cpp.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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. from .. import coredata
  12. from ..mesonlib import version_compare
  13. from .c import CCompiler, VisualStudioCCompiler
  14. from .compilers import (
  15. GCC_MINGW,
  16. gnu_winlibs,
  17. msvc_winlibs,
  18. ClangCompiler,
  19. GnuCompiler,
  20. IntelCompiler,
  21. )
  22. class CPPCompiler(CCompiler):
  23. def __init__(self, exelist, version, is_cross, exe_wrap):
  24. # If a child ObjCPP class has already set it, don't set it ourselves
  25. if not hasattr(self, 'language'):
  26. self.language = 'cpp'
  27. CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
  28. def get_display_language(self):
  29. return 'C++'
  30. def get_no_stdinc_args(self):
  31. return ['-nostdinc++']
  32. def sanity_check(self, work_dir, environment):
  33. code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n'
  34. return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code)
  35. def get_compiler_check_args(self):
  36. # -fpermissive allows non-conforming code to compile which is necessary
  37. # for many C++ checks. Particularly, the has_header_symbol check is
  38. # too strict without this and always fails.
  39. return super().get_compiler_check_args() + ['-fpermissive']
  40. def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
  41. # Check if it's a C-like symbol
  42. if super().has_header_symbol(hname, symbol, prefix, env, extra_args, dependencies):
  43. return True
  44. # Check if it's a class or a template
  45. if extra_args is None:
  46. extra_args = []
  47. fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol}
  48. t = '''{prefix}
  49. #include <{header}>
  50. using {symbol};
  51. int main () {{ return 0; }}'''
  52. return self.compiles(t.format(**fargs), env, extra_args, dependencies)
  53. class ClangCPPCompiler(ClangCompiler, CPPCompiler):
  54. def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None):
  55. CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
  56. ClangCompiler.__init__(self, cltype)
  57. default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
  58. self.warn_args = {'1': default_warn_args,
  59. '2': default_warn_args + ['-Wextra'],
  60. '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  61. def get_options(self):
  62. return {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
  63. ['none', 'c++03', 'c++11', 'c++14', 'c++1z',
  64. 'gnu++11', 'gnu++14', 'gnu++1z'],
  65. 'none')}
  66. def get_option_compile_args(self, options):
  67. args = []
  68. std = options['cpp_std']
  69. if std.value != 'none':
  70. args.append('-std=' + std.value)
  71. return args
  72. def get_option_link_args(self, options):
  73. return []
  74. class GnuCPPCompiler(GnuCompiler, CPPCompiler):
  75. def __init__(self, exelist, version, gcc_type, is_cross, exe_wrap, defines):
  76. CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
  77. GnuCompiler.__init__(self, gcc_type, defines)
  78. default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
  79. self.warn_args = {'1': default_warn_args,
  80. '2': default_warn_args + ['-Wextra'],
  81. '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  82. def get_options(self):
  83. opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
  84. ['none', 'c++03', 'c++11', 'c++14', 'c++1z',
  85. 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++1z'],
  86. 'none'),
  87. 'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl',
  88. 'STL debug mode',
  89. False)}
  90. if self.gcc_type == GCC_MINGW:
  91. opts.update({
  92. 'cpp_winlibs': coredata.UserStringArrayOption('cpp_winlibs', 'Standard Win libraries to link against',
  93. gnu_winlibs), })
  94. return opts
  95. def get_option_compile_args(self, options):
  96. args = []
  97. std = options['cpp_std']
  98. if std.value != 'none':
  99. args.append('-std=' + std.value)
  100. if options['cpp_debugstl'].value:
  101. args.append('-D_GLIBCXX_DEBUG=1')
  102. return args
  103. def get_option_link_args(self, options):
  104. if self.gcc_type == GCC_MINGW:
  105. return options['cpp_winlibs'].value[:]
  106. return []
  107. class IntelCPPCompiler(IntelCompiler, CPPCompiler):
  108. def __init__(self, exelist, version, icc_type, is_cross, exe_wrap):
  109. CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
  110. IntelCompiler.__init__(self, icc_type)
  111. self.lang_header = 'c++-header'
  112. default_warn_args = ['-Wall', '-w3', '-diag-disable:remark',
  113. '-Wpch-messages', '-Wnon-virtual-dtor']
  114. self.warn_args = {'1': default_warn_args,
  115. '2': default_warn_args + ['-Wextra'],
  116. '3': default_warn_args + ['-Wextra', '-Wpedantic']}
  117. def get_options(self):
  118. c_stds = []
  119. g_stds = ['gnu++98']
  120. if version_compare(self.version, '>=15.0.0'):
  121. c_stds += ['c++11', 'c++14']
  122. g_stds += ['gnu++11']
  123. if version_compare(self.version, '>=16.0.0'):
  124. c_stds += ['c++17']
  125. if version_compare(self.version, '>=17.0.0'):
  126. g_stds += ['gnu++14']
  127. opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
  128. ['none'] + c_stds + g_stds,
  129. 'none'),
  130. 'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl',
  131. 'STL debug mode',
  132. False)}
  133. return opts
  134. def get_option_compile_args(self, options):
  135. args = []
  136. std = options['cpp_std']
  137. if std.value != 'none':
  138. args.append('-std=' + std.value)
  139. if options['cpp_debugstl'].value:
  140. args.append('-D_GLIBCXX_DEBUG=1')
  141. return args
  142. def get_option_link_args(self, options):
  143. return []
  144. def has_multi_arguments(self, args, env):
  145. return super().has_multi_arguments(args + ['-diag-error', '10006'], env)
  146. class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
  147. def __init__(self, exelist, version, is_cross, exe_wrap, is_64):
  148. self.language = 'cpp'
  149. CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
  150. VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap, is_64)
  151. self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
  152. def get_options(self):
  153. return {'cpp_eh': coredata.UserComboOption('cpp_eh',
  154. 'C++ exception handling type.',
  155. ['none', 'a', 's', 'sc'],
  156. 'sc'),
  157. 'cpp_winlibs': coredata.UserStringArrayOption('cpp_winlibs',
  158. 'Windows libs to link against.',
  159. msvc_winlibs)
  160. }
  161. def get_option_compile_args(self, options):
  162. args = []
  163. std = options['cpp_eh']
  164. if std.value != 'none':
  165. args.append('/EH' + std.value)
  166. return args
  167. def get_option_link_args(self, options):
  168. return options['cpp_winlibs'].value[:]
  169. def get_compiler_check_args(self):
  170. # Visual Studio C++ compiler doesn't support -fpermissive,
  171. # so just use the plain C args.
  172. return super(VisualStudioCCompiler, self).get_compiler_check_args()