mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.54k stars 1.61k forks source link

Don't require a native compiler when doing only cross-compilation #2392

Closed rhd closed 4 years ago

rhd commented 7 years ago

I have a windows machine with the latest .msi installed - version 0.42.1.

I set my path like this:

PATH=C:\Xilinx\SDK\2017.1\bin;C:\Xilinx\SDK\2017.1\gnu\microblaze\nt\bin;C:\Xili
nx\SDK\2017.1\gnu\arm\nt\bin;C:\Xilinx\SDK\2017.1\gnu\microblaze\linux_toolchain
\nt64_be\bin;C:\Xilinx\SDK\2017.1\gnu\microblaze\linux_toolchain\nt64_le\bin;C:\
Xilinx\SDK\2017.1\gnu\aarch32\nt\gcc-arm-linux-gnueabi\bin;C:\Xilinx\SDK\2017.1\
gnu\aarch32\nt\gcc-arm-none-eabi\bin;C:\Xilinx\SDK\2017.1\gnu\aarch64\nt\aarch64
-linux\bin;C:\Xilinx\SDK\2017.1\gnu\aarch64\nt\aarch64-none\bin;C:\Xilinx\SDK\20
17.1\gnu\armr5\nt\gcc-arm-none-eabi\bin;C:\Xilinx\SDK\2017.1\tps\win64\cmake-3.3
.2\bin;C:\Xilinx\DocNav;

This is my cross file (I've tried also tried full paths but it makes no difference:

$ cat armr5_cross.txt 
[binaries]
c = ['ccache', 'armr5-none-eabi-gcc']
cpp = ['ccache', 'armr5-none-eabi-g++']
ar = 'armr5-none-eabi-ar'
strip = 'armr5-none-eabi-strip'

[properties]
c_args = ['-DARMR5', '-mcpu=cortex-r5', '-mfloat-abi=softfp', '-mfpu=vfpv3-d16', '-nostdlib']
cpp_args = ['-DARMR5', '-mcpu=cortex-r5', '-mfloat-abi=softfp', '-mfpu=vfpv3-d16', '-nostdlib']

[host_machine]
system = 'notlinux'
cpu_family = 'arm'
cpu = 'r5'
endian = 'little'

Meson prints this error:

"c:\Program Files\Meson\meson.exe" build-r5 --cross-file=armr5_cross.txt
The Meson build system
Version: 0.42.1
Source dir: c:\work\phg
Build dir: c:\work\phg\build-r5
Build type: cross build
Project name: phg

Meson encountered an error in file meson.build, line 1, column 0:
Unknown compiler(s): ['cl', 'cc', 'gcc', 'clang']
The follow exceptions were encountered:
Running "cl /?" gave "[WinError 2] The system cannot find the file specified"
Running "cc --version" gave "[WinError 2] The system cannot find the file specif
ied"
Running "gcc --version" gave "[WinError 2] The system cannot find the file speci
fied"
Running "clang --version" gave "[WinError 2] The system cannot find the file spe
cified"

What's interesting is that on another windows machine, I do have clang and gcc in the path and this exact same command works perfectly.

rhd commented 7 years ago

confirmed.

On the machine it was failing on, I installed mingw and now the meson command is working.

jpakkane commented 7 years ago

Meson requires that you have both a native compiler and a cross compiler available when doing cross compilations.

rhd commented 7 years ago

Hmm, that means I have to get windows people to install mingw to use the xilinx cross compiler? I can't imagine that's going to go over well...

maybe I can set the CC/CXX env variables to some other compiler that comes with the xilinx stuff. Meson will pick that up for the native tooling when using --cross-file?

Is there a particular reason why a native compiler is required?

jpakkane commented 7 years ago

Most of them have to do with laziness. The implementation code is a lot simpler if it can always assume that the native compiler exists and is usable. We don't have to have special checking code when people do native : true etc.

That being said we could probably accept a patch to fix this assuming it does not complicate the internals too much.

nirbheek commented 7 years ago

The error message should also definitely be improved to explicitly state what's missing.

jon-turney commented 5 years ago

I looked into this a bit, as having this would simplify adding cross ARM MSVC to CI.

This looks doable, but I think that we will need to extend the meson language so it's possible to say if a native compiler is required or not.

e.g. add_languages(), gains a native: keyword, indicating if a native or cross compiler is required. For backwards compatibility, if the keyword is absent, that means both are required.

project() gains a native_languages: keyword, listing the languages for which a native compiler is required. For backwards compatibility, if absent, the default value is the list of (host) languages given to project()

jpakkane commented 5 years ago

An alternative approach is not to add a keyword but just try to look up the compilers and if they are not found, then ignore them and later if the build definition tries to build a native target, exit with a hard error.

jon-turney commented 5 years ago

Yeah, I looked into doing it lazily, but as well as being a lot more work, there is at least one more problem:

add_languages(required: false) is supposed to return false if the required compiler(s) can't be found, but currently we can't know if a native compiler is required until after we've finished executing the entire meson.build

Ericson2314 commented 5 years ago

After #4010, it will be really really really easy. (I was planning on doing this / native kwarg for add_language anyways.)

mafes commented 5 years ago

Is there now a way to disable the native compiler? If so, how does it work? In my company we are currently evaluating different build systems and a useless dependency on a native compiler is a no-go.

Ericson2314 commented 5 years ago

It wasn't in #4010, but is easy to do now that it's merged. I have some regressions to fix before new features, but I'll help anyone else start this sooner.

jon-turney commented 4 years ago

After #4010, it will be really really really easy

Well, I must be dumb because it involved a lot of work, but I have made an attempt at this in #6512.

An alternative approach is not to add a keyword but just try to look up the compilers and if they are not found, then ignore them

I took the simple approach of always declaring what languages are used for what machine. It's certainly possible to do this lazily as a refinement, but there are multiple points where the interpreter wants information from the compiler object, which are not well surfaced at the moment.

scholarzry commented 4 years ago

in interpeter.py: 2790: `try:

                comp = self.environment.detect_compiler_for(lang, for_machine)
                if comp is None:
                    raise InvalidArguments('Tried to use unknown language "%s".' % lang)
                comp.sanity_check(self.environment.get_scratch_dir(), self.environment)

            except Exception:
                if not required:
                        mlog.log....`

An error occurred in detect_compiler_for, and the Execption part will not be executed