1# The MIT License (MIT) 2 3# Copyright (c) 2018 JFrog 4 5# Permission is hereby granted, free of charge, to any person obtaining a copy 6# of this software and associated documentation files (the "Software"), to deal 7# in the Software without restriction, including without limitation the rights 8# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9# copies of the Software, and to permit persons to whom the Software is 10# furnished to do so, subject to the following conditions: 11 12# The above copyright notice and this permission notice shall be included in all 13# copies or substantial portions of the Software. 14 15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21# SOFTWARE. 22 23 24 25# This file comes from: https://github.com/conan-io/cmake-conan. Please refer 26# to this repository for issues and documentation. 27 28# Its purpose is to wrap and launch Conan C/C++ Package Manager when cmake is called. 29# It will take CMake current settings (os, compiler, compiler version, architecture) 30# and translate them to conan settings for installing and retrieving dependencies. 31 32# It is intended to facilitate developers building projects that have conan dependencies, 33# but it is only necessary on the end-user side. It is not necessary to create conan 34# packages, in fact it shouldn't be use for that. Check the project documentation. 35 36 37include(CMakeParseArguments) 38 39function(_get_msvc_ide_version result) 40 set(${result} "" PARENT_SCOPE) 41 if(NOT MSVC_VERSION VERSION_LESS 1400 AND MSVC_VERSION VERSION_LESS 1500) 42 set(${result} 8 PARENT_SCOPE) 43 elseif(NOT MSVC_VERSION VERSION_LESS 1500 AND MSVC_VERSION VERSION_LESS 1600) 44 set(${result} 9 PARENT_SCOPE) 45 elseif(NOT MSVC_VERSION VERSION_LESS 1600 AND MSVC_VERSION VERSION_LESS 1700) 46 set(${result} 10 PARENT_SCOPE) 47 elseif(NOT MSVC_VERSION VERSION_LESS 1700 AND MSVC_VERSION VERSION_LESS 1800) 48 set(${result} 11 PARENT_SCOPE) 49 elseif(NOT MSVC_VERSION VERSION_LESS 1800 AND MSVC_VERSION VERSION_LESS 1900) 50 set(${result} 12 PARENT_SCOPE) 51 elseif(NOT MSVC_VERSION VERSION_LESS 1900 AND MSVC_VERSION VERSION_LESS 1910) 52 set(${result} 14 PARENT_SCOPE) 53 elseif(NOT MSVC_VERSION VERSION_LESS 1910 AND MSVC_VERSION VERSION_LESS 1920) 54 set(${result} 15 PARENT_SCOPE) 55 else() 56 message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") 57 endif() 58endfunction() 59 60function(conan_cmake_settings result) 61 message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER}) 62 message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER_ID}) 63 message(STATUS "VERSION " ${CMAKE_CXX_COMPILER_VERSION}) 64 message(STATUS "FLAGS " ${CMAKE_LANG_FLAGS}) 65 message(STATUS "LIB ARCH " ${CMAKE_CXX_LIBRARY_ARCHITECTURE}) 66 message(STATUS "BUILD TYPE " ${CMAKE_BUILD_TYPE}) 67 message(STATUS "GENERATOR " ${CMAKE_GENERATOR}) 68 message(STATUS "GENERATOR WIN64 " ${CMAKE_CL_64}) 69 70 message(STATUS "Conan ** WARNING** : This detection of settings from cmake is experimental and incomplete. " 71 "Please check 'conan.cmake' and contribute") 72 73 parse_arguments(${ARGV}) 74 set(arch ${ARGUMENTS_ARCH}) 75 76 if(CONAN_CMAKE_MULTI) 77 set(_SETTINGS -g cmake_multi) 78 else() 79 set(_SETTINGS -g cmake) 80 endif() 81 if(ARGUMENTS_BUILD_TYPE) 82 set(_SETTINGS ${_SETTINGS} -s build_type=${ARGUMENTS_BUILD_TYPE}) 83 elseif(CMAKE_BUILD_TYPE) 84 set(_SETTINGS ${_SETTINGS} -s build_type=${CMAKE_BUILD_TYPE}) 85 else() 86 message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") 87 endif() 88 89 #handle -s os setting 90 if(CMAKE_SYSTEM_NAME) 91 #use default conan os setting if CMAKE_SYSTEM_NAME is not defined 92 set(CONAN_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}) 93 if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") 94 set(CONAN_SYSTEM_NAME Macos) 95 endif() 96 set(CONAN_SUPPORTED_PLATFORMS Windows Linux Macos Android iOS FreeBSD) 97 list (FIND CONAN_SUPPORTED_PLATFORMS "${CONAN_SYSTEM_NAME}" _index) 98 if (${_index} GREATER -1) 99 #check if the cmake system is a conan supported one 100 set(_SETTINGS ${_SETTINGS} -s os=${CONAN_SYSTEM_NAME}) 101 else() 102 message(FATAL_ERROR "cmake system ${CONAN_SYSTEM_NAME} is not supported by conan. Use one of ${CONAN_SUPPORTED_PLATFORMS}") 103 endif() 104 endif() 105 106 get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) 107 if (";${_languages};" MATCHES ";CXX;") 108 set(LANGUAGE CXX) 109 set(USING_CXX 1) 110 elseif (";${_languages};" MATCHES ";C;") 111 set(LANGUAGE C) 112 set(USING_CXX 0) 113 else () 114 message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.") 115 endif() 116 117 if(arch) 118 set(_SETTINGS ${_SETTINGS} -s arch=${arch}) 119 endif() 120 121 if (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL GNU) 122 # using GCC 123 # TODO: Handle other params 124 string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) 125 list(GET VERSION_LIST 0 MAJOR) 126 list(GET VERSION_LIST 1 MINOR) 127 set(COMPILER_VERSION ${MAJOR}.${MINOR}) 128 if(${MAJOR} GREATER 4) 129 set(COMPILER_VERSION ${MAJOR}) 130 endif() 131 set(_SETTINGS ${_SETTINGS} -s compiler=gcc -s compiler.version=${COMPILER_VERSION}) 132 if (USING_CXX) 133 conan_cmake_detect_gnu_libcxx(_LIBCXX) 134 set(_SETTINGS ${_SETTINGS} -s compiler.libcxx=${_LIBCXX}) 135 endif () 136 elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL AppleClang) 137 # using AppleClang 138 string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) 139 list(GET VERSION_LIST 0 MAJOR) 140 list(GET VERSION_LIST 1 MINOR) 141 set(_SETTINGS ${_SETTINGS} -s compiler=apple-clang -s compiler.version=${MAJOR}.${MINOR}) 142 if (USING_CXX) 143 set(_SETTINGS ${_SETTINGS} -s compiler.libcxx=libc++) 144 endif () 145 elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang) 146 string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) 147 list(GET VERSION_LIST 0 MAJOR) 148 list(GET VERSION_LIST 1 MINOR) 149 if(APPLE) 150 cmake_policy(GET CMP0025 APPLE_CLANG_POLICY_ENABLED) 151 if(NOT APPLE_CLANG_POLICY_ENABLED) 152 message(STATUS "Conan: APPLE and Clang detected. Assuming apple-clang compiler. Set CMP0025 to avoid it") 153 set(_SETTINGS ${_SETTINGS} -s compiler=apple-clang -s compiler.version=${MAJOR}.${MINOR}) 154 else() 155 set(_SETTINGS ${_SETTINGS} -s compiler=clang -s compiler.version=${MAJOR}.${MINOR}) 156 endif() 157 if (USING_CXX) 158 set(_SETTINGS ${_SETTINGS} -s compiler.libcxx=libc++) 159 endif () 160 else() 161 set(_SETTINGS ${_SETTINGS} -s compiler=clang -s compiler.version=${MAJOR}.${MINOR}) 162 if (USING_CXX) 163 conan_cmake_detect_gnu_libcxx(_LIBCXX) 164 set(_SETTINGS ${_SETTINGS} -s compiler.libcxx=${_LIBCXX}) 165 endif () 166 endif() 167 elseif(${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL MSVC) 168 set(_VISUAL "Visual Studio") 169 _get_msvc_ide_version(_VISUAL_VERSION) 170 if("${_VISUAL_VERSION}" STREQUAL "") 171 message(FATAL_ERROR "Conan: Visual Studio not recognized") 172 else() 173 set(_SETTINGS ${_SETTINGS} -s compiler=${_VISUAL} -s compiler.version=${_VISUAL_VERSION}) 174 endif() 175 176 if(NOT arch) 177 if (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "64") 178 set(_SETTINGS ${_SETTINGS} -s arch=x86_64) 179 elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "^ARM") 180 message(STATUS "Conan: Using default ARM architecture from MSVC") 181 set(_SETTINGS ${_SETTINGS} -s arch=armv6) 182 elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "86") 183 set(_SETTINGS ${_SETTINGS} -s arch=x86) 184 else () 185 message(FATAL_ERROR "Conan: Unknown MSVC architecture [${MSVC_${LANGUAGE}_ARCHITECTURE_ID}]") 186 endif() 187 endif() 188 189 conan_cmake_detect_vs_runtime(_vs_runtime) 190 message(STATUS "Detected VS runtime: ${_vs_runtime}") 191 set(_SETTINGS ${_SETTINGS} -s compiler.runtime=${_vs_runtime}) 192 193 if (CMAKE_GENERATOR_TOOLSET) 194 set(_SETTINGS ${_SETTINGS} -s compiler.toolset=${CMAKE_VS_PLATFORM_TOOLSET}) 195 elseif(CMAKE_VS_PLATFORM_TOOLSET AND (CMAKE_GENERATOR STREQUAL "Ninja")) 196 set(_SETTINGS ${_SETTINGS} -s compiler.toolset=${CMAKE_VS_PLATFORM_TOOLSET}) 197 endif() 198 # Temp fix due to https://github.com/conan-io/cmake-conan/issues/166 199 elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Intel) 200 string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) 201 list(GET VERSION_LIST 0 MAJOR) 202 list(GET VERSION_LIST 1 MINOR) 203 set(COMPILER_VERSION ${MAJOR}.${MINOR}) 204 set(_CONAN_SETTING_COMPILER icc) 205 set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION}) 206 set(_SETTINGS ${_SETTINGS} -s compiler=icc -s compiler.version=${COMPILER_VERSION}) 207 if (USING_CXX) 208 conan_cmake_detect_gnu_libcxx(_LIBCXX) 209 set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) 210 endif () 211 else() 212 message(FATAL_ERROR "Conan: compiler setup not recognized") 213 endif() 214 215 foreach(ARG ${ARGUMENTS_SETTINGS}) 216 set(_SETTINGS ${_SETTINGS} -s ${ARG}) 217 endforeach() 218 219 set(${result} ${_SETTINGS} PARENT_SCOPE) 220endfunction() 221 222 223function(conan_cmake_detect_gnu_libcxx result) 224 # Allow -D_GLIBCXX_USE_CXX11_ABI=ON/OFF as argument to cmake 225 if(DEFINED _GLIBCXX_USE_CXX11_ABI) 226 if(_GLIBCXX_USE_CXX11_ABI) 227 set(${result} libstdc++11 PARENT_SCOPE) 228 return() 229 else() 230 set(${result} libstdc++ PARENT_SCOPE) 231 return() 232 endif() 233 endif() 234 235 # Check if there's any add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) 236 get_directory_property(defines DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS) 237 foreach(define ${defines}) 238 if(define STREQUAL "_GLIBCXX_USE_CXX11_ABI=0") 239 set(${result} libstdc++ PARENT_SCOPE) 240 return() 241 endif() 242 endforeach() 243 244 # Use C++11 stdlib as default if gcc is 5.1+ 245 if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.1") 246 set(${result} libstdc++ PARENT_SCOPE) 247 else() 248 set(${result} libstdc++11 PARENT_SCOPE) 249 endif() 250endfunction() 251 252 253function(conan_cmake_detect_vs_runtime result) 254 string(TOUPPER ${CMAKE_BUILD_TYPE} build_type) 255 set(variables CMAKE_CXX_FLAGS_${build_type} CMAKE_C_FLAGS_${build_type} CMAKE_CXX_FLAGS CMAKE_C_FLAGS) 256 foreach(variable ${variables}) 257 string(REPLACE " " ";" flags ${${variable}}) 258 foreach (flag ${flags}) 259 if(${flag} STREQUAL "/MD" OR ${flag} STREQUAL "/MDd" OR ${flag} STREQUAL "/MT" OR ${flag} STREQUAL "/MTd") 260 string(SUBSTRING ${flag} 1 -1 runtime) 261 set(${result} ${runtime} PARENT_SCOPE) 262 return() 263 endif() 264 endforeach() 265 endforeach() 266 if(${build_type} STREQUAL "DEBUG") 267 set(${result} "MDd" PARENT_SCOPE) 268 else() 269 set(${result} "MD" PARENT_SCOPE) 270 endif() 271endfunction() 272 273 274macro(parse_arguments) 275 set(options BASIC_SETUP CMAKE_TARGETS UPDATE KEEP_RPATHS NO_OUTPUT_DIRS) 276 set(oneValueArgs CONANFILE DEBUG_PROFILE RELEASE_PROFILE RELWITHDEBINFO_PROFILE MINSIZEREL_PROFILE PROFILE ARCH BUILD_TYPE) 277 set(multiValueArgs REQUIRES OPTIONS IMPORTS SETTINGS BUILD CONAN_COMMAND) 278 cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) 279endmacro() 280 281function(conan_cmake_install) 282 # Calls "conan install" 283 # Argument BUILD is equivalant to --build={missing, PkgName,...} or 284 # --build when argument is 'BUILD all' (which builds all packages from source) 285 # Argument CONAN_COMMAND, to specify the conan path, e.g. in case of running from source 286 # cmake does not identify conan as command, even if it is +x and it is in the path 287 parse_arguments(${ARGV}) 288 289 set(CONAN_BUILD_POLICY "") 290 foreach(ARG ${ARGUMENTS_BUILD}) 291 if(${ARG} STREQUAL "all") 292 set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build) 293 break() 294 else() 295 set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build=${ARG}) 296 endif() 297 endforeach() 298 if(ARGUMENTS_CONAN_COMMAND) 299 set(conan_command ${ARGUMENTS_CONAN_COMMAND}) 300 else() 301 set(conan_command conan) 302 endif() 303 set(CONAN_OPTIONS "") 304 if(ARGUMENTS_CONANFILE) 305 set(CONANFILE ${CMAKE_CURRENT_SOURCE_DIR}/${ARGUMENTS_CONANFILE}) 306 # A conan file has been specified - apply specified options as well if provided 307 foreach(ARG ${ARGUMENTS_OPTIONS}) 308 set(CONAN_OPTIONS ${CONAN_OPTIONS} -o ${ARG}) 309 endforeach() 310 else() 311 set(CONANFILE ".") 312 endif() 313 if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE) 314 set(settings -pr ${ARGUMENTS_DEBUG_PROFILE}) 315 endif() 316 if(CMAKE_BUILD_TYPE STREQUAL "Release" AND ARGUMENTS_RELEASE_PROFILE) 317 set(settings -pr ${ARGUMENTS_RELEASE_PROFILE}) 318 endif() 319 if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" AND ARGUMENTS_RELWITHDEBINFO_PROFILE) 320 set(settings -pr ${ARGUMENTS_RELWITHDEBINFO_PROFILE}) 321 endif() 322 if(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" AND ARGUMENTS_MINSIZEREL_PROFILE) 323 set(settings -pr ${ARGUMENTS_MINSIZEREL_PROFILE}) 324 endif() 325 if(ARGUMENTS_PROFILE) 326 set(settings -pr ${ARGUMENTS_PROFILE}) 327 endif() 328 if(ARGUMENTS_UPDATE) 329 set(CONAN_INSTALL_UPDATE --update) 330 endif() 331 set(conan_args install ${CONANFILE} ${settings} ${CONAN_BUILD_POLICY} ${CONAN_INSTALL_UPDATE} ${CONAN_OPTIONS}) 332 333 string (REPLACE ";" " " _conan_args "${conan_args}") 334 message(STATUS "Conan executing: ${conan_command} ${_conan_args}") 335 336 execute_process(COMMAND ${conan_command} ${conan_args} 337 RESULT_VARIABLE return_code 338 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 339 340 if(NOT "${return_code}" STREQUAL "0") 341 message(FATAL_ERROR "Conan install failed='${return_code}'") 342 endif() 343 344endfunction() 345 346 347function(conan_cmake_setup_conanfile) 348 parse_arguments(${ARGV}) 349 if(ARGUMENTS_CONANFILE) 350 # configure_file will make sure cmake re-runs when conanfile is updated 351 configure_file(${ARGUMENTS_CONANFILE} ${ARGUMENTS_CONANFILE}.junk) 352 file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${ARGUMENTS_CONANFILE}.junk) 353 else() 354 conan_cmake_generate_conanfile(${ARGV}) 355 endif() 356endfunction() 357 358function(conan_cmake_generate_conanfile) 359 # Generate, writing in disk a conanfile.txt with the requires, options, and imports 360 # specified as arguments 361 # This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) 362 parse_arguments(${ARGV}) 363 set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") 364 365 file(WRITE ${_FN} "[generators]\ncmake\n\n[requires]\n") 366 foreach(ARG ${ARGUMENTS_REQUIRES}) 367 file(APPEND ${_FN} ${ARG} "\n") 368 endforeach() 369 370 file(APPEND ${_FN} ${ARG} "\n[options]\n") 371 foreach(ARG ${ARGUMENTS_OPTIONS}) 372 file(APPEND ${_FN} ${ARG} "\n") 373 endforeach() 374 375 file(APPEND ${_FN} ${ARG} "\n[imports]\n") 376 foreach(ARG ${ARGUMENTS_IMPORTS}) 377 file(APPEND ${_FN} ${ARG} "\n") 378 endforeach() 379endfunction() 380 381 382macro(conan_load_buildinfo) 383 if(CONAN_CMAKE_MULTI) 384 set(_CONANBUILDINFO conanbuildinfo_multi.cmake) 385 else() 386 set(_CONANBUILDINFO conanbuildinfo.cmake) 387 endif() 388 # Checks for the existence of conanbuildinfo.cmake, and loads it 389 # important that it is macro, so variables defined at parent scope 390 if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${_CONANBUILDINFO}") 391 message(STATUS "Conan: Loading ${_CONANBUILDINFO}") 392 include(${CMAKE_CURRENT_BINARY_DIR}/${_CONANBUILDINFO}) 393 else() 394 message(FATAL_ERROR "${_CONANBUILDINFO} doesn't exist in ${CMAKE_CURRENT_BINARY_DIR}") 395 endif() 396endmacro() 397 398 399macro(conan_cmake_run) 400 parse_arguments(${ARGV}) 401 402 if(CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE AND NOT CONAN_EXPORTED) 403 set(CONAN_CMAKE_MULTI ON) 404 message(STATUS "Conan: Using cmake-multi generator") 405 else() 406 set(CONAN_CMAKE_MULTI OFF) 407 endif() 408 if(NOT CONAN_EXPORTED) 409 conan_cmake_setup_conanfile(${ARGV}) 410 if(CONAN_CMAKE_MULTI) 411 foreach(CMAKE_BUILD_TYPE "Release" "Debug") 412 conan_cmake_settings(settings ${ARGV}) 413 conan_cmake_install(SETTINGS ${settings} ${ARGV}) 414 endforeach() 415 set(CMAKE_BUILD_TYPE) 416 else() 417 conan_cmake_settings(settings ${ARGV}) 418 conan_cmake_install(SETTINGS ${settings} ${ARGV}) 419 endif() 420 endif() 421 422 conan_load_buildinfo() 423 424 if(ARGUMENTS_BASIC_SETUP) 425 foreach(_option CMAKE_TARGETS KEEP_RPATHS NO_OUTPUT_DIRS) 426 if(ARGUMENTS_${_option}) 427 if(${_option} STREQUAL "CMAKE_TARGETS") 428 list(APPEND _setup_options "TARGETS") 429 else() 430 list(APPEND _setup_options ${_option}) 431 endif() 432 endif() 433 endforeach() 434 conan_basic_setup(${_setup_options}) 435 endif() 436endmacro() 437