-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CMake: Fix Windows build with Clang/LLVM 17.
llvm-windres 17.0.0 has more accurate emulation of GNU windres, so the hack for GNU windres must now be used with llvm-windres too. LLVM 16.0.6 has the old behavior and there likely won't be more 16.x releases. So we can simply check for >= 17.0.0. See also: llvm/llvm-project@2bcc0fd
- Loading branch information
Showing
1 changed file
with
14 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
0570308
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kiitos/tack!
I was just about to submit a PR doing the same, when I saw that you had updated xz already to take this into account. Very much appreciated.
When I made llvm-windres originally, I wasn't aware of how
--use-temp-file
affects how GNU windres mangles the command line arguments. Without the flag, the arguments get interpreted by a shell one time extra within thepopen()
, as you've noted. Some projects explicitly expect this - see e.g. https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=blob;f=windows/windres-options;h=b12edd0edc875a15dd0b79a54b975cd6ced91b0f;hb=775d1d26a8f72214834ef4d399bad4690b7a604c#l67 - and I've made llvm-windres handle that. That works, but if you'd be using that, you'd need to pass different-D
options to windres and to the compiler in general. (That setup still is problematic for passing strings with spaces in them to GNU windres though.) But using--use-temp-file
seems like a much nicer solution.FWIW, I was about to suggest a slightly different form of the cmake conditional, something like this:
This assumes that any mingw-compatible toolchain supports this, with llvm-windres older than 16 being the exception. In the future for cleanup, that distinction could also maybe be dropped entirely.
Regardless, it might make sense to change the leading
if (WIN32 ...
intoif (MINGW
in any case; I think a setup with Clang acting in MSVC mode (withllvm-rc
or MSrc.exe
as the RC tool) would hit this otherwise.0570308
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for llvm-windres and improving the GNU windres compatibility! They way GNU windres handles the arguments doesn't feel right but it cannot be fixed in backward compatible way. It was confusing to figure it out as quoting has to work in both /bin/sh and cmd.exe. The docs don't directly say that
--use-temp-file
affects options handling but eventually I ended up trying that too.Using
MINGW
instead ofWIN32
: I understand the point. Would Cygwin be affected then though? I suppose Cygwin needs the windres workaround too. So should it beMINGW OR CYGWIN
orWIN32 AND NOT MSVC
? Or are there more targets that matchWIN32
too? Sorry, I'm quite clueless here.(There are more Windows-related improments to CMake-based build coming. I pushed some to the w32_update branch but it's not finished or polished yet. E.g. build.bash hasn't actually been tested on MSYS2 (and it's hardcoded for GCC too). Completely revised build instructions (CMake + MinGW-w64 + plain Command Prompt) for less experienced developers are coming too. For a long time I thought that CMake-based build would be for MSVC only but in the past two weeks I have started to think that it doesn't lack too many things anymore so maybe it should be polished to make it truly good on a few other common targets too.
I have heard comments saying that we should use Meson but years ago CMake support was requested due to Windows so that was started back then. Maintaining very many build systems isn't practical. Autotools cannot be dropped because those are likely the most supported method on less known platforms (for example, being EBCDIC compatible matters or at least did a few years ago) although Libtool's shared library versioning oddities have bothered me a long time.)
0570308
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely 100% sure here, but I think
MINGW OR CYGWIN
might be the right thing; cygwin in general doesn't setWIN32
I think, as it's mostly considered unixy.Yep, totally agree. And usually it's worse if one provides multiple build systems, but their functionality isn't entirely equal, either in how the build works, or worse, the header/pkgconfig install layout differs, or ABI details like sonames or such differ between various builds.
I've got plenty of Libtool frustrations myself as well...
Clang links compiler-rt builtins by passing an absolute path to the
.a
file, instead of passing-L
+-l
. If you're linking a C++ library with libtool, libtool decides to do a test run of the compiler with-v
, to see what linker flags it passes by default. Then it will do the actual link with-nostdlibs
and manually readd the options it thinks are relevant; it extracts all-L
and-l
options, but drops/absolute/path/to/lib.a
. https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27866 There was something that seemed like action towards getting this resolved last year, but then maintainance stopped again.0570308
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unfortunate that it's not documented very clearly but it seems that you are right. So perhaps the CMake-based build has been broken on Cygwin for quite some time.
(In C code,
_WIN32
is #defined on Cygwin, which slightly adds to the confusion.)Grepping the sources gave me a feeling that
MSYS
should be listed in addition toCYGWIN
to cover MSYS and MSYS2.I used
STREQUAL
instead ofMATCHES
. I suppose other Clang-based compiler strings in CMake aren't relevant in this particular case. I understand thatMATCHES
might be better in generic situations (it misses "IntelLLVM" though).I have committed a fix to master. Thanks!
Most of these apply to XZ Utils for now. w32_update has a commit to install the pkgconfig file. On GNU/Linux even that differs slightly due to CMake not adding
-pthread
since pthreads are in libc in modern glibc versions. That difference shouldn't matter in practice, luckily.Soname differences are hard to avoid with Libtool vs. anything else on certain platforms.
I wonder if not supporting Meson is a problem in the long term. I have seen one or two quickly-written files for building liblzma with Meson which work for x86-64 and maybe something else but can be suboptimal or maybe even subtly broken in some other cases. Maybe it's just the way things are, upstreams cannot worry about everything.
That's a showstopper issue indeed. I didn't read in detail but I suppose there's a reason why Libtool was designed to work like it does, it's an old tool and some decisions might be less relevant on today's platforms. The big deal is that Libtool has had lack of developer resources for many years.
Thanks!
0570308
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, that doesn't match my experience (and I just rechecked just to be sure), AFAIK
_WIN32
isn't defined by the compiler in Cygwin. (And other than that, the basics are defined in a unixy way, likesizeof(long) == sizeof(void*)
.)Yep, that's probably true. (I wonder if the MSYS environment defines
CYGWIN
as well - I'm too lazy to check right now.) Overall very few programs care about how they work in MSYS as they primarily should be built for mingw instead. But I'm sure xz is relevant to have available in all environments.Thanks!
Yep; for one project that I maintain, I spent some extra effort in CMake to try to match the sonames that are produced with libtool closely.
I've actually been faced with that decision as well.
For http://github.com/mstorsjo/fdk-aac, where I already have autotools and CMake, I got a PR to add Meson. Out of principle, I didn't want to merge it - it doesn't give any extra platform support over autotools and CMake. And if I'd do it, I'd want to spend the same level of effort as for CMake, making it match the autotools build both wrt soname and functionality across the main platforms. But even if I didn't merge it, the incomplete/unverified/possibly subtly incompatible Meson file lives on elsewhere in their wrapdb, unmaintained by me, used by some other Meson projects. So if I'd like to make sure it works properly, I guess I should take on the maintainance of that as well.
0570308
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, that's good to know, thanks. Now I wonder why the (harmless) commits 0deb1bb and 44d70cb were made and left me believe that
_WIN32
is or might be defined. The commit messages are a bit confusing. :-( I remember that around those times I even tested on Cygwin.It likely does since Modules/Platform/MSYS-Initialize.cmake includes Platform/CYGWIN-Initialize which sets
CYGWIN
. But checking forMSYS
shouldn't hurt, I hope.I had to look at wrapdb now. Seems that there is XZ Utils 5.2.12 under the name liblzma but not XZ Utils 5.4.x. If I understood correctly:
meson.build contains the old bug reporting address (my personal email address) which was changed in 5.2.9. So it's obvious that the wrap file is updated without a throrough compare with upstream changes.
It assumes that the target is little endian and supports fast unaligned access.
Check for
optreset
has been commented out. OpenBSD's man page says that GNU-styleoptind = 0
is supported but FreeBSD and NetBSD don't. So maybe parsing the environment varsXZ_OPT
andXZ_DEFAULTS
is broken on those.liblzma has an unneeded depedency on libintl on systems where it's not part of libc.
I don't see anything about installing the xz translation files even though translation support is built.
At glance I guess it is good enough in practice for the most common use cases (GNU/Linux and Windows). :-) It's clear that it has take some effort to get it to the current shape even though it would have a long way to become polished and feature complete. 5.4.x has a few new #defines so that might explain why 5.4.x isn't there yet.
Oh well. At least the windres workaround in CMake should be correct now. Thanks again!