Repository: mesonbuild/meson

Issue:
Cross compiler ignored when build and host architectures are identical
I'm trying to compile for Android x86_64 on Linux x86_64. Unfortunately, Meson selects the native compiler instead of the one provided by the cross-file. The setup is the same as described in #5097.


Discussion:
This sounds like a regression, it used to work fine in the past, can you confirm by trying with 0.49.2?
This seems to be affecting me as well. I'm cross compiling for iOS, and specifying `c_args` as `-arch arm64`. That argument was not used in `find_library('sqlite3')` which broke my build.
@nirbheek Yep, works as expected in 0.49.2.

Resolving patch:
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -477,7 +477,7 @@ def create_new_coredata(self, options):
         self.first_invocation = True
 
     def is_cross_build(self):
-        return not self.machines.matches_build_machine(MachineChoice.HOST)
+        return self.coredata.cross_file is not None
 
     def dump_coredata(self):
         return coredata.save(self.coredata, self.get_build_dir())
diff --git a/run_unittests.py b/run_unittests.py
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -5029,6 +5029,19 @@ def test_ldflag_dedup(self):
                 max_count = max(max_count, line.count(search_term))
         self.assertEqual(max_count, 1, 'Export dynamic incorrectly deduplicated.')
 
+    def test_identity_cross(self):
+        testdir = os.path.join(self.unit_test_dir, '58 identity cross')
+        crossfile = tempfile.NamedTemporaryFile(mode='w')
+        print(os.path.join(testdir, 'build_wrapper.py'))
+        print(os.path.join(testdir, 'host_wrapper.py'))
+        os.environ['CC'] = '"' + os.path.join(testdir, 'build_wrapper.py') + '"'
+        crossfile.write('''[binaries]
+c = ['{0}']
+'''.format(os.path.join(testdir, 'host_wrapper.py')))
+        crossfile.flush()
+        self.meson_cross_file = crossfile.name
+        # TODO should someday be explicit about build platform only here
+        self.init(testdir)
 
 def should_run_cross_arm_tests():
     return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')


Test patch:
diff --git a/test cases/unit/58 identity cross/build_wrapper.py b/test cases/unit/58 identity cross/build_wrapper.py
new file mode 100755
--- /dev/null
+++ b/test cases/unit/58 identity cross/build_wrapper.py	
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+import subprocess, sys
+
+subprocess.call(["cc", "-DEXTERNAL_BUILD"] + sys.argv[1:])
diff --git a/test cases/unit/58 identity cross/host_wrapper.py b/test cases/unit/58 identity cross/host_wrapper.py
new file mode 100755
--- /dev/null
+++ b/test cases/unit/58 identity cross/host_wrapper.py	
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+import subprocess, sys
+
+subprocess.call(["cc", "-DEXTERNAL_HOST"] + sys.argv[1:])
diff --git a/test cases/unit/58 identity cross/meson.build b/test cases/unit/58 identity cross/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/unit/58 identity cross/meson.build	
@@ -0,0 +1,15 @@
+project('identity cross test', 'c')
+
+assert(meson.get_compiler('c', native: true).get_define(
+  'GOT',
+  args : [ '-DARG_BUILD' ],
+  prefix : '#include "stuff.h"',
+  include_directories: include_directories('.'),
+) == 'BUILD', 'did not get BUILD from native: true compiler')
+
+assert(meson.get_compiler('c', native: false).get_define(
+  'GOT',
+  args : [ '-DARG_HOST' ],
+  prefix : '#include "stuff.h"',
+  include_directories: include_directories('.'),
+) == 'HOST', 'did not get HOST from native: false compiler')
diff --git a/test cases/unit/58 identity cross/stuff.h b/test cases/unit/58 identity cross/stuff.h
new file mode 100644
--- /dev/null
+++ b/test cases/unit/58 identity cross/stuff.h	
@@ -0,0 +1,27 @@
+#ifdef EXTERNAL_BUILD
+  #ifndef ARG_BUILD
+    #error "External is build but arg_build is not set."
+  #elif defined(ARG_HOST)
+    #error "External is build but arg_host is set."
+  #else
+    #define GOT BUILD
+  #endif
+#endif
+
+#ifdef EXTERNAL_HOST
+  #ifndef ARG_HOST
+    #error "External is host but arg_host is not set."
+  #elif defined(ARG_BUILD)
+    #error "External is host but arg_build is set."
+  #else
+    #define GOT HOST
+  #endif
+#endif
+
+#if defined(EXTERNAL_BUILD) && defined(EXTERNAL_HOST)
+  #error "Both external build and external host set."
+#endif
+
+#if !defined(EXTERNAL_BUILD) && !defined(EXTERNAL_HOST)
+  #error "Neither external build nor external host is set."
+#endif