-
-
Notifications
You must be signed in to change notification settings - Fork 56
/
Copy pathUtilities.cmake
180 lines (152 loc) · 5.56 KB
/
Utilities.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
include_guard()
# find a subtring from a string by a given prefix such as VCVARSALL_ENV_START
function(find_substring_by_prefix output prefix input)
# find the prefix
string(FIND "${input}" "${prefix}" prefix_index)
if("${prefix_index}" STREQUAL "-1")
message(SEND_ERROR "Could not find ${prefix} in ${input}")
endif()
# find the start index
string(LENGTH "${prefix}" prefix_length)
math(EXPR start_index "${prefix_index} + ${prefix_length}")
string(SUBSTRING "${input}" "${start_index}" "-1" _output)
set("${output}" "${_output}" PARENT_SCOPE)
endfunction()
# A function to set environment variables of CMake from the output of `cmd /c set`
function(set_env_from_string _env_string)
# replace ; in paths with __sep__ so we can split on ;
string(REGEX REPLACE ";" "__sep__" _env_string_sep_added "${_env_string}")
# the variables are separated by \r?\n
string(REGEX REPLACE "\r?\n" ";" _env_list "${_env_string_sep_added}")
foreach(_env_var ${_env_list})
# split by =
string(REGEX REPLACE "=" ";" _env_parts "${_env_var}")
list(LENGTH _env_parts _env_parts_length)
if("${_env_parts_length}" EQUAL "2")
# get the variable name and value
list(GET _env_parts 0 _env_name)
list(GET _env_parts 1 _env_value)
# recover ; in paths
string(REGEX REPLACE "__sep__" ";" _env_value "${_env_value}")
# set _env_name to _env_value
set(ENV{${_env_name}} "${_env_value}")
# update cmake program path
if("${_env_name}" EQUAL "PATH")
list(APPEND CMAKE_PROGRAM_PATH ${_env_value})
endif()
endif()
endforeach()
endfunction()
# Get all the CMake targets
function(get_all_targets var)
set(targets)
get_all_targets_recursive(targets ${CMAKE_CURRENT_SOURCE_DIR})
set(${var} ${targets} PARENT_SCOPE)
endfunction()
# Get all the installable CMake targets
function(get_all_installable_targets var)
set(targets)
get_all_targets(targets)
foreach(_target ${targets})
get_target_property(_target_type ${_target} TYPE)
if(NOT ${_target_type} MATCHES ".*LIBRARY|EXECUTABLE")
list(REMOVE_ITEM targets ${_target})
endif()
endforeach()
set(${var} ${targets} PARENT_SCOPE)
endfunction()
# Get all the CMake targets in the given directory
macro(get_all_targets_recursive targets dir)
get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
foreach(subdir ${subdirectories})
get_all_targets_recursive(${targets} ${subdir})
endforeach()
get_property(current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
list(APPEND ${targets} ${current_targets})
endmacro()
# Is CMake verbose?
function(is_verbose var)
if("${CMAKE_MESSAGE_LOG_LEVEL}" STREQUAL "VERBOSE" OR "${CMAKE_MESSAGE_LOG_LEVEL}" STREQUAL "DEBUG"
OR "${CMAKE_MESSAGE_LOG_LEVEL}" STREQUAL "TRACE"
)
set(${var} ON PARENT_SCOPE)
else()
set(${var} OFF PARENT_SCOPE)
endif()
endfunction()
# detect the architecture of the target build system or the host system as a fallback
function(detect_architecture arch)
# if the target processor is not known, fallback to the host processor
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "" AND NOT "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "")
set(_arch "${CMAKE_HOST_SYSTEM_PROCESSOR}")
elseif(NOT "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "")
set(_arch "${CMAKE_SYSTEM_PROCESSOR}")
elseif(NOT "${DETECTED_CMAKE_SYSTEM_PROCESSOR}" # set by detect_compiler()
STREQUAL ""
)
set(_arch "${DETECTED_CMAKE_SYSTEM_PROCESSOR}")
endif()
# make it lowercase for comparison
string(TOLOWER "${_arch}" _arch)
if(_arch STREQUAL x86 OR _arch MATCHES "^i[3456]86$")
set(${arch} x86 PARENT_SCOPE)
elseif(_arch STREQUAL x64 OR _arch STREQUAL x86_64 OR _arch STREQUAL amd64)
set(${arch} x64 PARENT_SCOPE)
elseif(_arch STREQUAL arm)
set(${arch} arm PARENT_SCOPE)
elseif(_arch STREQUAL arm64 OR _arch STREQUAL aarch64)
set(${arch} arm64 PARENT_SCOPE)
elseif(_arch STREQUAL riscv64)
set(${arch} rv64 PARENT_SCOPE)
elseif(_arch STREQUAL riscv32)
set(${arch} rv32 PARENT_SCOPE)
else()
# fallback to the most common architecture
message(STATUS "Unknown architecture ${_arch} - using x64")
set(${arch} x64 PARENT_SCOPE)
endif()
endfunction()
function(detect_macos_version version)
find_program(SW_VERS_EXECUTABLE sw_vers)
execute_process(COMMAND "${SW_VERS_EXECUTABLE}" -productVersion OUTPUT_VARIABLE MACOS_VERSION)
set(${version} "${MACOS_VERSION}" PARENT_SCOPE)
endfunction()
# convert semicolons in generator expression to $<SEMICOLON>
function(convert_genex_semicolons genex output)
set(result)
set(depth 0)
set(index 0)
set(prefixed_with_dollar FALSE)
string(LENGTH "${genex}" length)
while(index LESS length)
string(SUBSTRING "${genex}" ${index} 1 ch)
if(ch STREQUAL "$")
set(prefixed_with_dollar TRUE)
string(APPEND result "${ch}")
elseif(ch STREQUAL "<")
if(prefixed_with_dollar)
set(prefixed_with_dollar FALSE)
math(EXPR depth "${depth}+1")
endif()
string(APPEND result "${ch}")
elseif(ch STREQUAL ">")
set(prefixed_with_dollar FALSE)
if(depth GREATER 0)
math(EXPR depth "${depth}-1")
endif()
string(APPEND result "${ch}")
elseif(ch STREQUAL ";")
set(prefixed_with_dollar FALSE)
if(depth GREATER 0)
string(APPEND result "$<SEMICOLON>")
else()
string(APPEND result "${ch}")
endif()
else()
set(prefixed_with_dollar FALSE)
string(APPEND result "${ch}")
endif()
math(EXPR index "${index}+1")
endwhile()
set("${output}" "${result}" PARENT_SCOPE)
endfunction()