Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] TeX Live patches for Windows #21

Merged
merged 5 commits into from
Feb 12, 2019
Merged

Conversation

mojca
Copy link
Contributor

@mojca mojca commented Jan 28, 2019

This is a set of patches as currently used by TeX Live. I'm not the author of them (some of them were contributed by Peter Breitenlohner, some by Akira Kakuto), but I'm submitting them unchanged for now, so that you can make a code review and we can try to find a way to end up patch-free in TeX Live.

(I suspect that some of the patches were ifdef-ed to W32TeX just to minimize the impact elsewhere, but maybe some could be used outside of W32TeX as well.)

The sources need to work:

  • from msys2 / native MinGW on Windows
  • cross-compilations with 32-bit and 64-bit mingw-w64 from either Linux or Mac
  • from Visual Studio (I'm not yet sure how to test that; Akira has some zips with visual studio projects on the w32tex website, I would need to look at those)

I will edit history and commit messages as necessary.

@kberry @norbusan, see: #17, #20

@mojca
Copy link
Contributor Author

mojca commented Jan 28, 2019

Even with those patches in place, the build on msys2 currently fails with:

g++  -g -O2   -o cfftot1.exe cfftot1.o maket1font.o ../libefont/libefont.a ../liblcdf/liblcdf.a
../libefont/libefont.a(otf.o):C:\Programs\MSYS\msys64\home\me\lcdf-typetools\libefont/./../include/efont/otfdata.hh:122: undefined reference to `__imp_ntohs'

@@ -126,5 +126,5 @@ Filename::open_write(bool binary) const
if (_actual || !_path)
return _actual;
else
return fopen(_path.c_str(), binary ? "wb" : "w");
return fopen(_path.c_str(), "wb");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

Not really necessary in the upstream. I wanted that text files have
same EOL as Unix in TeX Live w32.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to read Kakuto's comment. Is he saying that we should use binary mode for all files on Windows, or that using binary mode is not necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I nearly missed this question.

Kakuto:

I said that it is not necessary to use binary mode in the upstream for all files on Windows. It will be better not to change original "w" and "a" in the upstream because LCDF-TYPETOOLS is used also outside the TeX Live.
In the case of TeX Live, sometimes files are shared between various platforms and ls-R files for Windows have Unix style lineendings. Thus I'll change "w" and "a" as "wb" and "ab" in the TeX Live, because I think that it is desirable.

My own comment (please note that I didn't test any of those binary-parameters, and didn't try to read the code from a wider context either, so please excuse my ignorance and ignore my comment in case it's irrelevant): the other patches use unconditional binary mode for files, but I noticed that this is specifically a function which takes an argument for whether or not the file should be binary:

Filename::open_write(bool binary) const

and thus I see this particular patch as the least problematic of them all. In its current state the function is actually ignoring the argument / lying about what it would do.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you're misreading the patch. In its current state the function is not ignoring the binary argument. The patch would make it ignore the argument.

# define mkdir(dir, access) mkdir(dir)
# include <io.h>
# include <direct.h>
# define mkdir(dir, access) _mkdir(dir)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't object to this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

Thanks a lot.

look_for_writable_texdir("$TEXMFVAR", true);
#endif
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question about this part would mainly be: is there a need to have this #ifdef-ed away? Note that I don't know the sources at all, but this looks as if the only reason for checking for W32TEX was because TEXMFVAR is not defined. Wouldn't the same code work everywhere (not just in that particular TeX distribution) where TEXMFVAR is missing? It might take a little more CPU cycles to execute, but it looks generic enough to me. (Maybe the error message below would need to be adapted a bit.)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that it would probably be fine not ifdef'd.

@@ -313,7 +326,7 @@ update_odir(int o, String file, ErrorHandler *errh)
String ls_r = writable_texdir + "ls-R";
bool success = false;
if (access(ls_r.c_str(), R_OK) >= 0) // make sure it already exists
if (FILE *f = fopen(ls_r.c_str(), "a")) {
if (FILE *f = fopen(ls_r.c_str(), "ab")) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are all files being made binary? Is there an actual concrete reason? Because this is just a text file. But maybe on Windows all kpathsea files such as ls-R should use Unix lineendings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

In the TeX Live, ls-R files on w32 use Unix style lineendings.

mktexupd = kpsei_string(kpsei_find_file("mktexupd", KPSEI_FMT_WEB2C));
#endif
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK (shrug)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

Thanks a lot.

@@ -677,7 +694,7 @@ update_autofont_map(const String &fontname, String mapline, ErrorHandler *errh)
#endif
{
fclose(f);
f = fopen(map_file.c_str(), "w");
f = fopen(map_file.c_str(), "wb");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

See above

} else // TeXLive
#endif
String option = "--enable Map ";
String command = "updmap --nomkmap " + option + shell_quote(filename) + redirect
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not right. It won't even compile if W32TEX is defined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to go into the contents / correctness (again, I'm not the author and I don't know why the syntax for calling updmap is different), but it looks like a valid / syntactically correct code to me. When W32TEX is defined, the code looks like

if (p != NULL) { // W32TeX
    ...
    String option = "--add ";
} else
    String option = "--enable Map ";

which looks valid. It's just that the first time around the code is surrounded by braces, and in the else part it's not (but since it's a single statement, that's ok). I'm not saying that this is a super clear and maintainable code, just that it doesn't look wrong. I'm only slightly confused because I would expect the String option to go out of scope by the time command is composed?

What I would probably do here is something like

bool filetype_is_jtex() // ... but using a more suitable function name, this is just an example
{
    char *p = kpsei_var_value("jtex_filetype");
    if (p != NULL) {
        free(p); // I hate doing this manually, but well ...
        return true;
    } else {
        return false;
    }
}
...
String option;
if (filetype_is_jtex())
    option = "--add ";
else
    option = "--enable Map ";

I also noticed that updmap_prog has been replaced by hardcoded "updmap", and that one is probably not ideal. Maybe it's just an oversight after this line changed in your (= upstream) sources.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like that would compile, because in the current code when W32TEX is defined, String option is never in scope in the definition of String command where it is used.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing is that obvious compilation errors under W32TEX make me wonder whether anyone needs W32TEX support for this program.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

I removed these wrong changes (r49873).
In W32TEX, updmap-sys[-user] is not executed because of
#if HAVE_KPATHSEA && !WIN32
here I
#define WIN32 1

#endif
if (binary) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

See above...

Copy link
Contributor Author

@mojca mojca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for the review. I will ask Akira to take a look and provide feedback.

look_for_writable_texdir("$TEXMFVAR", true);
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question about this part would mainly be: is there a need to have this #ifdef-ed away? Note that I don't know the sources at all, but this looks as if the only reason for checking for W32TEX was because TEXMFVAR is not defined. Wouldn't the same code work everywhere (not just in that particular TeX distribution) where TEXMFVAR is missing? It might take a little more CPU cycles to execute, but it looks generic enough to me. (Maybe the error message below would need to be adapted a bit.)

} else // TeXLive
#endif
String option = "--enable Map ";
String command = "updmap --nomkmap " + option + shell_quote(filename) + redirect
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to go into the contents / correctness (again, I'm not the author and I don't know why the syntax for calling updmap is different), but it looks like a valid / syntactically correct code to me. When W32TEX is defined, the code looks like

if (p != NULL) { // W32TeX
    ...
    String option = "--add ";
} else
    String option = "--enable Map ";

which looks valid. It's just that the first time around the code is surrounded by braces, and in the else part it's not (but since it's a single statement, that's ok). I'm not saying that this is a super clear and maintainable code, just that it doesn't look wrong. I'm only slightly confused because I would expect the String option to go out of scope by the time command is composed?

What I would probably do here is something like

bool filetype_is_jtex() // ... but using a more suitable function name, this is just an example
{
    char *p = kpsei_var_value("jtex_filetype");
    if (p != NULL) {
        free(p); // I hate doing this manually, but well ...
        return true;
    } else {
        return false;
    }
}
...
String option;
if (filetype_is_jtex())
    option = "--add ";
else
    option = "--enable Map ";

I also noticed that updmap_prog has been replaced by hardcoded "updmap", and that one is probably not ideal. Maybe it's just an oversight after this line changed in your (= upstream) sources.

{
return kpse_var_value(name);
}
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why this definition is needed. That is: why isn't kpse_var_value itself working? (I now also see why all other code is ifdef-ed by W32TEX, since kpsei_var_value is not defined outside.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

I wanted to use similar name, kpsei_... as in the upstream, for kpse interface.
kpsei_var_value() is used only in the case of W32TEX.

@@ -63,6 +63,9 @@
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef _MSC_VER
# include <io.h>
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is also needed for MinGW. I cannot currently complete the compilation due to some missing libraries in the link phase (see my previous comment).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

forgot why I added these lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turned out that Luigi needed this for MinGW as well (as I suspected), so it made sense to put it under #ifdef WIN32. I probably didn't need it since I disabled kpathsea, and it was probably needed for parts ifdef-ed for kpathsea functionality.

Copy link
Contributor Author

@mojca mojca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replying on behalf of Kakuto-san (copying his responses).

@@ -126,5 +126,5 @@ Filename::open_write(bool binary) const
if (_actual || !_path)
return _actual;
else
return fopen(_path.c_str(), binary ? "wb" : "w");
return fopen(_path.c_str(), "wb");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

Not really necessary in the upstream. I wanted that text files have
same EOL as Unix in TeX Live w32.

# define mkdir(dir, access) mkdir(dir)
# include <io.h>
# include <direct.h>
# define mkdir(dir, access) _mkdir(dir)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

Thanks a lot.

@@ -313,7 +326,7 @@ update_odir(int o, String file, ErrorHandler *errh)
String ls_r = writable_texdir + "ls-R";
bool success = false;
if (access(ls_r.c_str(), R_OK) >= 0) // make sure it already exists
if (FILE *f = fopen(ls_r.c_str(), "a")) {
if (FILE *f = fopen(ls_r.c_str(), "ab")) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

In the TeX Live, ls-R files on w32 use Unix style lineendings.

mktexupd = kpsei_string(kpsei_find_file("mktexupd", KPSEI_FMT_WEB2C));
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

Thanks a lot.

@@ -677,7 +694,7 @@ update_autofont_map(const String &fontname, String mapline, ErrorHandler *errh)
#endif
{
fclose(f);
f = fopen(map_file.c_str(), "w");
f = fopen(map_file.c_str(), "wb");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

See above

} else // TeXLive
#endif
String option = "--enable Map ";
String command = "updmap --nomkmap " + option + shell_quote(filename) + redirect
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

I removed these wrong changes (r49873).
In W32TEX, updmap-sys[-user] is not executed because of
#if HAVE_KPATHSEA && !WIN32
here I
#define WIN32 1

{
return kpse_var_value(name);
}
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

I wanted to use similar name, kpsei_... as in the upstream, for kpse interface.
kpsei_var_value() is used only in the case of W32TEX.

@@ -63,6 +63,9 @@
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef _MSC_VER
# include <io.h>
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

forgot why I added these lines.

#endif
if (binary) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakuto:

See above...

@mojca
Copy link
Contributor Author

mojca commented Feb 1, 2019

I removed the remaining #ifdef W32TEX, even though the code that checks for TEXMFLOCAL could probably be improved a bit (I left some TODO comments). Feedback welcome.

After manually fixing #22 the build with MinGW succeeds, earlier I would get undefined reference to __imp_ntohs.

@mojca mojca mentioned this pull request Feb 1, 2019
@mojca
Copy link
Contributor Author

mojca commented Feb 7, 2019

@kohler: what do you want me to do next?

Luigi Scarso also just published two more patches that he needed to make the cross-compilation to windows work. I'll add them later (I already suspected that one of them was needed for MinGW as well, not just for MSVC).

@@ -7,6 +7,7 @@
#ifdef WIN32
# ifdef __MINGW32__
# include <winsock2.h>
# include <windows.h>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this would not hurt even if defined immediately under WIN32. It's just that under VS it isn't really needed.

@@ -63,6 +63,9 @@
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef _MSC_VER
# include <io.h>
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turned out that Luigi needed this for MinGW as well (as I suspected), so it made sense to put it under #ifdef WIN32. I probably didn't need it since I disabled kpathsea, and it was probably needed for parts ifdef-ed for kpathsea functionality.

Copy link
Contributor Author

@mojca mojca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the changes I wanted to make, including the ones reported as still missing by Luigi trying to cross-compile for Windows. I'm waiting for further instructions.

If needed, I can split the PR into multiple pieces, totally non-controversial ones, and those still needing some discussion. Please let me know.

@kohler
Copy link
Owner

kohler commented Feb 10, 2019

@mojca Thanks very much for your work. I'd like you to remove the change to filename.cc. After that, I'll merge with a squash commit—it all looks good!

Copy link
Contributor Author

@mojca mojca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much.

But just to double-check: you are saying that I should remove the "binary" patch from filename.cc and leave other "binary" patches in the code? (I'm a tiny bit confused because I don't see in what way exactly they differ, so that some should stay and some should go. I'm fine with the solution, I just want to make sure that I don't mess things up by accident.)

My view on the subject is the following (again, please remember that my primary platform is not even Windows and that I'm not really using lcdf-typetools either):

  • TeX Live may combine the files for multiple platforms (Windows + Unix-style), so ls-R and other files have unix file endings there even on Windows. In such environment it probably helps to be able to read both unix-style and windows-style line endings correctly when reading files, and (maybe/optionally?) write unix-style line-endings when generating files.
  • As Akira said, lcdf-typetools can be used outside of TeX Live, in which case it makes more sense to use windows-style line endings for output files.
  • It would be ideal to minimize patching in TeX Live.
  • Maybe there's a way that we come up with a flag (to write LF line endings on Windows instead of CRLF; it could either be a build-time flag or runtime flag, or both) and allow defining the behaviour with that flag; the flag would be off by default, but the TeX Live build could turn it on.

That way the tool could work correctly and as expected for everyone.

@@ -126,5 +126,5 @@ Filename::open_write(bool binary) const
if (_actual || !_path)
return _actual;
else
return fopen(_path.c_str(), binary ? "wb" : "w");
return fopen(_path.c_str(), "wb");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I nearly missed this question.

Kakuto:

I said that it is not necessary to use binary mode in the upstream for all files on Windows. It will be better not to change original "w" and "a" in the upstream because LCDF-TYPETOOLS is used also outside the TeX Live.
In the case of TeX Live, sometimes files are shared between various platforms and ls-R files for Windows have Unix style lineendings. Thus I'll change "w" and "a" as "wb" and "ab" in the TeX Live, because I think that it is desirable.

My own comment (please note that I didn't test any of those binary-parameters, and didn't try to read the code from a wider context either, so please excuse my ignorance and ignore my comment in case it's irrelevant): the other patches use unconditional binary mode for files, but I noticed that this is specifically a function which takes an argument for whether or not the file should be binary:

Filename::open_write(bool binary) const

and thus I see this particular patch as the least problematic of them all. In its current state the function is actually ignoring the argument / lying about what it would do.

@kohler
Copy link
Owner

kohler commented Feb 12, 2019

Hi Mojca, I read your comment, but rather than discuss further, please remove the patch from lib/filename.cc as requested, and leave all other patches as is. I think the other patches are fine, the one in lib/filename.cc is not. The one in lib/filename.cc (1) is not used anywhere (2) is to generic code. The other ones are changing the ways specific files are treated, and I believe that those specific files are being treated correctly after the patches.

You may overestimate how often the typetools are used outside texlive.

TeX Live may share the same files between Windows and Unix,
so we need to make sure that files and line endings remain compatible.
Cosmetic change, only for consistency with other function names.
Some distributions like W32TEX may not have TEXMFVAR defined,
so we also check whether TEXMFLOCAL is writable.
@mojca
Copy link
Contributor Author

mojca commented Feb 12, 2019

I'm sorry, yes, I misread the direction of the problematic patch :)

I fixed the PR. I hope that no squashing will be necessary: I tried to make simple logical commits, but please check.

Once this gets addressed, I would be grateful for some help with #22.

Thank you very much for the swift response and help.

@kohler kohler merged commit cc78267 into kohler:master Feb 12, 2019
@mojca mojca deleted the TL-patches branch February 12, 2019 20:09
@mojca
Copy link
Contributor Author

mojca commented Feb 12, 2019

Thank you very very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants