meson icon indicating copy to clipboard operation
meson copied to clipboard

cc.get_define does not work when doing universal builds

Open jeremyhu opened this issue 3 years ago • 12 comments

Describe the bug

cc.get_define uses $CFLAGS with -E. That is not legal. You should only be using $CPPFLAGS when using $CC -E.

Using $CFLAGS causes configure to fail when building a fat binary, eg mesa does:

cc.get_define('ETIME', prefix : '#include <errno.h>')

We setup our CFLAGS and run meson, eg:

$ CFLAGS="-arch x86_64 -arch arm64" meson build/

but this fails with the following shown in the meson log:

Command line:  cc /var/folders/99/yp4q7wrs6ts8mlgwy6njn6280000gn/T/tmpl8i1u1kl/testfile.c -pipe -E -P -arch x86_64 -arch arm64 -P -O0 -std=c11 

Code:
 
        #include <errno.h>
        #ifndef ETIME
        # define ETIME
        #endif
        "MESON_GET_DEFINE_DELIMITER"
ETIME
Compiler stdout:
 
Compiler stderr:
 clang: error: cannot use 'cpp-output' output with multiple -arch options

system parameters

  • Is this a cross build or just a plain native build (for the same computer)? Native
  • what operating system? macOS 11
  • what Python version? 3.8.7
  • what meson --version? 0.55.3
  • what ninja --version if it's a Ninja build ? 1.10.2

jeremyhu avatar Jan 14 '21 21:01 jeremyhu

This is a really interesting issue, the basic problem here seems to be that we have no concept of a "fat" binary (when people were trying to pack x86 and x86_64 into a single elf container that's what they called it, not sure what you guys call it for mach-o). My understanding is that this is also common on AIX, so we probably want to solve it, not sure what that would look like.

@Ericson2314, this is the sort or problem you usually have good ideas about.

dcbaker avatar Jan 15 '21 19:01 dcbaker

Yeah fat binaries, bootloaders written in different mode, cpuid checks for obscure extensions; these all lay waste to tones of assumptions.

As to CPPFLAGS, yes meson doesn't really recognize it as a separate concept, and I'm not sure whether changing that is a good thing.

I'm guessing multi-arch clang doesn't work with -E because they do multiple CPP runs for each arch? I think one could still do an -E that case by doing partial evaluation of the CPP. See https://github.com/ckaestne/TypeChef for some food for thought, for example. And then we would see whether the variable was defined under every configuration the model.

Getting those sorts of techniques into Clang and LLVM is a massive yak shave, but one that I think could bring even bigger benefits to the C/C++ world, so I throw it out there wistfully.

Ericson2314 avatar Jan 15 '21 21:01 Ericson2314

@jeremyhu: what happens if you pass two arch switches and an arch specific argument, say like -msse4_1? Is clang smart enough to figure out that argument is only valid for the x86_64 code?

dcbaker avatar Jan 15 '21 22:01 dcbaker

@jeremyhu: what happens if you pass two arch switches and an arch specific argument, say like -msse4_1? Is clang smart enough to figure out that argument is only valid for the x86_64 code?

Yes:

[1002] ~ $ clang -arch x86_64 -arch arm64 -msse4.1 true.c

[1003] ~ $ clang -arch arm64 -msse4.1 true.c 
clang: warning: argument unused during compilation: '-msse4.1' [-Wunused-command-line-argument]

jeremyhu avatar Jan 27 '21 05:01 jeremyhu

Is it sufficient to simply strip the -arch options when we run the CPP tests, or will that have other consequences?

dcbaker avatar Jan 27 '21 17:01 dcbaker

If we strip the -arch and there's a -target command line without a valid arch, that will cause problems. For example, I usually do:

-target fat-apple-macos10.9 -arch x86_64 -arch arm64

But that's easily worked around at my level by using:

-target x86_64-apple-macos10.9 -arch x86_64 -arch arm64

So that is probably OK.

jeremyhu avatar Feb 01 '21 18:02 jeremyhu

On MacPorts we use your existing cross-file system, and set up one build for each arch, with cross-files for each arch we support. Then we lipo them together at the end.

This works for now, for us.

But if you made it work transparently such that cross-files were not needed, all the better.

kencu avatar Feb 09 '21 16:02 kencu

for interest, here are the three cross-files we use so far (the PPC one I haven't set up yet).

We could flesh it out a bit more perhaps - it wants a 'strip' binary and probably a pkg-config library path set up as well. But these work for us.

We set up a folder for each build, just like Jeremy is doing in his workaround on Xquartz, configure each with these cross files and then lipo the results together at the end.

I added a small patch to meson to have it search /opt/local/share/meson/cross/ automatically for cross-files.

% cat /opt/local/share/meson/cross/arm64-darwin
[host_machine]
system = 'darwin'
cpu_family = 'aarch64'
cpu = 'arm64'
endian = 'little'

[binaries]
pkgconfig = '/opt/local/bin/pkg-config'
cmake = '/opt/local/bin/cmake'

% cat /opt/local/share/meson/cross/i386-darwin
[host_machine]
system = 'darwin'
cpu_family = 'x86'
cpu = 'i386'
endian = 'little'

[binaries]
pkgconfig = '/opt/local/bin/pkg-config'
cmake = '/opt/local/bin/cmake'


% cat /opt/local/share/meson/cross/x86_64-darwin
[host_machine]
system = 'darwin'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

[binaries]
pkgconfig = '/opt/local/bin/pkg-config'
cmake = '/opt/local/bin/cmake'

kencu avatar Feb 11 '21 01:02 kencu

with those cross files, building for arm64 on BigSur Intel, or vice versa, or for both i386 and x86_84 on machines of the 10.4 to 10.13 vintage, works nicely for us, so far.

kencu avatar Feb 11 '21 01:02 kencu

See also #5290 for a similiar issue

jon-turney avatar Feb 27 '21 15:02 jon-turney

for interest, here are the three cross-files we use so far (the PPC one I haven't set up yet).

Just to update, we have cross-files for ppc and ppc64 now. That works, mostly. Some issues remain, like with gobject-introspection on 10.5.8 (ppc+ppc64) and on 10.6.8 (ppc via Rosetta).

See for example: https://github.com/mesonbuild/meson/pull/10442 A suboptimal fix for Rosetta build: https://github.com/mesonbuild/meson/issues/10351#issuecomment-1131530681

barracuda156 avatar Jul 22 '22 11:07 barracuda156

In addition, cc.has_header() always returns false with -arch x86_64 -arch arm64, producing the same cannot use 'cpp-output' output with multiple -arch options message in the log.

bgilbert avatar Apr 08 '24 13:04 bgilbert