summaryrefslogtreecommitdiff
blob: b3aa3693e69754700bd4db185fc6c8b859d020ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
From 9dc3ca2c1c9fbb47e731551c6432df144f725261 Mon Sep 17 00:00:00 2001
From: Yevhenii Kolesnikov <yevhenii.kolesnikov@globallogic.com>
Date: Thu, 21 May 2020 18:58:47 +0300
Subject: [PATCH] compilers: add fetching of define list for clang

Simmilar to gcc, the list of pre-processor defines can be fetched with
`-dM -E` option. The way cpu_family is determined on linux relies on
this list.

Fixes incorrect value of cpu_family on linux, when crosscompiling:

```
CC="clang -m32" meson ./build
```

Signed-off-by: Yevhenii Kolesnikov <yevhenii.kolesnikov@globallogic.com>
Co-authored-by: Dylan Baker <dylan@pnwbakers.com>
---
 mesonbuild/compilers/c.py            |  5 +++--
 mesonbuild/compilers/cpp.py          |  5 +++--
 mesonbuild/compilers/fortran.py      |  2 +-
 mesonbuild/compilers/mixins/clang.py |  9 ++++++++-
 mesonbuild/compilers/objc.py         |  2 +-
 mesonbuild/compilers/objcpp.py       |  2 +-
 mesonbuild/environment.py            | 26 +++++++++++++++++++++++++-
 7 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 1bc9e84998..aac99b4269 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -86,9 +86,10 @@ class ClangCCompiler(ClangCompiler, CCompiler):
     _C18_VERSION = '>=8.0.0'
 
     def __init__(self, exelist, version, for_machine: MachineChoice,
-                 is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs):
+                 is_cross, info: 'MachineInfo', exe_wrapper=None,
+                 defines: T.Optional[T.List[str]] = None, **kwargs):
         CCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, **kwargs)
-        ClangCompiler.__init__(self)
+        ClangCompiler.__init__(self, defines)
         default_warn_args = ['-Wall', '-Winvalid-pch']
         self.warn_args = {'0': [],
                           '1': default_warn_args,
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index f4bcfa9f89..478a68c13c 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -155,10 +155,11 @@ def _find_best_cpp_std(self, cpp_std):
 
 class ClangCPPCompiler(ClangCompiler, CPPCompiler):
     def __init__(self, exelist, version, for_machine: MachineChoice,
-                 is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs):
+                 is_cross, info: 'MachineInfo', exe_wrapper=None,
+                 defines : T.Optional[T.List[str]] = None, **kwargs):
         CPPCompiler.__init__(self, exelist, version, for_machine, is_cross,
                              info, exe_wrapper, **kwargs)
-        ClangCompiler.__init__(self)
+        ClangCompiler.__init__(self, defines)
         default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
         self.warn_args = {'0': [],
                           '1': default_warn_args,
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index c155b5b4f3..af83c0e564 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -424,7 +424,7 @@ def __init__(self, exelist, version, for_machine: MachineChoice,
                  **kwargs):
         FortranCompiler.__init__(self, exelist, version, for_machine,
                                  is_cross, info, exe_wrapper, **kwargs)
-        ClangCompiler.__init__(self)
+        ClangCompiler.__init__(self, [])
         self.id = 'flang'
         default_warn_args = ['-Minform=inform']
         self.warn_args = {'0': [],
diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py
index 1c0ee452f4..0ee10ad5d5 100644
--- a/mesonbuild/compilers/mixins/clang.py
+++ b/mesonbuild/compilers/mixins/clang.py
@@ -42,9 +42,10 @@
 }  # type: T.Dict[str, T.List[str]]
 
 class ClangCompiler(GnuLikeCompiler):
-    def __init__(self):
+    def __init__(self, defines: T.Optional[T.Dict[str, str]]):
         super().__init__()
         self.id = 'clang'
+        self.defines = defines or {}
         self.base_options.append('b_colorout')
         # TODO: this really should be part of the linker base_options, but
         # linkers don't have base_options.
@@ -56,6 +57,12 @@ def __init__(self):
     def get_colorout_args(self, colortype: str) -> T.List[str]:
         return clang_color_args[colortype][:]
 
+    def has_builtin_define(self, define: str) -> bool:
+        return define in self.defines
+
+    def get_builtin_define(self, define: str) -> T.Optional[str]:
+        return self.defines.get(define)
+
     def get_optimization_args(self, optimization_level: str) -> T.List[str]:
         return clang_optimization_args[optimization_level]
 
diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py
index 52d258dcdb..d351c8826a 100644
--- a/mesonbuild/compilers/objc.py
+++ b/mesonbuild/compilers/objc.py
@@ -86,7 +86,7 @@ def __init__(self, exelist, version, for_machine: MachineChoice,
                  **kwargs):
         ObjCCompiler.__init__(self, exelist, version, for_machine, is_cross,
                               info, exe_wrapper, **kwargs)
-        ClangCompiler.__init__(self)
+        ClangCompiler.__init__(self, [])
         default_warn_args = ['-Wall', '-Winvalid-pch']
         self.warn_args = {'0': [],
                           '1': default_warn_args,
diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py
index c8b422b35d..10555b4551 100644
--- a/mesonbuild/compilers/objcpp.py
+++ b/mesonbuild/compilers/objcpp.py
@@ -84,7 +84,7 @@ def __init__(self, exelist, version, for_machine: MachineChoice,
                  is_cross, info: 'MachineInfo', exe_wrapper=None,
                  **kwargs):
         ObjCPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, **kwargs)
-        ClangCompiler.__init__(self)
+        ClangCompiler.__init__(self, [])
         default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
         self.warn_args = {'0': [],
                           '1': default_warn_args,
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 8fad6288b1..cb6ae7d514 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -726,6 +726,28 @@ def get_lcc_version_from_defines(defines):
         minor = defines.get('__LCC_MINOR__', '0')
         return dot.join((generation, major, minor))
 
+    @staticmethod
+    def get_clang_compiler_defines(compiler):
+        """
+        Get the list of Clang pre-processor defines
+        """
+        args = compiler + ['-E', '-dM', '-']
+        p, output, error = Popen_safe(args, write='', stdin=subprocess.PIPE)
+        if p.returncode != 0:
+            raise EnvironmentException('Unable to get clang pre-processor defines:\n' + output + error)
+        defines = {}
+        for line in output.split('\n'):
+            if not line:
+                continue
+            d, *rest = line.split(' ', 2)
+            if d != '#define':
+                continue
+            if len(rest) == 1:
+                defines[rest] = True
+            if len(rest) == 2:
+                defines[rest[0]] = rest[1]
+        return defines
+
     def _get_compilers(self, lang, for_machine):
         '''
         The list of compilers is detected in the exact same way for
@@ -1043,6 +1065,8 @@ def sanitize(p):
             if 'clang' in out:
                 linker = None
 
+                defines = self.get_clang_compiler_defines(compiler)
+
                 # Even if the for_machine is darwin, we could be using vanilla
                 # clang.
                 if 'Apple' in out:
@@ -1063,7 +1087,7 @@ def sanitize(p):
 
                 return cls(
                     ccache + compiler, version, for_machine, is_cross, info,
-                    exe_wrap, full_version=full_version, linker=linker)
+                    exe_wrap, defines, full_version=full_version, linker=linker)
 
             if 'Intel(R) C++ Intel(R)' in err:
                 version = search_version(err)