1from conans.client.tools.apple import to_apple_arch 2from conans.model.version import Version 3 4 5def architecture_flag(settings): 6 """ 7 returns flags specific to the target architecture and compiler 8 """ 9 compiler = settings.get_safe("compiler") 10 compiler_base = settings.get_safe("compiler.base") 11 arch = settings.get_safe("arch") 12 the_os = settings.get_safe("os") 13 subsystem = settings.get_safe("os.subsystem") 14 if not compiler or not arch: 15 return "" 16 17 if the_os == "Android": 18 return "" 19 20 if str(compiler) in ['gcc', 'apple-clang', 'clang', 'sun-cc']: 21 if str(the_os) == 'Macos' and str(subsystem) == 'catalyst': 22 # FIXME: This might be conflicting with Autotools --target cli arg 23 apple_arch = to_apple_arch(arch) 24 if apple_arch: 25 return '--target=%s-apple-ios-macabi' % apple_arch 26 elif str(arch) in ['x86_64', 'sparcv9', 's390x']: 27 return '-m64' 28 elif str(arch) in ['x86', 'sparc']: 29 return '-m32' 30 elif str(arch) in ['s390']: 31 return '-m31' 32 elif str(the_os) == 'AIX': 33 if str(arch) in ['ppc32']: 34 return '-maix32' 35 elif str(arch) in ['ppc64']: 36 return '-maix64' 37 elif str(compiler) == "intel": 38 # https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-m32-m64-qm32-qm64 39 if str(arch) == "x86": 40 return "/Qm32" if str(compiler_base) == "Visual Studio" else "-m32" 41 elif str(arch) == "x86_64": 42 return "/Qm64" if str(compiler_base) == "Visual Studio" else "-m64" 43 elif str(compiler) == "intel-cc": 44 # https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-m32-m64-qm32-qm64 45 if str(arch) == "x86": 46 return "/Qm32" if the_os == "Windows" else "-m32" 47 elif str(arch) == "x86_64": 48 return "/Qm64" if the_os == "Windows" else "-m64" 49 elif str(compiler) == "mcst-lcc": 50 return {"e2k-v2": "-march=elbrus-v2", 51 "e2k-v3": "-march=elbrus-v3", 52 "e2k-v4": "-march=elbrus-v4", 53 "e2k-v5": "-march=elbrus-v5", 54 "e2k-v6": "-march=elbrus-v6", 55 "e2k-v7": "-march=elbrus-v7"}.get(str(arch), "") 56 return "" 57 58 59def build_type_flags(settings): 60 """ 61 returns flags specific to the build type (Debug, Release, etc.) 62 (-s, -g, /Zi, etc.) 63 """ 64 compiler = settings.get_safe("compiler.base") or settings.get_safe("compiler") 65 build_type = settings.get_safe("build_type") 66 vs_toolset = settings.get_safe("compiler.toolset") 67 if not compiler or not build_type: 68 return "" 69 70 # https://github.com/Kitware/CMake/blob/d7af8a34b67026feaee558433db3a835d6007e06/ 71 # Modules/Platform/Windows-MSVC.cmake 72 if str(compiler) in ['Visual Studio', 'msvc']: 73 if vs_toolset and "clang" in str(vs_toolset): 74 flags = {"Debug": ["-gline-tables-only", "-fno-inline", "-O0"], 75 "Release": ["-O2"], 76 "RelWithDebInfo": ["-gline-tables-only", "-O2", "-fno-inline"], 77 "MinSizeRel": [] 78 }.get(build_type, ["-O2", "-Ob2"]) 79 else: 80 flags = {"Debug": ["-Zi", "-Ob0", "-Od"], 81 "Release": ["-O2", "-Ob2"], 82 "RelWithDebInfo": ["-Zi", "-O2", "-Ob1"], 83 "MinSizeRel": ["-O1", "-Ob1"], 84 }.get(build_type, []) 85 return flags 86 else: 87 # https://github.com/Kitware/CMake/blob/f3bbb37b253a1f4a26809d6f132b3996aa2e16fc/ 88 # Modules/Compiler/GNU.cmake 89 # clang include the gnu (overriding some things, but not build type) and apple clang 90 # overrides clang but it doesn't touch clang either 91 if str(compiler) in ["clang", "gcc", "apple-clang", "qcc", "mcst-lcc"]: 92 # FIXME: It is not clear that the "-s" is something related with the build type 93 # cmake is not adjusting it 94 # -s: Remove all symbol table and relocation information from the executable. 95 flags = {"Debug": ["-g"], 96 "Release": ["-O3", "-s"] if str(compiler) == "gcc" else ["-O3"], 97 "RelWithDebInfo": ["-O2", "-g"], 98 "MinSizeRel": ["-Os"], 99 }.get(build_type, []) 100 return flags 101 elif str(compiler) == "sun-cc": 102 # https://github.com/Kitware/CMake/blob/f3bbb37b253a1f4a26809d6f132b3996aa2e16fc/ 103 # Modules/Compiler/SunPro-CXX.cmake 104 flags = {"Debug": ["-g"], 105 "Release": ["-xO3"], 106 "RelWithDebInfo": ["-xO2", "-g"], 107 "MinSizeRel": ["-xO2", "-xspace"], 108 }.get(build_type, []) 109 return flags 110 return "" 111 112 113def use_win_mingw(conanfile): 114 if hasattr(conanfile, 'settings_build'): 115 os_build = conanfile.settings_build.get_safe('os') 116 else: 117 os_build = conanfile.settings.get_safe('os_build') 118 if os_build is None: # Assume is the same specified in host settings, not cross-building 119 os_build = conanfile.settings.get_safe("os") 120 121 if os_build == "Windows": 122 compiler = conanfile.settings.get_safe("compiler") 123 sub = conanfile.settings.get_safe("os.subsystem") 124 if sub in ("cygwin", "msys2", "msys") or compiler == "qcc": 125 return False 126 else: 127 return True 128 return False 129 130 131def cppstd_flag(settings): 132 compiler = settings.get_safe("compiler") 133 compiler_version = settings.get_safe("compiler.version") 134 compiler_base = settings.get_safe("compiler.base") 135 cppstd = settings.get_safe("compiler.cppstd") 136 137 if not compiler or not compiler_version or not cppstd: 138 return "" 139 140 cppstd_intel = _cppstd_intel_visualstudio if compiler_base == "Visual Studio" else \ 141 _cppstd_intel_gcc 142 func = {"gcc": _cppstd_gcc, 143 "clang": _cppstd_clang, 144 "apple-clang": _cppstd_apple_clang, 145 "Visual Studio": _cppstd_visualstudio, 146 "msvc": _cppstd_msvc, 147 "intel": cppstd_intel, 148 "intel-cc": _cppstd_intel_cc, 149 "mcst-lcc": _cppstd_mcst_lcc}.get(str(compiler), None) 150 flag = None 151 if func: 152 flag = func(str(compiler_version), str(cppstd)) 153 return flag 154 155 156def _cppstd_visualstudio(visual_version, cppstd): 157 # https://docs.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version 158 v14 = None 159 v17 = None 160 v20 = None 161 v23 = None 162 163 if Version(visual_version) >= "14": 164 v14 = "c++14" 165 v17 = "c++latest" 166 if Version(visual_version) >= "15": 167 v17 = "c++17" 168 v20 = "c++latest" 169 if Version(visual_version) >= "17": 170 v20 = "c++20" 171 v23 = "c++latest" 172 173 flag = {"14": v14, "17": v17, "20": v20, "23": v23}.get(str(cppstd), None) 174 return "/std:%s" % flag if flag else None 175 176 177def _cppstd_msvc(visual_version, cppstd): 178 # https://docs.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version 179 v14 = None 180 v17 = None 181 v20 = None 182 v23 = None 183 184 if Version(visual_version) >= "190": 185 v14 = "c++14" 186 v17 = "c++latest" 187 if Version(visual_version) >= "191": 188 v17 = "c++17" 189 v20 = "c++latest" 190 if Version(visual_version) >= "193": 191 v20 = "c++20" 192 v23 = "c++latest" 193 194 flag = {"14": v14, "17": v17, "20": v20, "23": v23}.get(str(cppstd), None) 195 return "/std:%s" % flag if flag else None 196 197 198def _cppstd_apple_clang(clang_version, cppstd): 199 """ 200 Inspired in: 201 https://github.com/Kitware/CMake/blob/master/Modules/Compiler/AppleClang-CXX.cmake 202 """ 203 204 v98 = vgnu98 = v11 = vgnu11 = v14 = vgnu14 = v17 = vgnu17 = v20 = vgnu20 = None 205 206 if Version(clang_version) >= "4.0": 207 v98 = "c++98" 208 vgnu98 = "gnu++98" 209 v11 = "c++11" 210 vgnu11 = "gnu++11" 211 212 if Version(clang_version) >= "6.1": 213 v14 = "c++14" 214 vgnu14 = "gnu++14" 215 elif Version(clang_version) >= "5.1": 216 v14 = "c++1y" 217 vgnu14 = "gnu++1y" 218 219 if Version(clang_version) >= "6.1": 220 v17 = "c++1z" 221 vgnu17 = "gnu++1z" 222 223 if Version(clang_version) >= "9.1": 224 # Not confirmed that it didn't work before 9.1 but 1z is still valid, so we are ok 225 v17 = "c++17" 226 vgnu17 = "gnu++17" 227 228 if Version(clang_version) >= "10.0": 229 v20 = "c++2a" 230 vgnu20 = "gnu++2a" 231 232 flag = {"98": v98, "gnu98": vgnu98, 233 "11": v11, "gnu11": vgnu11, 234 "14": v14, "gnu14": vgnu14, 235 "17": v17, "gnu17": vgnu17, 236 "20": v20, "gnu20": vgnu20}.get(cppstd, None) 237 238 return "-std=%s" % flag if flag else None 239 240 241def _cppstd_clang(clang_version, cppstd): 242 """ 243 Inspired in: 244 https://github.com/Kitware/CMake/blob/ 245 1fe2dc5ef2a1f262b125a2ba6a85f624ce150dd2/Modules/Compiler/Clang-CXX.cmake 246 247 https://clang.llvm.org/cxx_status.html 248 """ 249 v98 = vgnu98 = v11 = vgnu11 = v14 = vgnu14 = v17 = vgnu17 = v20 = vgnu20 = v23 = vgnu23 = None 250 251 if Version(clang_version) >= "2.1": 252 v98 = "c++98" 253 vgnu98 = "gnu++98" 254 255 if Version(clang_version) >= "3.1": 256 v11 = "c++11" 257 vgnu11 = "gnu++11" 258 elif Version(clang_version) >= "2.1": 259 v11 = "c++0x" 260 vgnu11 = "gnu++0x" 261 262 if Version(clang_version) >= "3.5": 263 v14 = "c++14" 264 vgnu14 = "gnu++14" 265 elif Version(clang_version) >= "3.4": 266 v14 = "c++1y" 267 vgnu14 = "gnu++1y" 268 269 if Version(clang_version) >= "5": 270 v17 = "c++17" 271 vgnu17 = "gnu++17" 272 elif Version(clang_version) >= "3.5": 273 v17 = "c++1z" 274 vgnu17 = "gnu++1z" 275 276 if Version(clang_version) >= "6": 277 v20 = "c++2a" 278 vgnu20 = "gnu++2a" 279 280 if Version(clang_version) >= "12": 281 v20 = "c++20" 282 vgnu20 = "gnu++20" 283 284 v23 = "c++2b" 285 vgnu23 = "gnu++2b" 286 287 flag = {"98": v98, "gnu98": vgnu98, 288 "11": v11, "gnu11": vgnu11, 289 "14": v14, "gnu14": vgnu14, 290 "17": v17, "gnu17": vgnu17, 291 "20": v20, "gnu20": vgnu20, 292 "23": v23, "gnu23": vgnu23}.get(cppstd, None) 293 return "-std=%s" % flag if flag else None 294 295 296def _cppstd_gcc(gcc_version, cppstd): 297 """https://github.com/Kitware/CMake/blob/master/Modules/Compiler/GNU-CXX.cmake""" 298 # https://gcc.gnu.org/projects/cxx-status.html 299 v98 = vgnu98 = v11 = vgnu11 = v14 = vgnu14 = v17 = vgnu17 = v20 = vgnu20 = v23 = vgnu23 = None 300 301 if Version(gcc_version) >= "3.4": 302 v98 = "c++98" 303 vgnu98 = "gnu++98" 304 305 if Version(gcc_version) >= "4.7": 306 v11 = "c++11" 307 vgnu11 = "gnu++11" 308 elif Version(gcc_version) >= "4.3": 309 v11 = "c++0x" 310 vgnu11 = "gnu++0x" 311 312 if Version(gcc_version) >= "4.9": 313 v14 = "c++14" 314 vgnu14 = "gnu++14" 315 elif Version(gcc_version) >= "4.8": 316 v14 = "c++1y" 317 vgnu14 = "gnu++1y" 318 319 if Version(gcc_version) >= "5": 320 v17 = "c++1z" 321 vgnu17 = "gnu++1z" 322 323 if Version(gcc_version) >= "5.2": # Not sure if even in 5.1 gnu17 is valid, but gnu1z is 324 v17 = "c++17" 325 vgnu17 = "gnu++17" 326 327 if Version(gcc_version) >= "8": 328 v20 = "c++2a" 329 vgnu20 = "gnu++2a" 330 331 if Version(gcc_version) >= "11": 332 v23 = "c++2b" 333 vgnu23 = "gnu++2b" 334 335 flag = {"98": v98, "gnu98": vgnu98, 336 "11": v11, "gnu11": vgnu11, 337 "14": v14, "gnu14": vgnu14, 338 "17": v17, "gnu17": vgnu17, 339 "20": v20, "gnu20": vgnu20, 340 "23": v23, "gnu23": vgnu23}.get(cppstd) 341 return "-std=%s" % flag if flag else None 342 343 344def _cppstd_intel_common(intel_version, cppstd, vgnu98, vgnu0x): 345 # https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-std-qstd 346 # https://software.intel.com/en-us/articles/intel-cpp-compiler-release-notes 347 # NOTE: there are only gnu++98 and gnu++0x, and only for Linux/macOS 348 v98 = v11 = v14 = v17 = v20 = None 349 vgnu11 = vgnu14 = vgnu17 = vgnu20 = None 350 351 if Version(intel_version) >= "12": 352 v11 = "c++0x" 353 vgnu11 = vgnu0x 354 if Version(intel_version) >= "14": 355 v11 = "c++11" 356 vgnu11 = vgnu0x 357 if Version(intel_version) >= "16": 358 v14 = "c++14" 359 if Version(intel_version) >= "18": 360 v17 = "c++17" 361 if Version(intel_version) >= "19.1": 362 v20 = "c++20" 363 364 return {"98": v98, "gnu98": vgnu98, 365 "11": v11, "gnu11": vgnu11, 366 "14": v14, "gnu14": vgnu14, 367 "17": v17, "gnu17": vgnu17, 368 "20": v20, "gnu20": vgnu20}.get(cppstd) 369 370 371def _cppstd_intel_gcc(intel_version, cppstd): 372 flag = _cppstd_intel_common(intel_version, cppstd, "gnu++98", "gnu++0x") 373 return "-std=%s" % flag if flag else None 374 375 376def _cppstd_intel_visualstudio(intel_version, cppstd): 377 flag = _cppstd_intel_common(intel_version, cppstd, None, None) 378 return "/Qstd=%s" % flag if flag else None 379 380 381def _cppstd_mcst_lcc(mcst_lcc_version, cppstd): 382 v11 = vgnu11 = v14 = vgnu14 = v17 = vgnu17 = v20 = vgnu20 = None 383 384 if Version(mcst_lcc_version) >= "1.21": 385 v11 = "c++11" 386 vgnu11 = "gnu++11" 387 v14 = "c++14" 388 vgnu14 = "gnu++14" 389 390 if Version(mcst_lcc_version) >= "1.24": 391 v17 = "c++17" 392 vgnu17 = "gnu++17" 393 394 if Version(mcst_lcc_version) >= "1.25": 395 v20 = "c++2a" 396 vgnu20 = "gnu++2a" 397 398 flag = {"98": "c++98", "gnu98": "gnu++98", 399 "03": "c++03", "gnu03": "gnu++03", 400 "11": v11, "gnu11": vgnu11, 401 "14": v14, "gnu14": vgnu14, 402 "17": v17, "gnu17": vgnu17, 403 "20": v20, "gnu20": vgnu20}.get(cppstd) 404 return "-std=%s" % flag if flag else None 405 406 407def _cppstd_intel_cc(_, cppstd): 408 """ 409 Inspired in: 410 https://software.intel.com/content/www/us/en/develop/documentation/ 411 oneapi-dpcpp-cpp-compiler-dev-guide-and-reference/top/compiler-reference/ 412 compiler-options/compiler-option-details/language-options/std-qstd.html 413 """ 414 # Note: for now, we don't care about compiler version 415 v98 = "c++98" 416 vgnu98 = "gnu++98" 417 v03 = "c++03" 418 vgnu03 = "gnu++03" 419 v11 = "c++11" 420 vgnu11 = "gnu++11" 421 v14 = "c++14" 422 vgnu14 = "gnu++14" 423 v17 = "c++17" 424 vgnu17 = "gnu++17" 425 v20 = "c++20" 426 vgnu20 = "gnu++20" 427 v23 = "c++2b" 428 vgnu23 = "gnu++2b" 429 430 flag = {"98": v98, "gnu98": vgnu98, 431 "03": v03, "gnu03": vgnu03, 432 "11": v11, "gnu11": vgnu11, 433 "14": v14, "gnu14": vgnu14, 434 "17": v17, "gnu17": vgnu17, 435 "20": v20, "gnu20": vgnu20, 436 "23": v23, "gnu23": vgnu23}.get(cppstd, None) 437 return "-std=%s" % flag if flag else None 438