Repository: mesonbuild/meson

Issue:
0.51.0 incorrectly thinks arm-none-eabi-gcc can not compile programs due to missing _exit
I'm using arm-none-eabi-gcc (8-2018-q4-major) with nanolib for an embedded project. As of 0.51.0, the sanitycheckc.c compilation fails (I assume it was never attempted before) due to missing builtins such as `_exit`, `_isatty` etc.

For my actual build, stubs containing these impls are linked in with the final project, but the sanity check doesn't use them, for obvious reasons.

Reproducing on your end _should_ be as simple as running `arm-none-eabi-gcc sanitycheckc.c -o sanitycheckc_cross.exe` and seeing the relevant error.

Am I going about this the wrong way, or is there a way to temporarily disable the sanity check?


Discussion:
Just went back to 0.50.0 for a triage - it's because 0.51.0 now tries to link the executable, whereas before the sanity check merely compiled. (0.50.0 used `-c`)

Considering my user link flags are missing from the sanity check compile command, I suspect this might not be intentional.
As far as I am aware (even though I am not a Meson contributor), this can be fixed by supplying the appropriate link_args in a cross file.
@avdgrinten unfortunately not - even if link_args _were_ being pulled in (they're not), you cannot provide any link args to find the stubs for the stdlib. They must be compiled in, thus compile only (`-c`) is the versatile solution.
> 0.51.0 now tries to link the executable, whereas before the sanity check merely compiled. (0.50.0 used -c)

This is an unwanted change. We specifically did not link cross compiled binaries because of this reason. Probably fallout from the build/host changed by @Ericson2314.
Hmm I thought took specific steps to ensure we *didn't* link things. Can you try master? https://github.com/mesonbuild/meson/pull/5483/files#diff-330c05ce33750cfbd6229f700e0506bcR472 fixes some other issues with these "configure steps", and in general we can further deduplicate/systematize the code to help prevent bugs.
Hmm looking at master between my earlier changes and @dcbaker's changes some stuff might have been lost. I'm hoping https://github.com/mesonbuild/meson/issues/5485 will better allow us to assess what's up.
@jpakkane you can assign this one to me.
Don't you have the powers to assign it yourself? You should, at least.
@jpakkane no i don't have that power.
How about now?
Just for clarity, yeah master is a no-go too (though I think you've worked that out yourself). Version printed to console is `0.51.999` so I assume I pip installed from git correctly.
@jpakkane all good!

Resolving patch:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1062,7 +1062,7 @@ def link(self, target):
                 msg += "Use the 'pic' option to static_library to build with PIC."
                 raise InvalidArguments(msg)
             if self.for_machine is not t.for_machine:
-                msg = 'Tried to mix libraries for machines {1} and {2} in target {!r}'.format(self.name, self.for_machine, t.for_machine)
+                msg = 'Tried to mix libraries for machines {} and {} in target {!r}'.format(self.for_machine, t.for_machine, self.name)
                 if self.environment.is_cross_build():
                     raise InvalidArguments(msg + ' This is not possible in a cross build.')
                 else:
diff --git a/mesonbuild/compilers/clike.py b/mesonbuild/compilers/clike.py
--- a/mesonbuild/compilers/clike.py
+++ b/mesonbuild/compilers/clike.py
@@ -396,6 +396,8 @@ def _get_basic_compiler_args(self, env, mode):
         elif mode == 'link':
             # Add LDFLAGS from the env
             args += env.coredata.get_external_link_args(self.for_machine, self.language)
+
+        args += self.get_compiler_args_for_mode(mode)
         return args
 
     def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -1139,6 +1139,15 @@ def _get_compile_output(self, dirname, mode):
             suffix = 'obj'
         return os.path.join(dirname, 'output.' + suffix)
 
+    def get_compiler_args_for_mode(self, mode):
+        args = []
+        args += self.get_always_args()
+        if mode == 'compile':
+            args += self.get_compile_only_args()
+        if mode == 'preprocess':
+            args += self.get_preprocess_only_args()
+        return args
+
     @contextlib.contextmanager
     def compile(self, code, extra_args=None, *, mode='link', want_output=False):
         if extra_args is None:
@@ -1156,15 +1165,11 @@ def compile(self, code, extra_args=None, *, mode='link', want_output=False):
                 # Construct the compiler command-line
                 commands = CompilerArgs(self)
                 commands.append(srcname)
-                commands += self.get_always_args()
-                if mode == 'compile':
-                    commands += self.get_compile_only_args()
                 # Preprocess mode outputs to stdout, so no output args
-                if mode == 'preprocess':
-                    commands += self.get_preprocess_only_args()
-                else:
+                if mode != 'preprocess':
                     output = self._get_compile_output(tmpdirname, mode)
                     commands += self.get_output_args(output)
+                commands.extend(self.get_compiler_args_for_mode(mode))
                 # extra_args must be last because it could contain '/link' to
                 # pass args to VisualStudio's linker. In that case everything
                 # in the command line after '/link' is given to the linker.


Test patch: