c.py 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  1. # Copyright 2012-2017 The Meson development team
  2. # Licensed under the Apache License, Version 2.0 (the "License");
  3. # you may not use this file except in compliance with the License.
  4. # You may obtain a copy of the License at
  5. # http://www.apache.org/licenses/LICENSE-2.0
  6. # Unless required by applicable law or agreed to in writing, software
  7. # distributed under the License is distributed on an "AS IS" BASIS,
  8. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. # See the License for the specific language governing permissions and
  10. # limitations under the License.
  11. import subprocess, os.path, tempfile
  12. from .. import mlog
  13. from .. import coredata
  14. from ..mesonlib import EnvironmentException, version_compare, Popen_safe
  15. from .compilers import (
  16. GCC_MINGW,
  17. get_largefile_args,
  18. gnu_winlibs,
  19. msvc_buildtype_args,
  20. msvc_buildtype_linker_args,
  21. msvc_winlibs,
  22. vs32_instruction_set_args,
  23. vs64_instruction_set_args,
  24. ClangCompiler,
  25. Compiler,
  26. CompilerArgs,
  27. CrossNoRunException,
  28. GnuCompiler,
  29. IntelCompiler,
  30. RunResult,
  31. )
  32. class CCompiler(Compiler):
  33. def __init__(self, exelist, version, is_cross, exe_wrapper=None):
  34. # If a child ObjC or CPP class has already set it, don't set it ourselves
  35. if not hasattr(self, 'language'):
  36. self.language = 'c'
  37. super().__init__(exelist, version)
  38. self.id = 'unknown'
  39. self.is_cross = is_cross
  40. self.can_compile_suffixes.add('h')
  41. if isinstance(exe_wrapper, str):
  42. self.exe_wrapper = [exe_wrapper]
  43. else:
  44. self.exe_wrapper = exe_wrapper
  45. def needs_static_linker(self):
  46. return True # When compiling static libraries, so yes.
  47. def get_always_args(self):
  48. '''
  49. Args that are always-on for all C compilers other than MSVC
  50. '''
  51. return ['-pipe'] + get_largefile_args(self)
  52. def get_linker_debug_crt_args(self):
  53. """
  54. Arguments needed to select a debug crt for the linker
  55. This is only needed for MSVC
  56. """
  57. return []
  58. def get_no_stdinc_args(self):
  59. return ['-nostdinc']
  60. def get_no_stdlib_link_args(self):
  61. return ['-nostdlib']
  62. def get_warn_args(self, level):
  63. return self.warn_args[level]
  64. def get_no_warn_args(self):
  65. # Almost every compiler uses this for disabling warnings
  66. return ['-w']
  67. def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module):
  68. return []
  69. def split_shlib_to_parts(self, fname):
  70. return None, fname
  71. # The default behavior is this, override in MSVC
  72. def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
  73. return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
  74. def get_dependency_gen_args(self, outtarget, outfile):
  75. return ['-MMD', '-MQ', outtarget, '-MF', outfile]
  76. def depfile_for_object(self, objfile):
  77. return objfile + '.' + self.get_depfile_suffix()
  78. def get_depfile_suffix(self):
  79. return 'd'
  80. def get_exelist(self):
  81. return self.exelist[:]
  82. def get_linker_exelist(self):
  83. return self.exelist[:]
  84. def get_preprocess_only_args(self):
  85. return ['-E', '-P']
  86. def get_compile_only_args(self):
  87. return ['-c']
  88. def get_no_optimization_args(self):
  89. return ['-O0']
  90. def get_compiler_check_args(self):
  91. '''
  92. Get arguments useful for compiler checks such as being permissive in
  93. the code quality and not doing any optimization.
  94. '''
  95. return self.get_no_optimization_args()
  96. def get_output_args(self, target):
  97. return ['-o', target]
  98. def get_linker_output_args(self, outputname):
  99. return ['-o', outputname]
  100. def get_coverage_args(self):
  101. return ['--coverage']
  102. def get_coverage_link_args(self):
  103. return ['--coverage']
  104. def get_werror_args(self):
  105. return ['-Werror']
  106. def get_std_exe_link_args(self):
  107. return []
  108. def get_include_args(self, path, is_system):
  109. if path == '':
  110. path = '.'
  111. if is_system:
  112. return ['-isystem', path]
  113. return ['-I' + path]
  114. def get_std_shared_lib_link_args(self):
  115. return ['-shared']
  116. def get_library_dirs(self):
  117. stdo = Popen_safe(self.exelist + ['--print-search-dirs'])[1]
  118. for line in stdo.split('\n'):
  119. if line.startswith('libraries:'):
  120. libstr = line.split('=', 1)[1]
  121. return libstr.split(':')
  122. return []
  123. def get_pic_args(self):
  124. return ['-fPIC']
  125. def name_string(self):
  126. return ' '.join(self.exelist)
  127. def get_pch_use_args(self, pch_dir, header):
  128. return ['-include', os.path.split(header)[-1]]
  129. def get_pch_name(self, header_name):
  130. return os.path.split(header_name)[-1] + '.' + self.get_pch_suffix()
  131. def get_linker_search_args(self, dirname):
  132. return ['-L' + dirname]
  133. def gen_import_library_args(self, implibname):
  134. """
  135. The name of the outputted import library
  136. This implementation is used only on Windows by compilers that use GNU ld
  137. """
  138. return ['-Wl,--out-implib=' + implibname]
  139. def sanity_check_impl(self, work_dir, environment, sname, code):
  140. mlog.debug('Sanity testing ' + self.get_display_language() + ' compiler:', ' '.join(self.exelist))
  141. mlog.debug('Is cross compiler: %s.' % str(self.is_cross))
  142. extra_flags = []
  143. source_name = os.path.join(work_dir, sname)
  144. binname = sname.rsplit('.', 1)[0]
  145. if self.is_cross:
  146. binname += '_cross'
  147. if self.exe_wrapper is None:
  148. # Linking cross built apps is painful. You can't really
  149. # tell if you should use -nostdlib or not and for example
  150. # on OSX the compiler binary is the same but you need
  151. # a ton of compiler flags to differentiate between
  152. # arm and x86_64. So just compile.
  153. extra_flags += self.get_cross_extra_flags(environment, link=False)
  154. extra_flags += self.get_compile_only_args()
  155. else:
  156. extra_flags += self.get_cross_extra_flags(environment, link=True)
  157. # Is a valid executable output for all toolchains and platforms
  158. binname += '.exe'
  159. # Write binary check source
  160. binary_name = os.path.join(work_dir, binname)
  161. with open(source_name, 'w') as ofile:
  162. ofile.write(code)
  163. # Compile sanity check
  164. cmdlist = self.exelist + extra_flags + [source_name] + self.get_output_args(binary_name)
  165. pc, stdo, stde = Popen_safe(cmdlist, cwd=work_dir)
  166. mlog.debug('Sanity check compiler command line:', ' '.join(cmdlist))
  167. mlog.debug('Sanity check compile stdout:')
  168. mlog.debug(stdo)
  169. mlog.debug('-----\nSanity check compile stderr:')
  170. mlog.debug(stde)
  171. mlog.debug('-----')
  172. if pc.returncode != 0:
  173. raise EnvironmentException('Compiler {0} can not compile programs.'.format(self.name_string()))
  174. # Run sanity check
  175. if self.is_cross:
  176. if self.exe_wrapper is None:
  177. # Can't check if the binaries run so we have to assume they do
  178. return
  179. cmdlist = self.exe_wrapper + [binary_name]
  180. else:
  181. cmdlist = [binary_name]
  182. mlog.debug('Running test binary command: ' + ' '.join(cmdlist))
  183. pe = subprocess.Popen(cmdlist)
  184. pe.wait()
  185. if pe.returncode != 0:
  186. raise EnvironmentException('Executables created by {0} compiler {1} are not runnable.'.format(self.language, self.name_string()))
  187. def sanity_check(self, work_dir, environment):
  188. code = 'int main(int argc, char **argv) { int class=0; return class; }\n'
  189. return self.sanity_check_impl(work_dir, environment, 'sanitycheckc.c', code)
  190. def has_header(self, hname, prefix, env, extra_args=None, dependencies=None):
  191. fargs = {'prefix': prefix, 'header': hname}
  192. code = '''{prefix}
  193. #ifdef __has_include
  194. #if !__has_include("{header}")
  195. #error "Header '{header}' could not be found"
  196. #endif
  197. #else
  198. #include <{header}>
  199. #endif'''
  200. return self.compiles(code.format(**fargs), env, extra_args,
  201. dependencies, 'preprocess')
  202. def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
  203. fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol}
  204. t = '''{prefix}
  205. #include <{header}>
  206. int main () {{
  207. /* If it's not defined as a macro, try to use as a symbol */
  208. #ifndef {symbol}
  209. {symbol};
  210. #endif
  211. }}'''
  212. return self.compiles(t.format(**fargs), env, extra_args, dependencies)
  213. def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
  214. if extra_args is None:
  215. extra_args = []
  216. elif isinstance(extra_args, str):
  217. extra_args = [extra_args]
  218. if dependencies is None:
  219. dependencies = []
  220. elif not isinstance(dependencies, list):
  221. dependencies = [dependencies]
  222. # Collect compiler arguments
  223. args = CompilerArgs(self)
  224. for d in dependencies:
  225. # Add compile flags needed by dependencies
  226. args += d.get_compile_args()
  227. if d.need_threads():
  228. args += self.thread_flags()
  229. if mode == 'link':
  230. # Add link flags needed to find dependencies
  231. args += d.get_link_args()
  232. if d.need_threads():
  233. args += self.thread_link_flags()
  234. # Select a CRT if needed since we're linking
  235. if mode == 'link':
  236. args += self.get_linker_debug_crt_args()
  237. # Read c_args/cpp_args/etc from the cross-info file (if needed)
  238. args += self.get_cross_extra_flags(env, link=(mode == 'link'))
  239. if not self.is_cross:
  240. if mode == 'preprocess':
  241. # Add CPPFLAGS from the env.
  242. args += env.coredata.external_preprocess_args[self.language]
  243. elif mode == 'compile':
  244. # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS from the env
  245. args += env.coredata.external_args[self.language]
  246. elif mode == 'link':
  247. # Add LDFLAGS from the env
  248. args += env.coredata.external_link_args[self.language]
  249. args += self.get_compiler_check_args()
  250. # extra_args must override all other arguments, so we add them last
  251. args += extra_args
  252. return args
  253. def compiles(self, code, env, extra_args=None, dependencies=None, mode='compile'):
  254. args = self._get_compiler_check_args(env, extra_args, dependencies, mode)
  255. # We only want to compile; not link
  256. with self.compile(code, args.to_native(), mode) as p:
  257. return p.returncode == 0
  258. def _links_wrapper(self, code, env, extra_args, dependencies):
  259. "Shares common code between self.links and self.run"
  260. args = self._get_compiler_check_args(env, extra_args, dependencies, mode='link')
  261. return self.compile(code, args)
  262. def links(self, code, env, extra_args=None, dependencies=None):
  263. with self._links_wrapper(code, env, extra_args, dependencies) as p:
  264. return p.returncode == 0
  265. def run(self, code, env, extra_args=None, dependencies=None):
  266. if self.is_cross and self.exe_wrapper is None:
  267. raise CrossNoRunException('Can not run test applications in this cross environment.')
  268. with self._links_wrapper(code, env, extra_args, dependencies) as p:
  269. if p.returncode != 0:
  270. mlog.debug('Could not compile test file %s: %d\n' % (
  271. p.input_name,
  272. p.returncode))
  273. return RunResult(False)
  274. if self.is_cross:
  275. cmdlist = self.exe_wrapper + [p.output_name]
  276. else:
  277. cmdlist = p.output_name
  278. try:
  279. pe, so, se = Popen_safe(cmdlist)
  280. except Exception as e:
  281. mlog.debug('Could not run: %s (error: %s)\n' % (cmdlist, e))
  282. return RunResult(False)
  283. mlog.debug('Program stdout:\n')
  284. mlog.debug(so)
  285. mlog.debug('Program stderr:\n')
  286. mlog.debug(se)
  287. return RunResult(True, pe.returncode, so, se)
  288. def _compile_int(self, expression, prefix, env, extra_args, dependencies):
  289. fargs = {'prefix': prefix, 'expression': expression}
  290. t = '''#include <stdio.h>
  291. {prefix}
  292. int main() {{ static int a[1-2*!({expression})]; a[0]=0; return 0; }}'''
  293. return self.compiles(t.format(**fargs), env, extra_args, dependencies)
  294. def cross_compute_int(self, expression, low, high, guess, prefix, env, extra_args, dependencies):
  295. if isinstance(guess, int):
  296. if self._compile_int('%s == %d' % (expression, guess), prefix, env, extra_args, dependencies):
  297. return guess
  298. cur = low
  299. while low < high:
  300. cur = int((low + high) / 2)
  301. if cur == low:
  302. break
  303. if self._compile_int('%s >= %d' % (expression, cur), prefix, env, extra_args, dependencies):
  304. low = cur
  305. else:
  306. high = cur
  307. if self._compile_int('%s == %d' % (expression, cur), prefix, env, extra_args, dependencies):
  308. return cur
  309. raise EnvironmentException('Cross-compile check overflowed')
  310. def compute_int(self, expression, low, high, guess, prefix, env, extra_args=None, dependencies=None):
  311. if extra_args is None:
  312. extra_args = []
  313. if self.is_cross:
  314. return self.cross_compute_int(expression, low, high, guess, prefix, env, extra_args, dependencies)
  315. fargs = {'prefix': prefix, 'expression': expression}
  316. t = '''#include<stdio.h>
  317. {prefix}
  318. int main(int argc, char **argv) {{
  319. printf("%ld\\n", (long)({expression}));
  320. return 0;
  321. }};'''
  322. res = self.run(t.format(**fargs), env, extra_args, dependencies)
  323. if not res.compiled:
  324. return -1
  325. if res.returncode != 0:
  326. raise EnvironmentException('Could not run compute_int test binary.')
  327. return int(res.stdout)
  328. def cross_sizeof(self, typename, prefix, env, extra_args=None, dependencies=None):
  329. if extra_args is None:
  330. extra_args = []
  331. fargs = {'prefix': prefix, 'type': typename}
  332. t = '''#include <stdio.h>
  333. {prefix}
  334. int main(int argc, char **argv) {{
  335. {type} something;
  336. }}'''
  337. if not self.compiles(t.format(**fargs), env, extra_args, dependencies):
  338. return -1
  339. return self.cross_compute_int('sizeof(%s)' % typename, 1, 128, None, prefix, env, extra_args, dependencies)
  340. def sizeof(self, typename, prefix, env, extra_args=None, dependencies=None):
  341. if extra_args is None:
  342. extra_args = []
  343. fargs = {'prefix': prefix, 'type': typename}
  344. if self.is_cross:
  345. return self.cross_sizeof(typename, prefix, env, extra_args, dependencies)
  346. t = '''#include<stdio.h>
  347. {prefix}
  348. int main(int argc, char **argv) {{
  349. printf("%ld\\n", (long)(sizeof({type})));
  350. return 0;
  351. }};'''
  352. res = self.run(t.format(**fargs), env, extra_args, dependencies)
  353. if not res.compiled:
  354. return -1
  355. if res.returncode != 0:
  356. raise EnvironmentException('Could not run sizeof test binary.')
  357. return int(res.stdout)
  358. def cross_alignment(self, typename, prefix, env, extra_args=None, dependencies=None):
  359. if extra_args is None:
  360. extra_args = []
  361. fargs = {'prefix': prefix, 'type': typename}
  362. t = '''#include <stdio.h>
  363. {prefix}
  364. int main(int argc, char **argv) {{
  365. {type} something;
  366. }}'''
  367. if not self.compiles(t.format(**fargs), env, extra_args, dependencies):
  368. return -1
  369. t = '''#include <stddef.h>
  370. {prefix}
  371. struct tmp {{
  372. char c;
  373. {type} target;
  374. }};'''
  375. return self.cross_compute_int('offsetof(struct tmp, target)', 1, 1024, None, t.format(**fargs), env, extra_args, dependencies)
  376. def alignment(self, typename, prefix, env, extra_args=None, dependencies=None):
  377. if extra_args is None:
  378. extra_args = []
  379. if self.is_cross:
  380. return self.cross_alignment(typename, prefix, env, extra_args, dependencies)
  381. fargs = {'prefix': prefix, 'type': typename}
  382. t = '''#include <stdio.h>
  383. #include <stddef.h>
  384. {prefix}
  385. struct tmp {{
  386. char c;
  387. {type} target;
  388. }};
  389. int main(int argc, char **argv) {{
  390. printf("%d", (int)offsetof(struct tmp, target));
  391. return 0;
  392. }}'''
  393. res = self.run(t.format(**fargs), env, extra_args, dependencies)
  394. if not res.compiled:
  395. raise EnvironmentException('Could not compile alignment test.')
  396. if res.returncode != 0:
  397. raise EnvironmentException('Could not run alignment test binary.')
  398. align = int(res.stdout)
  399. if align == 0:
  400. raise EnvironmentException('Could not determine alignment of %s. Sorry. You might want to file a bug.' % typename)
  401. return align
  402. def get_define(self, dname, prefix, env, extra_args, dependencies):
  403. delim = '"MESON_GET_DEFINE_DELIMITER"'
  404. fargs = {'prefix': prefix, 'define': dname, 'delim': delim}
  405. code = '''
  406. {prefix}
  407. #ifndef {define}
  408. # define {define}
  409. #endif
  410. {delim}\n{define}'''
  411. args = self._get_compiler_check_args(env, extra_args, dependencies,
  412. mode='preprocess').to_native()
  413. with self.compile(code.format(**fargs), args, 'preprocess') as p:
  414. if p.returncode != 0:
  415. raise EnvironmentException('Could not get define {!r}'.format(dname))
  416. # Get the preprocessed value after the delimiter,
  417. # minus the extra newline at the end
  418. return p.stdo.split(delim + '\n')[-1][:-1]
  419. @staticmethod
  420. def _no_prototype_templ():
  421. """
  422. Try to find the function without a prototype from a header by defining
  423. our own dummy prototype and trying to link with the C library (and
  424. whatever else the compiler links in by default). This is very similar
  425. to the check performed by Autoconf for AC_CHECK_FUNCS.
  426. """
  427. # Define the symbol to something else since it is defined by the
  428. # includes or defines listed by the user or by the compiler. This may
  429. # include, for instance _GNU_SOURCE which must be defined before
  430. # limits.h, which includes features.h
  431. # Then, undef the symbol to get rid of it completely.
  432. head = '''
  433. #define {func} meson_disable_define_of_{func}
  434. {prefix}
  435. #include <limits.h>
  436. #undef {func}
  437. '''
  438. # Override any GCC internal prototype and declare our own definition for
  439. # the symbol. Use char because that's unlikely to be an actual return
  440. # value for a function which ensures that we override the definition.
  441. head += '''
  442. #ifdef __cplusplus
  443. extern "C"
  444. #endif
  445. char {func} ();
  446. '''
  447. # The actual function call
  448. main = '''
  449. int main () {{
  450. return {func} ();
  451. }}'''
  452. return head, main
  453. @staticmethod
  454. def _have_prototype_templ():
  455. """
  456. Returns a head-er and main() call that uses the headers listed by the
  457. user for the function prototype while checking if a function exists.
  458. """
  459. # Add the 'prefix', aka defines, includes, etc that the user provides
  460. # This may include, for instance _GNU_SOURCE which must be defined
  461. # before limits.h, which includes features.h
  462. head = '{prefix}\n#include <limits.h>\n'
  463. # We don't know what the function takes or returns, so return it as an int.
  464. # Just taking the address or comparing it to void is not enough because
  465. # compilers are smart enough to optimize it away. The resulting binary
  466. # is not run so we don't care what the return value is.
  467. main = '''\nint main() {{
  468. void *a = (void*) &{func};
  469. long b = (long) a;
  470. return (int) b;
  471. }}'''
  472. return head, main
  473. def has_function(self, funcname, prefix, env, extra_args=None, dependencies=None):
  474. """
  475. First, this function looks for the symbol in the default libraries
  476. provided by the compiler (stdlib + a few others usually). If that
  477. fails, it checks if any of the headers specified in the prefix provide
  478. an implementation of the function, and if that fails, it checks if it's
  479. implemented as a compiler-builtin.
  480. """
  481. if extra_args is None:
  482. extra_args = []
  483. # Short-circuit if the check is already provided by the cross-info file
  484. varname = 'has function ' + funcname
  485. varname = varname.replace(' ', '_')
  486. if self.is_cross:
  487. val = env.cross_info.config['properties'].get(varname, None)
  488. if val is not None:
  489. if isinstance(val, bool):
  490. return val
  491. raise EnvironmentException('Cross variable {0} is not a boolean.'.format(varname))
  492. fargs = {'prefix': prefix, 'func': funcname}
  493. # glibc defines functions that are not available on Linux as stubs that
  494. # fail with ENOSYS (such as e.g. lchmod). In this case we want to fail
  495. # instead of detecting the stub as a valid symbol.
  496. # We already included limits.h earlier to ensure that these are defined
  497. # for stub functions.
  498. stubs_fail = '''
  499. #if defined __stub_{func} || defined __stub___{func}
  500. fail fail fail this function is not going to work
  501. #endif
  502. '''
  503. # If we have any includes in the prefix supplied by the user, assume
  504. # that the user wants us to use the symbol prototype defined in those
  505. # includes. If not, then try to do the Autoconf-style check with
  506. # a dummy prototype definition of our own.
  507. # This is needed when the linker determines symbol availability from an
  508. # SDK based on the prototype in the header provided by the SDK.
  509. # Ignoring this prototype would result in the symbol always being
  510. # marked as available.
  511. if '#include' in prefix:
  512. head, main = self._have_prototype_templ()
  513. else:
  514. head, main = self._no_prototype_templ()
  515. templ = head + stubs_fail + main
  516. if self.links(templ.format(**fargs), env, extra_args, dependencies):
  517. return True
  518. # MSVC does not have compiler __builtin_-s.
  519. if self.get_id() == 'msvc':
  520. return False
  521. # Detect function as a built-in
  522. #
  523. # Some functions like alloca() are defined as compiler built-ins which
  524. # are inlined by the compiler and you can't take their address, so we
  525. # need to look for them differently. On nice compilers like clang, we
  526. # can just directly use the __has_builtin() macro.
  527. fargs['no_includes'] = '#include' not in prefix
  528. t = '''{prefix}
  529. int main() {{
  530. #ifdef __has_builtin
  531. #if !__has_builtin(__builtin_{func})
  532. #error "__builtin_{func} not found"
  533. #endif
  534. #elif ! defined({func})
  535. /* Check for __builtin_{func} only if no includes were added to the
  536. * prefix above, which means no definition of {func} can be found.
  537. * We would always check for this, but we get false positives on
  538. * MSYS2 if we do. Their toolchain is broken, but we can at least
  539. * give them a workaround. */
  540. #if {no_includes:d}
  541. __builtin_{func};
  542. #else
  543. #error "No definition for __builtin_{func} found in the prefix"
  544. #endif
  545. #endif
  546. }}'''
  547. return self.links(t.format(**fargs), env, extra_args, dependencies)
  548. def has_members(self, typename, membernames, prefix, env, extra_args=None, dependencies=None):
  549. if extra_args is None:
  550. extra_args = []
  551. fargs = {'prefix': prefix, 'type': typename, 'name': 'foo'}
  552. # Create code that accesses all members
  553. members = ''
  554. for member in membernames:
  555. members += '{}.{};\n'.format(fargs['name'], member)
  556. fargs['members'] = members
  557. t = '''{prefix}
  558. void bar() {{
  559. {type} {name};
  560. {members}
  561. }};'''
  562. return self.compiles(t.format(**fargs), env, extra_args, dependencies)
  563. def has_type(self, typename, prefix, env, extra_args, dependencies=None):
  564. fargs = {'prefix': prefix, 'type': typename}
  565. t = '''{prefix}
  566. void bar() {{
  567. sizeof({type});
  568. }};'''
  569. return self.compiles(t.format(**fargs), env, extra_args, dependencies)
  570. def symbols_have_underscore_prefix(self, env):
  571. '''
  572. Check if the compiler prefixes an underscore to global C symbols
  573. '''
  574. symbol_name = b'meson_uscore_prefix'
  575. code = '''#ifdef __cplusplus
  576. extern "C" {
  577. #endif
  578. void ''' + symbol_name.decode() + ''' () {}
  579. #ifdef __cplusplus
  580. }
  581. #endif
  582. '''
  583. args = self.get_cross_extra_flags(env, link=False)
  584. args += self.get_compiler_check_args()
  585. n = 'symbols_have_underscore_prefix'
  586. with self.compile(code, args, 'compile') as p:
  587. if p.returncode != 0:
  588. m = 'BUG: Unable to compile {!r} check: {}'
  589. raise RuntimeError(m.format(n, p.stdo))
  590. if not os.path.isfile(p.output_name):
  591. m = 'BUG: Can\'t find compiled test code for {!r} check'
  592. raise RuntimeError(m.format(n))
  593. with open(p.output_name, 'rb') as o:
  594. for line in o:
  595. # Check if the underscore form of the symbol is somewhere
  596. # in the output file.
  597. if b'_' + symbol_name in line:
  598. return True
  599. # Else, check if the non-underscored form is present
  600. elif symbol_name in line:
  601. return False
  602. raise RuntimeError('BUG: {!r} check failed unexpectedly'.format(n))
  603. def find_library(self, libname, env, extra_dirs):
  604. # These libraries are either built-in or invalid
  605. if libname in self.ignore_libs:
  606. return []
  607. # First try if we can just add the library as -l.
  608. code = 'int main(int argc, char **argv) { return 0; }'
  609. if extra_dirs and isinstance(extra_dirs, str):
  610. extra_dirs = [extra_dirs]
  611. # Gcc + co seem to prefer builtin lib dirs to -L dirs.
  612. # Only try to find std libs if no extra dirs specified.
  613. if not extra_dirs:
  614. args = ['-l' + libname]
  615. if self.links(code, env, extra_args=args):
  616. return args
  617. # Not found? Try to find the library file itself.
  618. extra_dirs += self.get_library_dirs()
  619. suffixes = ['so', 'dylib', 'lib', 'dll', 'a']
  620. for d in extra_dirs:
  621. for suffix in suffixes:
  622. trial = os.path.join(d, 'lib' + libname + '.' + suffix)
  623. if os.path.isfile(trial):
  624. return [trial]
  625. trial2 = os.path.join(d, libname + '.' + suffix)
  626. if os.path.isfile(trial2):
  627. return [trial2]
  628. return None
  629. def thread_flags(self):
  630. return ['-pthread']
  631. def thread_link_flags(self):
  632. return ['-pthread']
  633. def has_multi_arguments(self, args, env):
  634. return self.compiles('int i;\n', env, extra_args=args)
  635. class ClangCCompiler(ClangCompiler, CCompiler):
  636. def __init__(self, exelist, version, clang_type, is_cross, exe_wrapper=None):
  637. CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
  638. ClangCompiler.__init__(self, clang_type)
  639. default_warn_args = ['-Wall', '-Winvalid-pch']
  640. self.warn_args = {'1': default_warn_args,
  641. '2': default_warn_args + ['-Wextra'],
  642. '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  643. def get_options(self):
  644. return {'c_std': coredata.UserComboOption('c_std', 'C language standard to use',
  645. ['none', 'c89', 'c99', 'c11',
  646. 'gnu89', 'gnu99', 'gnu11'],
  647. 'none')}
  648. def get_option_compile_args(self, options):
  649. args = []
  650. std = options['c_std']
  651. if std.value != 'none':
  652. args.append('-std=' + std.value)
  653. return args
  654. def get_option_link_args(self, options):
  655. return []
  656. class GnuCCompiler(GnuCompiler, CCompiler):
  657. def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None):
  658. CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
  659. GnuCompiler.__init__(self, gcc_type, defines)
  660. default_warn_args = ['-Wall', '-Winvalid-pch']
  661. self.warn_args = {'1': default_warn_args,
  662. '2': default_warn_args + ['-Wextra'],
  663. '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  664. def get_options(self):
  665. opts = {'c_std': coredata.UserComboOption('c_std', 'C language standard to use',
  666. ['none', 'c89', 'c99', 'c11',
  667. 'gnu89', 'gnu99', 'gnu11'],
  668. 'none')}
  669. if self.gcc_type == GCC_MINGW:
  670. opts.update({
  671. 'c_winlibs': coredata.UserStringArrayOption('c_winlibs', 'Standard Win libraries to link against',
  672. gnu_winlibs), })
  673. return opts
  674. def get_option_compile_args(self, options):
  675. args = []
  676. std = options['c_std']
  677. if std.value != 'none':
  678. args.append('-std=' + std.value)
  679. return args
  680. def get_option_link_args(self, options):
  681. if self.gcc_type == GCC_MINGW:
  682. return options['c_winlibs'].value[:]
  683. return []
  684. def get_std_shared_lib_link_args(self):
  685. return ['-shared']
  686. class IntelCCompiler(IntelCompiler, CCompiler):
  687. def __init__(self, exelist, version, icc_type, is_cross, exe_wrapper=None):
  688. CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
  689. IntelCompiler.__init__(self, icc_type)
  690. self.lang_header = 'c-header'
  691. default_warn_args = ['-Wall', '-w3', '-diag-disable:remark', '-Wpch-messages']
  692. self.warn_args = {'1': default_warn_args,
  693. '2': default_warn_args + ['-Wextra'],
  694. '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  695. def get_options(self):
  696. c_stds = ['c89', 'c99']
  697. g_stds = ['gnu89', 'gnu99']
  698. if version_compare(self.version, '>=16.0.0'):
  699. c_stds += ['c11']
  700. opts = {'c_std': coredata.UserComboOption('c_std', 'C language standard to use',
  701. ['none'] + c_stds + g_stds,
  702. 'none')}
  703. return opts
  704. def get_option_compile_args(self, options):
  705. args = []
  706. std = options['c_std']
  707. if std.value != 'none':
  708. args.append('-std=' + std.value)
  709. return args
  710. def get_std_shared_lib_link_args(self):
  711. return ['-shared']
  712. def has_multi_arguments(self, args, env):
  713. return super().has_multi_arguments(args + ['-diag-error', '10006'], env)
  714. class VisualStudioCCompiler(CCompiler):
  715. std_warn_args = ['/W3']
  716. std_opt_args = ['/O2']
  717. ignore_libs = ('m', 'c', 'pthread')
  718. def __init__(self, exelist, version, is_cross, exe_wrap, is_64):
  719. CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
  720. self.id = 'msvc'
  721. # /showIncludes is needed for build dependency tracking in Ninja
  722. # See: https://ninja-build.org/manual.html#_deps
  723. self.always_args = ['/nologo', '/showIncludes']
  724. self.warn_args = {'1': ['/W2'],
  725. '2': ['/W3'],
  726. '3': ['/W4']}
  727. self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
  728. self.is_64 = is_64
  729. # Override CCompiler.get_always_args
  730. def get_always_args(self):
  731. return self.always_args
  732. def get_linker_debug_crt_args(self):
  733. """
  734. Arguments needed to select a debug crt for the linker
  735. Sometimes we need to manually select the CRT (C runtime) to use with
  736. MSVC. One example is when trying to link with static libraries since
  737. MSVC won't auto-select a CRT for us in that case and will error out
  738. asking us to select one.
  739. """
  740. return ['/MDd']
  741. def get_buildtype_args(self, buildtype):
  742. return msvc_buildtype_args[buildtype]
  743. def get_buildtype_linker_args(self, buildtype):
  744. return msvc_buildtype_linker_args[buildtype]
  745. def get_pch_suffix(self):
  746. return 'pch'
  747. def get_pch_name(self, header):
  748. chopped = os.path.split(header)[-1].split('.')[:-1]
  749. chopped.append(self.get_pch_suffix())
  750. pchname = '.'.join(chopped)
  751. return pchname
  752. def get_pch_use_args(self, pch_dir, header):
  753. base = os.path.split(header)[-1]
  754. pchname = self.get_pch_name(header)
  755. return ['/FI' + base, '/Yu' + base, '/Fp' + os.path.join(pch_dir, pchname)]
  756. def get_preprocess_only_args(self):
  757. return ['/EP']
  758. def get_compile_only_args(self):
  759. return ['/c']
  760. def get_no_optimization_args(self):
  761. return ['/Od']
  762. def get_output_args(self, target):
  763. if target.endswith('.exe'):
  764. return ['/Fe' + target]
  765. return ['/Fo' + target]
  766. def get_dependency_gen_args(self, outtarget, outfile):
  767. return []
  768. def get_linker_exelist(self):
  769. return ['link'] # FIXME, should have same path as compiler.
  770. def get_linker_always_args(self):
  771. return ['/nologo']
  772. def get_linker_output_args(self, outputname):
  773. return ['/OUT:' + outputname]
  774. def get_linker_search_args(self, dirname):
  775. return ['/LIBPATH:' + dirname]
  776. def get_pic_args(self):
  777. return [] # PIC is handled by the loader on Windows
  778. def get_std_shared_lib_link_args(self):
  779. return ['/DLL']
  780. def gen_vs_module_defs_args(self, defsfile):
  781. if not isinstance(defsfile, str):
  782. raise RuntimeError('Module definitions file should be str')
  783. # With MSVC, DLLs only export symbols that are explicitly exported,
  784. # so if a module defs file is specified, we use that to export symbols
  785. return ['/DEF:' + defsfile]
  786. def gen_pch_args(self, header, source, pchname):
  787. objname = os.path.splitext(pchname)[0] + '.obj'
  788. return objname, ['/Yc' + header, '/Fp' + pchname, '/Fo' + objname]
  789. def gen_import_library_args(self, implibname):
  790. "The name of the outputted import library"
  791. return ['/IMPLIB:' + implibname]
  792. def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
  793. return []
  794. # FIXME, no idea what these should be.
  795. def thread_flags(self):
  796. return []
  797. def thread_link_flags(self):
  798. return []
  799. def get_options(self):
  800. return {'c_winlibs': coredata.UserStringArrayOption('c_winlibs',
  801. 'Windows libs to link against.',
  802. msvc_winlibs)
  803. }
  804. def get_option_link_args(self, options):
  805. return options['c_winlibs'].value[:]
  806. @classmethod
  807. def unix_args_to_native(cls, args):
  808. result = []
  809. for i in args:
  810. # -mms-bitfields is specific to MinGW-GCC
  811. # -pthread is only valid for GCC
  812. if i in ('-mms-bitfields', '-pthread'):
  813. continue
  814. if i.startswith('-L'):
  815. i = '/LIBPATH:' + i[2:]
  816. # Translate GNU-style -lfoo library name to the import library
  817. elif i.startswith('-l'):
  818. name = i[2:]
  819. if name in cls.ignore_libs:
  820. # With MSVC, these are provided by the C runtime which is
  821. # linked in by default
  822. continue
  823. else:
  824. i = name + '.lib'
  825. # -pthread in link flags is only used on Linux
  826. elif i == '-pthread':
  827. continue
  828. result.append(i)
  829. return result
  830. def get_werror_args(self):
  831. return ['/WX']
  832. def get_include_args(self, path, is_system):
  833. if path == '':
  834. path = '.'
  835. # msvc does not have a concept of system header dirs.
  836. return ['-I' + path]
  837. # Visual Studio is special. It ignores some arguments it does not
  838. # understand and you can't tell it to error out on those.
  839. # http://stackoverflow.com/questions/15259720/how-can-i-make-the-microsoft-c-compiler-treat-unknown-flags-as-errors-rather-t
  840. def has_multi_arguments(self, args, env):
  841. warning_text = '9002'
  842. code = 'int i;\n'
  843. (fd, srcname) = tempfile.mkstemp(suffix='.' + self.default_suffix)
  844. os.close(fd)
  845. with open(srcname, 'w') as ofile:
  846. ofile.write(code)
  847. # Read c_args/cpp_args/etc from the cross-info file (if needed)
  848. extra_args = self.get_cross_extra_flags(env, link=False)
  849. extra_args += self.get_compile_only_args()
  850. commands = self.exelist + args + extra_args + [srcname]
  851. mlog.debug('Running VS compile:')
  852. mlog.debug('Command line: ', ' '.join(commands))
  853. mlog.debug('Code:\n', code)
  854. p, stdo, stde = Popen_safe(commands, cwd=os.path.split(srcname)[0])
  855. if p.returncode != 0:
  856. return False
  857. return not(warning_text in stde or warning_text in stdo)
  858. def get_compile_debugfile_args(self, rel_obj, pch=False):
  859. pdbarr = rel_obj.split('.')[:-1]
  860. pdbarr += ['pdb']
  861. args = ['/Fd' + '.'.join(pdbarr)]
  862. # When generating a PDB file with PCH, all compile commands write
  863. # to the same PDB file. Hence, we need to serialize the PDB
  864. # writes using /FS since we do parallel builds. This slows down the
  865. # build obviously, which is why we only do this when PCH is on.
  866. # This was added in Visual Studio 2013 (MSVC 18.0). Before that it was
  867. # always on: https://msdn.microsoft.com/en-us/library/dn502518.aspx
  868. if pch and version_compare(self.version, '>=18.0'):
  869. args = ['/FS'] + args
  870. return args
  871. def get_link_debugfile_args(self, targetfile):
  872. pdbarr = targetfile.split('.')[:-1]
  873. pdbarr += ['pdb']
  874. return ['/DEBUG', '/PDB:' + '.'.join(pdbarr)]
  875. def get_link_whole_for(self, args):
  876. # Only since VS2015
  877. if not isinstance(args, list):
  878. args = [args]
  879. return ['/WHOLEARCHIVE:' + x for x in args]
  880. def get_instruction_set_args(self, instruction_set):
  881. if self.is_64:
  882. return vs64_instruction_set_args.get(instruction_set, None)
  883. if self.version.split('.')[0] == '16' and instruction_set == 'avx':
  884. # VS documentation says that this exists and should work, but
  885. # it does not. The headers do not contain AVX intrinsics
  886. # and the can not be called.
  887. return None
  888. return vs32_instruction_set_args.get(instruction_set, None)