-
Notifications
You must be signed in to change notification settings - Fork 1
/
DLLDeployer.cmake
225 lines (182 loc) · 7.95 KB
/
DLLDeployer.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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
cmake_minimum_required(VERSION 3.25)
set(DLLD_deploy_dll_exe_version "1.5.1")
# Replace backslash \ with slash /
function(DLLD_replace_backslash in_var out_var)
set(temp)
foreach (item ${${in_var}})
string(REPLACE "\\" "/" item ${item})
list(APPEND temp ${item})
endforeach ()
set(${out_var} ${temp} PARENT_SCOPE)
endfunction()
function(DLLD_validate_deploy_dll_exe exe_location out_error)
unset(${out_error} PARENT_SCOPE)
execute_process(COMMAND ${exe_location} --version
OUTPUT_VARIABLE output
COMMAND_ERROR_IS_FATAL ANY)
string(REPLACE " " ";" splitted_output ${output})
list(LENGTH splitted_output len)
if(${len} LESS 2)
set(${out_error} "Failed to deduce version from output \"${output}\"" PARENT_SCOPE)
return()
endif ()
list(GET splitted_output 1 this_version)
if(${this_version} VERSION_LESS ${DLLD_deploy_dll_exe_version})
set(${out_error} "Required at least ${DLLD_deploy_dll_exe_version}, but found ${this_version}" PARENT_SCOPE)
return()
endif ()
set(${out_error} "" PARENT_SCOPE)
endfunction()
function(DLLD_find_dll_deployer_validator validator_result_var item)
DLLD_validate_deploy_dll_exe(${item} error)
if(error)
message(STATUS "Skip ${item} because ${error}")
set(${validator_result_var} FALSE PARENT_SCOPE)
else ()
set(${validator_result_var} TRUE PARENT_SCOPE)
endif ()
endfunction()
function(DLLD_get_deploy_dll_exe out_deploy_dll out_objdump)
unset(${out_deploy_dll} PARENT_SCOPE)
unset(${out_objdump} PARENT_SCOPE)
set(extract_destination "${PROJECT_BINARY_DIR}/3rdParty/SharedLibDeployer")
set(found_components 0)
message(STATUS "Searching for installed deploy-dll executable")
find_program(exe_path
NAMES "deploy-dll"
HINTS ${extract_destination}/bin
VALIDATOR DLLD_find_dll_deployer_validator
NO_CACHE)
if(exe_path)
message(STATUS "Found ${exe_path}")
set(${out_deploy_dll} ${exe_path} PARENT_SCOPE)
math(EXPR found_components "${found_components} + 1")
endif ()
message(STATUS "Searching for objdump executable")
find_program(objdump_path
NAMES "objdump"
HINTS ${extract_destination}/bin
NO_CACHE)
if(objdump_path)
message(STATUS "Found ${objdump_path}")
set(${out_objdump} ${objdump_path} PARENT_SCOPE)
math(EXPR found_components "${found_components} + 1")
endif ()
if(${found_components} GREATER_EQUAL 2)
return()
endif ()
message(STATUS "Downloading and extracting SharedLibDeployer-${DLLD_deploy_dll_exe_version}-win64.7z")
set(archive_loc "${PROJECT_BINARY_DIR}/SharedLibDeployer-${DLLD_deploy_dll_exe_version}-win64.7z")
file(DOWNLOAD https://github.com/SlopeCraft/SharedLibDeployer/releases/download/v${DLLD_deploy_dll_exe_version}/SharedLibDeployer-${DLLD_deploy_dll_exe_version}-win64.7z
${archive_loc}
EXPECTED_HASH SHA512=9EAC9586417FF351F3CB2FF965734AF7AA5029406EAAA282CF9507375E5E4A4B35DFFF12A974E36917F440D3443EFF366576B563C9E7F02DD9A54965D706985D
)
file(ARCHIVE_EXTRACT INPUT ${archive_loc} DESTINATION ${extract_destination})
set(extracted_deploy_dll_exe "${extract_destination}/bin/deploy-dll.exe")
if(NOT EXISTS ${extracted_deploy_dll_exe})
message(FATAL_ERROR "${archive_loc} was extracted, but \"${extracted_deploy_dll_exe}\" was not found")
endif ()
DLLD_replace_backslash(extracted_deploy_dll_exe extracted_deploy_dll_exe)
set(${out_deploy_dll} ${extracted_deploy_dll_exe} PARENT_SCOPE)
set(extracted_objdump_exe "${extract_destination}/bin/objdump.exe")
if(NOT EXISTS ${extracted_objdump_exe})
message(FATAL_ERROR "${archive_loc} was extracted, but \"${extracted_objdump_exe}\" was not found")
endif ()
DLLD_replace_backslash(extracted_objdump_exe extracted_objdump_exe)
set(${out_objdump} ${extracted_objdump_exe} PARENT_SCOPE)
# message(STATUS "Searching for cargo")
# find_program(cargo_path NAMES cargo)
# if(cargo_path)
# message(STATUS "Cloning ")
# endif ()
endfunction()
DLLD_get_deploy_dll_exe(DLLD_deploy_dll_executable_location DLLD_objdump_executable_location)
function(DLLD_add_deploy target_name)
cmake_parse_arguments(DLLD_add_deploy
"BUILD_MODE;INSTALL_MODE;ALL;VERBOSE;COPY_VC_REDIST"
"INSTALL_DESTINATION"
"IGNORE;OPTIONAL_DLLS;FLAGS"
${ARGN})
# Check target type
get_target_property(target_type ${target_name} TYPE)
set(valid_types EXECUTABLE SHARED_LIBRARY)
if(NOT ${target_type} IN_LIST valid_types)
message(FATAL_ERROR "The type of ${target_name} is invalid. Valid types: ${valid_types}")
endif ()
# Get filename of target
get_target_property(target_prefix ${target_name} PREFIX)
get_target_property(target_prop_name ${target_name} NAME)
get_target_property(target_suffix ${target_name} SUFFIX)
set(filename ${target_prop_name})
if(target_prefix)
set(filename "${target_prefix}${filename}")
endif ()
if(target_suffix)
set(filename "${filename}${target_suffix}")
endif ()
if(${target_type} STREQUAL EXECUTABLE)
set(filename "${filename}.exe")
else ()
set(filename "${filename}.dll")
endif ()
set(flags "")
foreach (ignore_dll_name ${DLLD_add_deploy_IGNORE})
list(APPEND flags "--ignore=${ignore_dll_name}")
endforeach ()
if(${DLLD_add_deploy_VERBOSE})
list(APPEND flags "--verbose")
endif ()
if(${DLLD_add_deploy_COPY_VC_REDIST})
list(APPEND flags "--copy-vc-redist")
endif ()
cmake_path(GET CMAKE_C_COMPILER PARENT_PATH c_compiler_path)
if(c_compiler_path)
list(APPEND flags "\"--shallow-search-dir=${c_compiler_path}\"")
endif ()
cmake_path(GET CMAKE_CXX_COMPILER PARENT_PATH cxx_compiler_path)
if((cxx_compiler_path) AND (NOT c_compiler_path STREQUAL cxx_compiler_path))
list(APPEND flags "\"--shallow-search-dir=${cxx_compiler_path}\"")
endif ()
list(APPEND flags "\"--deep-search-dir=${CMAKE_BINARY_DIR}\"")
foreach (item ${DLLD_add_deploy_OPTIONAL_DLLS})
list(APPEND flags "\"--optional-dlls=${item}\"")
endforeach ()
DLLD_replace_backslash(CMAKE_PREFIX_PATH CMAKE_PREFIX_PATH)
foreach (path ${CMAKE_PREFIX_PATH})
list(APPEND flags "\"--cmake-prefix-path=${path}\"")
endforeach ()
list(APPEND flags ${DLLD_add_deploy_FLAGS})
if(${DLLD_add_deploy_BUILD_MODE})
set(custom_target_name "DLLD_deploy_for_${target_name}")
if (${DLLD_add_deploy_ALL})
set(DLLD_all_tag ALL)
else ()
set(DLLD_all_tag)
endif ()
get_target_property(target_binary_dir ${target_name} BINARY_DIR)
add_custom_target(${custom_target_name}
${DLLD_all_tag}
COMMAND ${DLLD_deploy_dll_executable_location} ${filename} --objdump-file=${DLLD_objdump_executable_location} ${flags}
WORKING_DIRECTORY ${target_binary_dir}
DEPENDS ${target_name}
COMMENT "Deploy dll for ${target_name} at build directory"
COMMAND_EXPAND_LISTS)
if(NOT TARGET DLLD_deploy_all)
add_custom_target(DLLD_deploy_all
COMMENT "Build all targets like DLLD_deploy_for_*")
endif ()
add_dependencies(DLLD_deploy_all ${custom_target_name})
if(TARGET "QD_deploy_for_${target_name}")
add_dependencies(${custom_target_name} "QD_deploy_for_${target_name}")
endif ()
endif ()
if(${DLLD_add_deploy_INSTALL_MODE})
string(JOIN " " flags ${flags})
install(CODE
"
execute_process(COMMAND \"${DLLD_deploy_dll_executable_location}\" \"./${DLLD_add_deploy_INSTALL_DESTINATION}/${filename}\" \"--objdump-file=${DLLD_objdump_executable_location}\" ${flags}
WORKING_DIRECTORY \${CMAKE_INSTALL_PREFIX}
COMMAND_ERROR_IS_FATAL ANY)
")
endif ()
endfunction()