16050
|
1 |
function(_cargo_metadata out manifest)
|
|
2 |
set(OPTIONS LOCKED FROZEN)
|
|
3 |
set(ONE_VALUE_KEYWORDS "")
|
|
4 |
set(MULTI_VALUE_KEYWORDS "")
|
|
5 |
cmake_parse_arguments(PARSE_ARGV 2 CM "${OPTIONS}" "${ONE_VALUE_KEYWORDS}" "${MULTI_VALUE_KEYWORDS}")
|
|
6 |
|
|
7 |
list(APPEND CMAKE_MESSAGE_CONTEXT "_cargo_metadata")
|
|
8 |
|
|
9 |
if(DEFINED CM_UNPARSED_ARGUMENTS)
|
|
10 |
message(FATAL_ERROR "Internal error - unexpected arguments: ${CM_UNPARSED_ARGUMENTS}")
|
|
11 |
elseif(DEFINED CM_KEYWORDS_MISSING_VALUES)
|
|
12 |
message(FATAL_ERROR "Internal error - the following keywords had no associated value(s):"
|
|
13 |
"${CM_KEYWORDS_MISSING_VALUES}")
|
|
14 |
endif()
|
|
15 |
|
|
16 |
set(cargo_locked "")
|
|
17 |
set(cargo_frozen "")
|
|
18 |
if(LOCKED)
|
|
19 |
set(cargo_locked "--locked")
|
|
20 |
endif()
|
|
21 |
if(FROZEN)
|
|
22 |
set(cargo_frozen "--frozen")
|
|
23 |
endif()
|
|
24 |
execute_process(
|
|
25 |
COMMAND
|
|
26 |
${CMAKE_COMMAND} -E env
|
|
27 |
"CARGO_BUILD_RUSTC=${_CORROSION_RUSTC}"
|
|
28 |
"${_CORROSION_CARGO}"
|
|
29 |
metadata
|
|
30 |
--manifest-path "${manifest}"
|
|
31 |
--format-version 1
|
|
32 |
# We don't care about non-workspace dependencies
|
|
33 |
--no-deps
|
|
34 |
${cargo_locked}
|
|
35 |
${cargo_frozen}
|
|
36 |
|
|
37 |
OUTPUT_VARIABLE json
|
|
38 |
COMMAND_ERROR_IS_FATAL ANY
|
|
39 |
)
|
|
40 |
|
|
41 |
set(${out} "${json}" PARENT_SCOPE)
|
|
42 |
endfunction()
|
|
43 |
|
|
44 |
# Add targets (crates) of one package
|
|
45 |
function(_generator_add_package_targets)
|
|
46 |
set(OPTIONS NO_LINKER_OVERRIDE)
|
16067
|
47 |
set(ONE_VALUE_KEYWORDS
|
|
48 |
WORKSPACE_MANIFEST_PATH
|
|
49 |
PACKAGE_MANIFEST_PATH
|
|
50 |
PACKAGE_NAME
|
|
51 |
PACKAGE_VERSION
|
|
52 |
TARGETS_JSON
|
|
53 |
OUT_CREATED_TARGETS)
|
|
54 |
set(MULTI_VALUE_KEYWORDS CRATE_TYPES OVERRIDE_CRATE_TYPE_ARGS)
|
16050
|
55 |
cmake_parse_arguments(PARSE_ARGV 0 GAPT "${OPTIONS}" "${ONE_VALUE_KEYWORDS}" "${MULTI_VALUE_KEYWORDS}")
|
|
56 |
|
|
57 |
if(DEFINED GAPT_UNPARSED_ARGUMENTS)
|
|
58 |
message(FATAL_ERROR "Internal error - unexpected arguments: ${GAPT_UNPARSED_ARGUMENTS}")
|
|
59 |
elseif(DEFINED GAPT_KEYWORDS_MISSING_VALUES)
|
|
60 |
message(FATAL_ERROR "Internal error - the following keywords had no associated value(s):"
|
|
61 |
"${GAPT_KEYWORDS_MISSING_VALUES}")
|
|
62 |
endif()
|
|
63 |
|
|
64 |
_corrosion_option_passthrough_helper(NO_LINKER_OVERRIDE GAPT no_linker_override)
|
|
65 |
|
|
66 |
set(workspace_manifest_path "${GAPT_WORKSPACE_MANIFEST_PATH}")
|
|
67 |
set(package_manifest_path "${GAPT_PACKAGE_MANIFEST_PATH}")
|
|
68 |
set(package_name "${GAPT_PACKAGE_NAME}")
|
|
69 |
set(package_version "${GAPT_PACKAGE_VERSION}")
|
|
70 |
set(targets "${GAPT_TARGETS_JSON}")
|
|
71 |
set(out_created_targets "${GAPT_OUT_CREATED_TARGETS}")
|
|
72 |
set(crate_types "${GAPT_CRATE_TYPES}")
|
16067
|
73 |
if(DEFINED GAPT_OVERRIDE_CRATE_TYPE_ARGS)
|
|
74 |
list(GET GAPT_OVERRIDE_CRATE_TYPE_ARGS 0 override_crate_name_list_ref)
|
|
75 |
list(GET GAPT_OVERRIDE_CRATE_TYPE_ARGS 1 override_crate_types_list_ref)
|
|
76 |
endif()
|
16050
|
77 |
|
|
78 |
set(corrosion_targets "")
|
|
79 |
|
|
80 |
file(TO_CMAKE_PATH "${package_manifest_path}" manifest_path)
|
|
81 |
|
|
82 |
string(JSON targets_len LENGTH "${targets}")
|
|
83 |
math(EXPR targets_len-1 "${targets_len} - 1")
|
|
84 |
|
|
85 |
message(DEBUG "Found ${targets_len} targets in package ${package_name}")
|
|
86 |
|
|
87 |
foreach(ix RANGE ${targets_len-1})
|
|
88 |
string(JSON target GET "${targets}" ${ix})
|
|
89 |
string(JSON target_name GET "${target}" "name")
|
|
90 |
string(JSON target_kind GET "${target}" "kind")
|
|
91 |
string(JSON target_kind_len LENGTH "${target_kind}")
|
|
92 |
|
|
93 |
math(EXPR target_kind_len-1 "${target_kind_len} - 1")
|
|
94 |
set(kinds)
|
16067
|
95 |
unset(override_package_crate_type)
|
|
96 |
# OVERRIDE_CRATE_TYPE is more specific than the CRATE_TYPES argument to corrosion_import_crate, and thus takes
|
|
97 |
# priority.
|
|
98 |
if(DEFINED GAPT_OVERRIDE_CRATE_TYPE_ARGS)
|
|
99 |
foreach(override_crate_name override_crate_types IN ZIP_LISTS ${override_crate_name_list_ref} ${override_crate_types_list_ref})
|
|
100 |
if("${override_crate_name}" STREQUAL "${target_name}")
|
|
101 |
message(DEBUG "Forcing crate ${target_name} to crate-type(s): ${override_crate_types}.")
|
|
102 |
# Convert to CMake list
|
|
103 |
string(REPLACE "," ";" kinds "${override_crate_types}")
|
|
104 |
break()
|
|
105 |
endif()
|
|
106 |
endforeach()
|
|
107 |
else()
|
|
108 |
foreach(ix RANGE ${target_kind_len-1})
|
|
109 |
string(JSON kind GET "${target_kind}" ${ix})
|
|
110 |
if(NOT crate_types OR ${kind} IN_LIST crate_types)
|
|
111 |
list(APPEND kinds ${kind})
|
|
112 |
endif()
|
|
113 |
endforeach()
|
|
114 |
endif()
|
16050
|
115 |
if(TARGET "${target_name}"
|
|
116 |
AND ("staticlib" IN_LIST kinds OR "cdylib" IN_LIST kinds OR "bin" IN_LIST kinds)
|
|
117 |
)
|
|
118 |
message(WARNING "Failed to import Rust crate ${target_name} (kind: `${target_kind}`) because a target "
|
|
119 |
"with the same name already exists. Skipping this target.\n"
|
|
120 |
"Help: If you are importing a package which exposes both a `lib` and "
|
|
121 |
"a `bin` target, please consider explicitly naming the targets in your `Cargo.toml` manifest.\n"
|
|
122 |
"Note: If you have multiple different packages which have targets with the same name, please note that "
|
|
123 |
"this is currently not supported by Corrosion. Feel free to open an issue on Github to request "
|
|
124 |
"supporting this scenario."
|
|
125 |
)
|
|
126 |
# Skip this target to prevent a hard error.
|
|
127 |
continue()
|
|
128 |
endif()
|
|
129 |
|
|
130 |
if("staticlib" IN_LIST kinds OR "cdylib" IN_LIST kinds)
|
|
131 |
# Explicitly set library names have always been forbidden from using dashes (by cargo).
|
|
132 |
# Starting with Rust 1.79, names inherited from the package name will have dashes replaced
|
|
133 |
# by underscores too. Corrosion will thus replace dashes with underscores, to make the target
|
|
134 |
# name consistent independent of the Rust version. `bin` target names are not affected.
|
|
135 |
# See https://github.com/corrosion-rs/corrosion/issues/501 for more details.
|
|
136 |
string(REPLACE "\-" "_" target_name "${target_name}")
|
|
137 |
|
|
138 |
set(archive_byproducts "")
|
|
139 |
set(shared_lib_byproduct "")
|
|
140 |
set(pdb_byproduct "")
|
|
141 |
|
16067
|
142 |
add_library(${target_name} INTERFACE)
|
|
143 |
_corrosion_initialize_properties(${target_name})
|
16050
|
144 |
_corrosion_add_library_target(
|
|
145 |
WORKSPACE_MANIFEST_PATH "${workspace_manifest_path}"
|
|
146 |
TARGET_NAME "${target_name}"
|
|
147 |
LIB_KINDS ${kinds}
|
|
148 |
OUT_ARCHIVE_OUTPUT_BYPRODUCTS archive_byproducts
|
|
149 |
OUT_SHARED_LIB_BYPRODUCTS shared_lib_byproduct
|
|
150 |
OUT_PDB_BYPRODUCT pdb_byproduct
|
|
151 |
)
|
|
152 |
|
|
153 |
set(byproducts "")
|
|
154 |
list(APPEND byproducts "${archive_byproducts}" "${shared_lib_byproduct}" "${pdb_byproduct}")
|
|
155 |
|
|
156 |
set(cargo_build_out_dir "")
|
|
157 |
_add_cargo_build(
|
|
158 |
cargo_build_out_dir
|
|
159 |
PACKAGE ${package_name}
|
|
160 |
TARGET ${target_name}
|
|
161 |
MANIFEST_PATH "${manifest_path}"
|
|
162 |
WORKSPACE_MANIFEST_PATH "${workspace_manifest_path}"
|
|
163 |
TARGET_KINDS "${kinds}"
|
|
164 |
BYPRODUCTS "${byproducts}"
|
|
165 |
# Optional
|
|
166 |
${no_linker_override}
|
|
167 |
)
|
|
168 |
if(archive_byproducts)
|
|
169 |
_corrosion_copy_byproducts(
|
|
170 |
${target_name} ARCHIVE_OUTPUT_DIRECTORY "${cargo_build_out_dir}" "${archive_byproducts}"
|
|
171 |
)
|
|
172 |
endif()
|
|
173 |
if(shared_lib_byproduct)
|
|
174 |
_corrosion_copy_byproducts(
|
|
175 |
${target_name} LIBRARY_OUTPUT_DIRECTORY "${cargo_build_out_dir}" "${shared_lib_byproduct}"
|
|
176 |
)
|
|
177 |
endif()
|
|
178 |
if(pdb_byproduct)
|
|
179 |
_corrosion_copy_byproducts(
|
16067
|
180 |
${target_name} "PDB_OUTPUT_DIRECTORY;LIBRARY_OUTPUT_DIRECTORY" "${cargo_build_out_dir}" "${pdb_byproduct}"
|
16050
|
181 |
)
|
|
182 |
endif()
|
|
183 |
list(APPEND corrosion_targets ${target_name})
|
16067
|
184 |
set_property(TARGET "${target_name}" PROPERTY COR_CARGO_PACKAGE_NAME "${package_name}" )
|
16050
|
185 |
# Note: "bin" is mutually exclusive with "staticlib/cdylib", since `bin`s are seperate crates from libraries.
|
|
186 |
elseif("bin" IN_LIST kinds)
|
|
187 |
set(bin_byproduct "")
|
|
188 |
set(pdb_byproduct "")
|
16067
|
189 |
add_executable(${target_name} IMPORTED GLOBAL)
|
|
190 |
_corrosion_initialize_properties(${target_name})
|
16050
|
191 |
_corrosion_add_bin_target("${workspace_manifest_path}" "${target_name}"
|
|
192 |
"bin_byproduct" "pdb_byproduct"
|
|
193 |
)
|
|
194 |
|
|
195 |
set(byproducts "")
|
|
196 |
list(APPEND byproducts "${bin_byproduct}" "${pdb_byproduct}")
|
|
197 |
|
|
198 |
set(cargo_build_out_dir "")
|
|
199 |
_add_cargo_build(
|
|
200 |
cargo_build_out_dir
|
|
201 |
PACKAGE "${package_name}"
|
|
202 |
TARGET "${target_name}"
|
|
203 |
MANIFEST_PATH "${manifest_path}"
|
|
204 |
WORKSPACE_MANIFEST_PATH "${workspace_manifest_path}"
|
|
205 |
TARGET_KINDS "bin"
|
|
206 |
BYPRODUCTS "${byproducts}"
|
|
207 |
# Optional
|
|
208 |
${no_linker_override}
|
|
209 |
)
|
|
210 |
_corrosion_copy_byproducts(
|
|
211 |
${target_name} RUNTIME_OUTPUT_DIRECTORY "${cargo_build_out_dir}" "${bin_byproduct}"
|
|
212 |
)
|
|
213 |
if(pdb_byproduct)
|
|
214 |
_corrosion_copy_byproducts(
|
16067
|
215 |
${target_name} "PDB_OUTPUT_DIRECTORY;RUNTIME_OUTPUT_DIRECTORY" "${cargo_build_out_dir}" "${pdb_byproduct}"
|
16050
|
216 |
)
|
|
217 |
endif()
|
|
218 |
list(APPEND corrosion_targets ${target_name})
|
16067
|
219 |
set_property(TARGET "${target_name}" PROPERTY COR_CARGO_PACKAGE_NAME "${package_name}" )
|
16050
|
220 |
else()
|
|
221 |
# ignore other kinds (like examples, tests, build scripts, ...)
|
|
222 |
endif()
|
|
223 |
endforeach()
|
|
224 |
|
|
225 |
if(NOT corrosion_targets)
|
|
226 |
message(DEBUG "No relevant targets found in package ${package_name} - Ignoring")
|
|
227 |
else()
|
|
228 |
set_target_properties(${corrosion_targets} PROPERTIES INTERFACE_COR_PACKAGE_MANIFEST_PATH "${package_manifest_path}")
|
|
229 |
endif()
|
|
230 |
set(${out_created_targets} "${corrosion_targets}" PARENT_SCOPE)
|
|
231 |
|
|
232 |
endfunction()
|
|
233 |
|
|
234 |
# Add all cargo targets defined in the packages defined in the Cargo.toml manifest at
|
|
235 |
# `MANIFEST_PATH`.
|
|
236 |
function(_generator_add_cargo_targets)
|
|
237 |
set(options NO_LINKER_OVERRIDE)
|
|
238 |
set(one_value_args MANIFEST_PATH IMPORTED_CRATES)
|
16067
|
239 |
set(multi_value_args CRATES CRATE_TYPES OVERRIDE_CRATE_TYPE_ARGS)
|
16050
|
240 |
cmake_parse_arguments(
|
|
241 |
GGC
|
|
242 |
"${options}"
|
|
243 |
"${one_value_args}"
|
|
244 |
"${multi_value_args}"
|
|
245 |
${ARGN}
|
|
246 |
)
|
|
247 |
list(APPEND CMAKE_MESSAGE_CONTEXT "_add_cargo_targets")
|
|
248 |
|
|
249 |
_corrosion_option_passthrough_helper(NO_LINKER_OVERRIDE GGC no_linker_override)
|
|
250 |
_corrosion_arg_passthrough_helper(CRATE_TYPES GGC crate_types)
|
16067
|
251 |
_corrosion_arg_passthrough_helper(OVERRIDE_CRATE_TYPE_ARGS GGC override_crate_types)
|
16050
|
252 |
|
|
253 |
_cargo_metadata(json "${GGC_MANIFEST_PATH}")
|
|
254 |
string(JSON packages GET "${json}" "packages")
|
|
255 |
string(JSON workspace_members GET "${json}" "workspace_members")
|
|
256 |
|
|
257 |
string(JSON pkgs_len LENGTH "${packages}")
|
|
258 |
math(EXPR pkgs_len-1 "${pkgs_len} - 1")
|
|
259 |
|
|
260 |
string(JSON ws_mems_len LENGTH ${workspace_members})
|
|
261 |
math(EXPR ws_mems_len-1 "${ws_mems_len} - 1")
|
|
262 |
|
|
263 |
set(created_targets "")
|
|
264 |
set(available_package_names "")
|
|
265 |
foreach(ix RANGE ${pkgs_len-1})
|
|
266 |
string(JSON pkg GET "${packages}" ${ix})
|
|
267 |
string(JSON pkg_id GET "${pkg}" "id")
|
|
268 |
string(JSON pkg_name GET "${pkg}" "name")
|
|
269 |
string(JSON pkg_manifest_path GET "${pkg}" "manifest_path")
|
|
270 |
string(JSON pkg_version GET "${pkg}" "version")
|
|
271 |
list(APPEND available_package_names "${pkg_name}")
|
|
272 |
|
|
273 |
if(DEFINED GGC_CRATES)
|
|
274 |
if(NOT pkg_name IN_LIST GGC_CRATES)
|
|
275 |
continue()
|
|
276 |
endif()
|
|
277 |
endif()
|
|
278 |
|
|
279 |
# probably this loop is not necessary at all, since when using --no-deps, the
|
|
280 |
# contents of packages should already be only workspace members!
|
|
281 |
unset(pkg_is_ws_member)
|
|
282 |
foreach(ix RANGE ${ws_mems_len-1})
|
|
283 |
string(JSON ws_mem GET "${workspace_members}" ${ix})
|
|
284 |
if(ws_mem STREQUAL pkg_id)
|
|
285 |
set(pkg_is_ws_member YES)
|
|
286 |
break()
|
|
287 |
endif()
|
|
288 |
endforeach()
|
|
289 |
|
|
290 |
if(NOT DEFINED pkg_is_ws_member)
|
|
291 |
# Since we pass `--no-deps` to cargo metadata now, I think this situation can't happen, but lets check for
|
|
292 |
# it anyway, just to discover any potential issues.
|
|
293 |
# If nobody complains for a while, it should be safe to remove this check and the previous loop, which
|
|
294 |
# should speed up the configuration process.
|
|
295 |
message(WARNING "The package `${pkg_name}` unexpectedly is not part of the workspace."
|
|
296 |
"Please open an issue at corrosion with some background information on the package"
|
|
297 |
)
|
|
298 |
endif()
|
|
299 |
|
|
300 |
string(JSON targets GET "${pkg}" "targets")
|
|
301 |
|
|
302 |
_generator_add_package_targets(
|
|
303 |
WORKSPACE_MANIFEST_PATH "${GGC_MANIFEST_PATH}"
|
|
304 |
PACKAGE_MANIFEST_PATH "${pkg_manifest_path}"
|
|
305 |
PACKAGE_NAME "${pkg_name}"
|
|
306 |
PACKAGE_VERSION "${pkg_version}"
|
|
307 |
TARGETS_JSON "${targets}"
|
|
308 |
OUT_CREATED_TARGETS curr_created_targets
|
|
309 |
${no_linker_override}
|
|
310 |
${crate_types}
|
16067
|
311 |
${override_crate_types}
|
16050
|
312 |
)
|
|
313 |
list(APPEND created_targets "${curr_created_targets}")
|
|
314 |
endforeach()
|
|
315 |
|
|
316 |
if(NOT created_targets)
|
|
317 |
set(crates_error_message "")
|
|
318 |
if(DEFINED GGC_CRATES)
|
|
319 |
set(crates_error_message "\n`corrosion_import_crate()` was called with the `CRATES` "
|
|
320 |
"parameter set to `${GGC_CRATES}`. Corrosion will only attempt to import packages matching "
|
|
321 |
"names from this list."
|
|
322 |
)
|
|
323 |
endif()
|
|
324 |
message(FATAL_ERROR
|
|
325 |
"Found no targets in ${pkgs_len} packages."
|
|
326 |
${crates_error_message}.
|
|
327 |
"\nPlease keep in mind that corrosion will only import Rust `bin` targets or"
|
|
328 |
"`staticlib` or `cdylib` library targets."
|
|
329 |
"The following packages were found in the Manifest: ${available_package_names}"
|
|
330 |
)
|
|
331 |
else()
|
|
332 |
message(DEBUG "Corrosion created the following CMake targets: ${created_targets}")
|
|
333 |
endif()
|
|
334 |
|
|
335 |
if(GGC_IMPORTED_CRATES)
|
|
336 |
set(${GGC_IMPORTED_CRATES} "${created_targets}" PARENT_SCOPE)
|
|
337 |
endif()
|
|
338 |
endfunction()
|