102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# The macro choose_msvc_crt() takes a list of possible 202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# C runtimes to choose from, in the form of compiler flags, 302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# to present to the user. (MTd for /MTd, etc) 402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# 502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# The macro is invoked at the end of the file. 602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# 702a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# CMake already sets CRT flags in the CMAKE_CXX_FLAGS_* and 802a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# CMAKE_C_FLAGS_* variables by default. To let the user 902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# override that for each build type: 1002a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# 1. Detect which CRT is already selected, and reflect this in 1102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# LLVM_USE_CRT_* so the user can have a better idea of what 1202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# changes they're making. 1302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# 2. Replace the flags in both variables with the new flag via a regex. 1402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# 3. set() the variables back into the cache so the changes 1502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# are user-visible. 1602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 1702a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes### Helper macros: ### 1802a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesmacro(make_crt_regex regex crts) 1902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes set(${regex} "") 2002a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes foreach(crt ${${crts}}) 2102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes # Trying to match the beginning or end of the string with stuff 2202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes # like [ ^]+ didn't work, so use a bunch of parentheses instead. 2302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes set(${regex} "${${regex}}|(^| +)/${crt}($| +)") 2402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes endforeach(crt) 2502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes string(REGEX REPLACE "^\\|" "" ${regex} "${${regex}}") 2602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesendmacro(make_crt_regex) 2702a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 2802a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesmacro(get_current_crt crt_current regex flagsvar) 2902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes # Find the selected-by-CMake CRT for each build type, if any. 3002a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes # Strip off the leading slash and any whitespace. 3102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes string(REGEX MATCH "${${regex}}" ${crt_current} "${${flagsvar}}") 3202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes string(REPLACE "/" " " ${crt_current} "${${crt_current}}") 3302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes string(STRIP "${${crt_current}}" ${crt_current}) 3402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesendmacro(get_current_crt) 3502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 3602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# Replaces or adds a flag to a variable. 3702a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# Expects 'flag' to be padded with spaces. 3802a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesmacro(set_flag_in_var flagsvar regex flag) 3902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes string(REGEX MATCH "${${regex}}" current_flag "${${flagsvar}}") 4002a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes if("${current_flag}" STREQUAL "") 4102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes set(${flagsvar} "${${flagsvar}}${${flag}}") 4202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes else() 4302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes string(REGEX REPLACE "${${regex}}" "${${flag}}" ${flagsvar} "${${flagsvar}}") 4402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes endif() 4502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes string(STRIP "${${flagsvar}}" ${flagsvar}) 4602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes # Make sure this change gets reflected in the cache/gui. 4702a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes # CMake requires the docstring parameter whenever set() touches the cache, 4802a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes # so get the existing docstring and re-use that. 4902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes get_property(flagsvar_docs CACHE ${flagsvar} PROPERTY HELPSTRING) 5002a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes set(${flagsvar} "${${flagsvar}}" CACHE STRING "${flagsvar_docs}" FORCE) 5102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesendmacro(set_flag_in_var) 5202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 5302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 5402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesmacro(choose_msvc_crt MSVC_CRT) 5502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes if(LLVM_USE_CRT) 5602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes message(FATAL_ERROR 5702a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes "LLVM_USE_CRT is deprecated. Use the CMAKE_BUILD_TYPE-specific 5802a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesvariables (LLVM_USE_CRT_DEBUG, etc) instead.") 5902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes endif() 6002a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 6102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes make_crt_regex(MSVC_CRT_REGEX ${MSVC_CRT}) 6202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 632b379460510523e0a05b3558523dcc50e976b916NAKAMURA Takumi foreach(build_type ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE}) 6402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes string(TOUPPER "${build_type}" build) 6502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes if (NOT LLVM_USE_CRT_${build}) 6602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes get_current_crt(LLVM_USE_CRT_${build} 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MSVC_CRT_REGEX 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CMAKE_CXX_FLAGS_${build}) 6902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes set(LLVM_USE_CRT_${build} 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "${LLVM_USE_CRT_${build}}" 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CACHE STRING "Specify VC++ CRT to use for ${build_type} configurations." 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FORCE) 7302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes set_property(CACHE LLVM_USE_CRT_${build} 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PROPERTY STRINGS ;${${MSVC_CRT}}) 7502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes endif(NOT LLVM_USE_CRT_${build}) 7602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes endforeach(build_type) 7702a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 782b379460510523e0a05b3558523dcc50e976b916NAKAMURA Takumi foreach(build_type ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE}) 7902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes string(TOUPPER "${build_type}" build) 8002a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes if ("${LLVM_USE_CRT_${build}}" STREQUAL "") 8102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes set(flag_string " ") 8202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes else() 8302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes set(flag_string " /${LLVM_USE_CRT_${build}} ") 8402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes list(FIND ${MSVC_CRT} ${LLVM_USE_CRT_${build}} idx) 8502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes if (idx LESS 0) 8602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes message(FATAL_ERROR 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Invalid value for LLVM_USE_CRT_${build}: ${LLVM_USE_CRT_${build}}. Valid options are one of: ${${MSVC_CRT}}") 8802a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes endif (idx LESS 0) 8902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes message(STATUS "Using ${build_type} VC++ CRT: ${LLVM_USE_CRT_${build}}") 9002a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes endif() 9102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes foreach(lang C CXX) 9202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes set_flag_in_var(CMAKE_${lang}_FLAGS_${build} MSVC_CRT_REGEX flag_string) 9302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes endforeach(lang) 9402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes endforeach(build_type) 9502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesendmacro(choose_msvc_crt MSVC_CRT) 9602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 9702a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 9802a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes# List of valid CRTs for MSVC 9902a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentesset(MSVC_CRT 10002a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes MD 10102a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes MDd 10202a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes MT 10302a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes MTd) 10402a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 10502a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuenteschoose_msvc_crt(MSVC_CRT) 10602a8f76d58cbc44fbcd55f29d2eccbfac49df794Oscar Fuentes 107