aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2017-03-27 14:40:34 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2017-03-27 14:40:34 +0530
commit001cf52c3a10aa4d2b0db5ec008fb5d2160ce23e (patch)
treefdffc3df42e987632a9da67a643d643fcbc158e8
parent58131c05153f947c37362dba4248bdaca7ebcbfa (diff)
downloadmeson-001cf52c3a10aa4d2b0db5ec008fb5d2160ce23e.zip
meson-001cf52c3a10aa4d2b0db5ec008fb5d2160ce23e.tar.gz
meson-001cf52c3a10aa4d2b0db5ec008fb5d2160ce23e.tar.bz2
Try even harder to use the C compiler for assembly
Now as long as you have a C compiler available in the project, it will be used to compile assembly even if the target contains a C++ compiler and even if the target contains only assembly and C++ sources. Earlier, the order in which sources appeared in a target would decide which compiler would be used. However, if the project only provides a C++ compiler, that will be used for compiling assembly sources. If this breaks your use-case, please tell us. Includes a test that ensures that all of the above is adhered to.
-rw-r--r--mesonbuild/build.py11
-rw-r--r--mesonbuild/compilers.py11
-rw-r--r--mesonbuild/interpreter.py14
-rwxr-xr-xrun_unittests.py46
-rw-r--r--test cases/common/141 c cpp and asm/main.cpp11
-rw-r--r--test cases/common/141 c cpp and asm/meson.build17
-rw-r--r--test cases/common/141 c cpp and asm/retval-arm.S8
-rw-r--r--test cases/common/141 c cpp and asm/retval-x86.S8
-rw-r--r--test cases/common/141 c cpp and asm/retval-x86_64.S8
-rw-r--r--test cases/common/141 c cpp and asm/somelib.c3
-rw-r--r--test cases/common/141 c cpp and asm/symbol-underscore.h5
11 files changed, 126 insertions, 16 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index c28a8a4..1f646dc 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -12,15 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import copy, os, re
+from collections import OrderedDict
+
from . import environment
from . import dependencies
from . import mlog
-import copy, os, re
from .mesonlib import File, MesonException
from .mesonlib import flatten, stringlistify, classify_unity_sources
from .mesonlib import get_filenames_templates_dict, substitute_values
from .environment import for_windows, for_darwin
-from .compilers import is_object, clike_langs, lang_suffixes
+from .compilers import is_object, clike_langs, sort_clike, lang_suffixes
known_basic_kwargs = {'install': True,
'c_pch': True,
@@ -291,7 +293,7 @@ class BuildTarget(Target):
self.is_unity = environment.coredata.get_builtin_option('unity')
self.environment = environment
self.sources = []
- self.compilers = {}
+ self.compilers = OrderedDict()
self.objects = []
self.external_deps = []
self.include_dirs = []
@@ -444,6 +446,9 @@ class BuildTarget(Target):
if lang not in self.compilers:
self.compilers[lang] = compiler
break
+ # Re-sort according to clike_langs
+ self.compilers = OrderedDict(sorted(self.compilers.items(),
+ key=lambda t: sort_clike(t[0])))
else:
# No source files, target consists of only object files of unknown
# origin. Just add the first clike compiler that we have and hope
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index 22fb522..76a9067 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -57,6 +57,17 @@ clike_suffixes += ('h', 'll', 's')
# All these are only for C-like languages; see `clike_langs` above.
+def sort_clike(lang):
+ '''
+ Sorting function to sort the list of languages according to
+ reversed(compilers.clike_langs) and append the unknown langs in the end.
+ The purpose is to prefer C over C++ for files that can be compiled by
+ both such as assembly, C, etc. Also applies to ObjC, ObjC++, etc.
+ '''
+ if lang not in clike_langs:
+ return 1
+ return -clike_langs.index(lang)
+
def is_header(fname):
if hasattr(fname, 'fname'):
fname = fname.fname
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 550e2f9..198c758 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1752,22 +1752,10 @@ class Interpreter(InterpreterBase):
self.coredata.compiler_options = new_options
return comp, cross_comp
- @staticmethod
- def sort_clike(lang):
- '''
- Sorting function to sort the list of languages according to
- reversed(compilers.clike_langs) and append the unknown langs in the end.
- The purpose is to prefer C over C++ for files that can be compiled by
- both such as assembly, C, etc. Also applies to ObjC, ObjC++, etc.
- '''
- if lang not in compilers.clike_langs:
- return 1
- return -compilers.clike_langs.index(lang)
-
def add_languages(self, args, required):
success = True
need_cross_compiler = self.environment.is_cross_build() and self.environment.cross_info.need_cross_compiler()
- for lang in sorted(args, key=self.sort_clike):
+ for lang in sorted(args, key=compilers.sort_clike):
lang = lang.lower()
if lang in self.coredata.compilers:
comp = self.coredata.compilers[lang]
diff --git a/run_unittests.py b/run_unittests.py
index a11e3a5..91ccf37 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -878,6 +878,52 @@ class AllPlatformTests(BasePlatformTests):
self.assertEqual(wcc.get_exelist(), wrappercc)
self.assertEqual(wlinker.get_exelist(), wrapperlinker)
+ def test_always_prefer_c_compiler_for_asm(self):
+ testdir = os.path.join(self.common_test_dir, '141 c cpp and asm')
+ self.init(testdir)
+ commands = {'cpp-asm': {}, 'cpp-c-asm': {}, 'c-cpp-asm': {}}
+ for cmd in self.get_compdb():
+ # Get compiler
+ split = shlex.split(cmd['command'])
+ if split[0] == 'ccache':
+ compiler = split[1]
+ else:
+ compiler = split[0]
+ # Classify commands
+ if 'Icpp-asm' in cmd['command']:
+ if cmd['file'].endswith('.S'):
+ commands['cpp-asm']['asm'] = compiler
+ elif cmd['file'].endswith('.cpp'):
+ commands['cpp-asm']['cpp'] = compiler
+ else:
+ raise AssertionError('{!r} found in cpp-asm?'.format(cmd['command']))
+ elif 'Ic-cpp-asm' in cmd['command']:
+ if cmd['file'].endswith('.S'):
+ commands['c-cpp-asm']['asm'] = compiler
+ elif cmd['file'].endswith('.c'):
+ commands['c-cpp-asm']['c'] = compiler
+ elif cmd['file'].endswith('.cpp'):
+ commands['c-cpp-asm']['cpp'] = compiler
+ else:
+ raise AssertionError('{!r} found in c-cpp-asm?'.format(cmd['command']))
+ elif 'Icpp-c-asm' in cmd['command']:
+ if cmd['file'].endswith('.S'):
+ commands['cpp-c-asm']['asm'] = compiler
+ elif cmd['file'].endswith('.c'):
+ commands['cpp-c-asm']['c'] = compiler
+ elif cmd['file'].endswith('.cpp'):
+ commands['cpp-c-asm']['cpp'] = compiler
+ else:
+ raise AssertionError('{!r} found in cpp-c-asm?'.format(cmd['command']))
+ else:
+ raise AssertionError('Unknown command {!r} found'.format(cmd['command']))
+ self.assertEqual(commands['cpp-asm']['asm'], commands['c-cpp-asm']['c'])
+ self.assertEqual(commands['c-cpp-asm']['asm'], commands['c-cpp-asm']['c'])
+ self.assertEqual(commands['cpp-c-asm']['asm'], commands['cpp-c-asm']['c'])
+ self.assertNotEqual(commands['cpp-asm']['asm'], commands['cpp-asm']['cpp'])
+ self.assertNotEqual(commands['c-cpp-asm']['c'], commands['c-cpp-asm']['cpp'])
+ self.assertNotEqual(commands['cpp-c-asm']['c'], commands['cpp-c-asm']['cpp'])
+
class WindowsTests(BasePlatformTests):
'''
diff --git a/test cases/common/141 c cpp and asm/main.cpp b/test cases/common/141 c cpp and asm/main.cpp
new file mode 100644
index 0000000..c089870
--- /dev/null
+++ b/test cases/common/141 c cpp and asm/main.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+
+extern "C" {
+ int get_retval(void);
+ int get_cval(void);
+}
+
+int main(int argc, char **argv) {
+ std::cout << "C++ seems to be working." << std::endl;
+ return get_retval();
+}
diff --git a/test cases/common/141 c cpp and asm/meson.build b/test cases/common/141 c cpp and asm/meson.build
new file mode 100644
index 0000000..5004ef8
--- /dev/null
+++ b/test cases/common/141 c cpp and asm/meson.build
@@ -0,0 +1,17 @@
+project('c cpp and asm', 'c', 'cpp')
+
+cpu = host_machine.cpu_family()
+
+supported_cpus = ['arm', 'x86', 'x86_64']
+
+if not supported_cpus.contains(cpu)
+ error('MESON_SKIP_TEST unsupported cpu:' + cpu)
+endif
+
+if meson.get_compiler('c').get_id() == 'msvc'
+ error('MESON_SKIP_TEST MSVC can\'t compile assembly')
+endif
+
+test('test-cpp-asm', executable('cpp-asm', ['main.cpp', 'retval-' + cpu + '.S']))
+test('test-c-cpp-asm', executable('c-cpp-asm', ['somelib.c', 'main.cpp', 'retval-' + cpu + '.S']))
+test('test-cpp-c-asm', executable('cpp-c-asm', ['main.cpp', 'somelib.c', 'retval-' + cpu + '.S']))
diff --git a/test cases/common/141 c cpp and asm/retval-arm.S b/test cases/common/141 c cpp and asm/retval-arm.S
new file mode 100644
index 0000000..8b37197
--- /dev/null
+++ b/test cases/common/141 c cpp and asm/retval-arm.S
@@ -0,0 +1,8 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+
+SYMBOL_NAME(get_retval):
+ mov r0, #0
+ mov pc, lr
diff --git a/test cases/common/141 c cpp and asm/retval-x86.S b/test cases/common/141 c cpp and asm/retval-x86.S
new file mode 100644
index 0000000..06bd75c
--- /dev/null
+++ b/test cases/common/141 c cpp and asm/retval-x86.S
@@ -0,0 +1,8 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retl
diff --git a/test cases/common/141 c cpp and asm/retval-x86_64.S b/test cases/common/141 c cpp and asm/retval-x86_64.S
new file mode 100644
index 0000000..638921e
--- /dev/null
+++ b/test cases/common/141 c cpp and asm/retval-x86_64.S
@@ -0,0 +1,8 @@
+#include "symbol-underscore.h"
+
+.text
+.globl SYMBOL_NAME(get_retval)
+
+SYMBOL_NAME(get_retval):
+ xorl %eax, %eax
+ retq
diff --git a/test cases/common/141 c cpp and asm/somelib.c b/test cases/common/141 c cpp and asm/somelib.c
new file mode 100644
index 0000000..e585b8e
--- /dev/null
+++ b/test cases/common/141 c cpp and asm/somelib.c
@@ -0,0 +1,3 @@
+int get_cval (void) {
+ return 0;
+}
diff --git a/test cases/common/141 c cpp and asm/symbol-underscore.h b/test cases/common/141 c cpp and asm/symbol-underscore.h
new file mode 100644
index 0000000..508cf50
--- /dev/null
+++ b/test cases/common/141 c cpp and asm/symbol-underscore.h
@@ -0,0 +1,5 @@
+#if defined(__WIN32__) || defined(__APPLE__)
+# define SYMBOL_NAME(name) _##name
+#else
+# define SYMBOL_NAME(name) name
+#endif