Skip to content

Commit 1b76e31

Browse files
charles-lunargBoiledElectricity
authored andcommitted
Add CMake code to support Arm64X builds
Since building arm64x is a two step process, we use CMake to cache the binary artifacts from the first build step so it can apply them during the second build step. (cherry picked from commit 3bde50c)
1 parent 26a2a29 commit 1b76e31

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,47 @@ if (BUILD_TESTS)
324324
enable_testing()
325325
add_subdirectory(tests)
326326
endif()
327+
328+
329+
# Building Arm64X binaries requires 2 builds. One for the arm64 code, and the other for the x64.
330+
# Source https://learn.microsoft.com/en-us/windows/arm/arm64x-build#building-an-arm64x-dll-with-cmake
331+
if(DEFINED BUILD_AS_ARM64X)
332+
set(ARM64X_TARGETS vulkan)
333+
334+
# directory where the link.rsp file generated during arm64 build will be stored
335+
set(arm64ReproDir "${CMAKE_CURRENT_SOURCE_DIR}/repros")
336+
337+
# This function reads in the content of the rsp file outputted from arm64 build for a target. Then passes the arm64 libs, objs and def file to the linker using /machine:arm64x to combine them with the arm64ec counterparts and create an arm64x binary.
338+
339+
function(set_arm64_dependencies n)
340+
set(REPRO_FILE "${arm64ReproDir}/${n}.rsp")
341+
file(STRINGS "${REPRO_FILE}" ARM64_OBJS REGEX obj\"$)
342+
file(STRINGS "${REPRO_FILE}" ARM64_DEF REGEX def\"$)
343+
file(STRINGS "${REPRO_FILE}" ARM64_LIBS REGEX lib\"$)
344+
string(REPLACE "\"" ";" ARM64_OBJS "${ARM64_OBJS}")
345+
string(REPLACE "\"" ";" ARM64_LIBS "${ARM64_LIBS}")
346+
string(REPLACE "\"" ";" ARM64_DEF "${ARM64_DEF}")
347+
string(REPLACE "/def:" "/defArm64Native:" ARM64_DEF "${ARM64_DEF}")
348+
349+
target_sources(${n} PRIVATE ${ARM64_OBJS})
350+
target_link_options(${n} PRIVATE /machine:arm64x "${ARM64_DEF}" "${ARM64_LIBS}")
351+
endfunction()
352+
353+
# During the arm64 build, create link.rsp files that containes the absolute path to the inputs passed to the linker (objs, def files, libs).
354+
355+
if("${BUILD_AS_ARM64X}" STREQUAL "ARM64")
356+
add_custom_target(mkdirs ALL COMMAND cmd /c (if not exist \"${arm64ReproDir}/\" mkdir \"${arm64ReproDir}\" ))
357+
foreach (n ${ARM64X_TARGETS})
358+
add_dependencies(${n} mkdirs)
359+
# tell the linker to produce this special rsp file that has absolute paths to its inputs
360+
target_link_options(${n} PRIVATE "/LINKREPROFULLPATHRSP:${arm64ReproDir}/${n}.rsp")
361+
endforeach()
362+
363+
# During the ARM64EC build, modify the link step appropriately to produce an arm64x binary
364+
elseif("${BUILD_AS_ARM64X}" STREQUAL "ARM64EC")
365+
foreach (n ${ARM64X_TARGETS})
366+
set_arm64_dependencies(${n})
367+
endforeach()
368+
endif()
369+
endif()
370+

0 commit comments

Comments
 (0)