1617a3babSopenharmony_ci# Copyright (C) 2020 The Khronos Group Inc. 2617a3babSopenharmony_ci# 3617a3babSopenharmony_ci# All rights reserved. 4617a3babSopenharmony_ci# 5617a3babSopenharmony_ci# Redistribution and use in source and binary forms, with or without 6617a3babSopenharmony_ci# modification, are permitted provided that the following conditions 7617a3babSopenharmony_ci# are met: 8617a3babSopenharmony_ci# 9617a3babSopenharmony_ci# Redistributions of source code must retain the above copyright 10617a3babSopenharmony_ci# notice, this list of conditions and the following disclaimer. 11617a3babSopenharmony_ci# 12617a3babSopenharmony_ci# Redistributions in binary form must reproduce the above 13617a3babSopenharmony_ci# copyright notice, this list of conditions and the following 14617a3babSopenharmony_ci# disclaimer in the documentation and/or other materials provided 15617a3babSopenharmony_ci# with the distribution. 16617a3babSopenharmony_ci# 17617a3babSopenharmony_ci# Neither the name of The Khronos Group Inc. nor the names of its 18617a3babSopenharmony_ci# contributors may be used to endorse or promote products derived 19617a3babSopenharmony_ci# from this software without specific prior written permission. 20617a3babSopenharmony_ci# 21617a3babSopenharmony_ci# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22617a3babSopenharmony_ci# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23617a3babSopenharmony_ci# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24617a3babSopenharmony_ci# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25617a3babSopenharmony_ci# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26617a3babSopenharmony_ci# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27617a3babSopenharmony_ci# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28617a3babSopenharmony_ci# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29617a3babSopenharmony_ci# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30617a3babSopenharmony_ci# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31617a3babSopenharmony_ci# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32617a3babSopenharmony_ci# POSSIBILITY OF SUCH DAMAGE. 33617a3babSopenharmony_ci 34617a3babSopenharmony_ci# The macro choose_msvc_crt() takes a list of possible 35617a3babSopenharmony_ci# C runtimes to choose from, in the form of compiler flags, 36617a3babSopenharmony_ci# to present to the user. (MTd for /MTd, etc) 37617a3babSopenharmony_ci# 38617a3babSopenharmony_ci# The macro is invoked at the end of the file. 39617a3babSopenharmony_ci# 40617a3babSopenharmony_ci# CMake already sets CRT flags in the CMAKE_CXX_FLAGS_* and 41617a3babSopenharmony_ci# CMAKE_C_FLAGS_* variables by default. To let the user 42617a3babSopenharmony_ci# override that for each build type: 43617a3babSopenharmony_ci# 1. Detect which CRT is already selected, and reflect this in 44617a3babSopenharmony_ci# LLVM_USE_CRT_* so the user can have a better idea of what 45617a3babSopenharmony_ci# changes they're making. 46617a3babSopenharmony_ci# 2. Replace the flags in both variables with the new flag via a regex. 47617a3babSopenharmony_ci# 3. set() the variables back into the cache so the changes 48617a3babSopenharmony_ci# are user-visible. 49617a3babSopenharmony_ci 50617a3babSopenharmony_ci### Helper macros: ### 51617a3babSopenharmony_cimacro(make_crt_regex regex crts) 52617a3babSopenharmony_ci set(${regex} "") 53617a3babSopenharmony_ci foreach(crt ${${crts}}) 54617a3babSopenharmony_ci # Trying to match the beginning or end of the string with stuff 55617a3babSopenharmony_ci # like [ ^]+ didn't work, so use a bunch of parentheses instead. 56617a3babSopenharmony_ci set(${regex} "${${regex}}|(^| +)/${crt}($| +)") 57617a3babSopenharmony_ci endforeach(crt) 58617a3babSopenharmony_ci string(REGEX REPLACE "^\\|" "" ${regex} "${${regex}}") 59617a3babSopenharmony_ciendmacro(make_crt_regex) 60617a3babSopenharmony_ci 61617a3babSopenharmony_cimacro(get_current_crt crt_current regex flagsvar) 62617a3babSopenharmony_ci # Find the selected-by-CMake CRT for each build type, if any. 63617a3babSopenharmony_ci # Strip off the leading slash and any whitespace. 64617a3babSopenharmony_ci string(REGEX MATCH "${${regex}}" ${crt_current} "${${flagsvar}}") 65617a3babSopenharmony_ci string(REPLACE "/" " " ${crt_current} "${${crt_current}}") 66617a3babSopenharmony_ci string(STRIP "${${crt_current}}" ${crt_current}) 67617a3babSopenharmony_ciendmacro(get_current_crt) 68617a3babSopenharmony_ci 69617a3babSopenharmony_ci# Replaces or adds a flag to a variable. 70617a3babSopenharmony_ci# Expects 'flag' to be padded with spaces. 71617a3babSopenharmony_cimacro(set_flag_in_var flagsvar regex flag) 72617a3babSopenharmony_ci string(REGEX MATCH "${${regex}}" current_flag "${${flagsvar}}") 73617a3babSopenharmony_ci if("${current_flag}" STREQUAL "") 74617a3babSopenharmony_ci set(${flagsvar} "${${flagsvar}}${${flag}}") 75617a3babSopenharmony_ci else() 76617a3babSopenharmony_ci string(REGEX REPLACE "${${regex}}" "${${flag}}" ${flagsvar} "${${flagsvar}}") 77617a3babSopenharmony_ci endif() 78617a3babSopenharmony_ci string(STRIP "${${flagsvar}}" ${flagsvar}) 79617a3babSopenharmony_ci # Make sure this change gets reflected in the cache/gui. 80617a3babSopenharmony_ci # CMake requires the docstring parameter whenever set() touches the cache, 81617a3babSopenharmony_ci # so get the existing docstring and re-use that. 82617a3babSopenharmony_ci get_property(flagsvar_docs CACHE ${flagsvar} PROPERTY HELPSTRING) 83617a3babSopenharmony_ci set(${flagsvar} "${${flagsvar}}" CACHE STRING "${flagsvar_docs}" FORCE) 84617a3babSopenharmony_ciendmacro(set_flag_in_var) 85617a3babSopenharmony_ci 86617a3babSopenharmony_ci 87617a3babSopenharmony_cimacro(choose_msvc_crt MSVC_CRT) 88617a3babSopenharmony_ci if(LLVM_USE_CRT) 89617a3babSopenharmony_ci message(FATAL_ERROR 90617a3babSopenharmony_ci "LLVM_USE_CRT is deprecated. Use the CMAKE_BUILD_TYPE-specific 91617a3babSopenharmony_civariables (LLVM_USE_CRT_DEBUG, etc) instead.") 92617a3babSopenharmony_ci endif() 93617a3babSopenharmony_ci 94617a3babSopenharmony_ci make_crt_regex(MSVC_CRT_REGEX ${MSVC_CRT}) 95617a3babSopenharmony_ci 96617a3babSopenharmony_ci foreach(build_type ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE}) 97617a3babSopenharmony_ci string(TOUPPER "${build_type}" build) 98617a3babSopenharmony_ci if (NOT LLVM_USE_CRT_${build}) 99617a3babSopenharmony_ci get_current_crt(LLVM_USE_CRT_${build} 100617a3babSopenharmony_ci MSVC_CRT_REGEX 101617a3babSopenharmony_ci CMAKE_CXX_FLAGS_${build}) 102617a3babSopenharmony_ci set(LLVM_USE_CRT_${build} 103617a3babSopenharmony_ci "${LLVM_USE_CRT_${build}}" 104617a3babSopenharmony_ci CACHE STRING "Specify VC++ CRT to use for ${build_type} configurations." 105617a3babSopenharmony_ci FORCE) 106617a3babSopenharmony_ci set_property(CACHE LLVM_USE_CRT_${build} 107617a3babSopenharmony_ci PROPERTY STRINGS ;${${MSVC_CRT}}) 108617a3babSopenharmony_ci endif(NOT LLVM_USE_CRT_${build}) 109617a3babSopenharmony_ci endforeach(build_type) 110617a3babSopenharmony_ci 111617a3babSopenharmony_ci foreach(build_type ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE}) 112617a3babSopenharmony_ci string(TOUPPER "${build_type}" build) 113617a3babSopenharmony_ci if ("${LLVM_USE_CRT_${build}}" STREQUAL "") 114617a3babSopenharmony_ci set(flag_string " ") 115617a3babSopenharmony_ci else() 116617a3babSopenharmony_ci set(flag_string " /${LLVM_USE_CRT_${build}} ") 117617a3babSopenharmony_ci list(FIND ${MSVC_CRT} ${LLVM_USE_CRT_${build}} idx) 118617a3babSopenharmony_ci if (idx LESS 0) 119617a3babSopenharmony_ci message(FATAL_ERROR 120617a3babSopenharmony_ci "Invalid value for LLVM_USE_CRT_${build}: ${LLVM_USE_CRT_${build}}. Valid options are one of: ${${MSVC_CRT}}") 121617a3babSopenharmony_ci endif (idx LESS 0) 122617a3babSopenharmony_ci message(STATUS "Using ${build_type} VC++ CRT: ${LLVM_USE_CRT_${build}}") 123617a3babSopenharmony_ci endif() 124617a3babSopenharmony_ci foreach(lang C CXX) 125617a3babSopenharmony_ci set_flag_in_var(CMAKE_${lang}_FLAGS_${build} MSVC_CRT_REGEX flag_string) 126617a3babSopenharmony_ci endforeach(lang) 127617a3babSopenharmony_ci endforeach(build_type) 128617a3babSopenharmony_ciendmacro(choose_msvc_crt MSVC_CRT) 129617a3babSopenharmony_ci 130617a3babSopenharmony_ci 131617a3babSopenharmony_ci# List of valid CRTs for MSVC 132617a3babSopenharmony_ciset(MSVC_CRT 133617a3babSopenharmony_ci MD 134617a3babSopenharmony_ci MDd 135617a3babSopenharmony_ci MT 136617a3babSopenharmony_ci MTd) 137617a3babSopenharmony_ci 138617a3babSopenharmony_cichoose_msvc_crt(MSVC_CRT) 139