Skip to content

Commit

Permalink
Build the WinRTComponent winmd file as a CMake subproject (#453)
Browse files Browse the repository at this point in the history
  • Loading branch information
tristanlabelle authored Dec 30, 2024
1 parent 751465a commit a5da873
Show file tree
Hide file tree
Showing 40 changed files with 74 additions and 117 deletions.
1 change: 0 additions & 1 deletion InteropTests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Support using this directory as a standalone project or as a subdirectory.
if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
cmake_minimum_required(VERSION 3.21.0)

project(InteropTests LANGUAGES C Swift)
endif()

Expand Down
2 changes: 1 addition & 1 deletion InteropTests/SPMPrebuild.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ switch ($SwiftBug72724) {
default {}
}
& cmake.exe --preset $CMakePreset @Defines
& cmake.exe --build --preset $CMakePreset --target WinRTComponent
& cmake.exe --build --preset $CMakePreset --target WinRTComponentDll
$WinRTComponentBinDir = "$(Get-Location)\build\$CMakePreset\Dll"
Pop-Location

Expand Down
23 changes: 12 additions & 11 deletions InteropTests/WinRTComponent/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ if(NOT DEFINED PROJECTION_DIR)
endif()

# Generate the WinRTComponent.winmd file
set(WINRTCOMPONENT_WINMD "${CMAKE_CURRENT_BINARY_DIR}/WinRTComponent.winmd")
include(GenerateWinMD.cmake)
generate_winrtcomponent_winmd(
IDL "${CMAKE_CURRENT_SOURCE_DIR}/IDL/WinRTComponent.idl"
WINMD "${WINRTCOMPONENT_WINMD}")

# Copy the documentation xml file next to it
message(STATUS "Building WinRTComponent.winmd as a subproject...")
execute_process(
COMMAND ${CMAKE_COMMAND}
-S "${CMAKE_CURRENT_SOURCE_DIR}/WinMD"
-B "${CMAKE_CURRENT_BINARY_DIR}/WinMD"
-G "${CMAKE_GENERATOR}"
COMMAND_ERROR_IS_FATAL ANY)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_SOURCE_DIR}/WinRTComponent.xml"
"${CMAKE_CURRENT_BINARY_DIR}/"
COMMAND ${CMAKE_COMMAND} --build "${CMAKE_CURRENT_BINARY_DIR}/WinMD"
COMMAND_ERROR_IS_FATAL ANY)

set(WINRTCOMPONENT_WINMD "${CMAKE_CURRENT_BINARY_DIR}/WinMD/WinRTComponent.winmd")

# Generate Swift projection
message(STATUS "Generating Swift projection for WinRTComponent...")
include(GenerateProjection.cmake)
Expand All @@ -38,10 +38,11 @@ generate_projection(

# Define the dll build (requires cl.exe)
include(ExternalProject)
ExternalProject_Add(WinRTComponent
ExternalProject_Add(WinRTComponentDll
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Dll"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/Dll"
CMAKE_ARGS
-D "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
-D "WINRTCOMPONENT_WINMD=${WINRTCOMPONENT_WINMD}"
-D "CMAKE_CXX_COMPILER=cl.exe"
-D "CMAKE_CXX_FLAGS=/std:c++latest /W4 /EHsc"
Expand Down
19 changes: 0 additions & 19 deletions InteropTests/WinRTComponent/Clear-PEDateTimeStamp.ps1

This file was deleted.

52 changes: 0 additions & 52 deletions InteropTests/WinRTComponent/GenerateWinMD.cmake

This file was deleted.

33 changes: 0 additions & 33 deletions InteropTests/WinRTComponent/IDL/WinRTComponent.idl

This file was deleted.

File renamed without changes.
61 changes: 61 additions & 0 deletions InteropTests/WinRTComponent/WinMD/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Support using this directory as a standalone project or as a subdirectory.
if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
cmake_minimum_required(VERSION 3.21.0)
project(WinMD LANGUAGES NONE)
endif()

# Locate files we need from the Windows SDK
if("$ENV{VSCMD_ARG_HOST_ARCH}" STREQUAL "" OR "$ENV{WindowsSdkDir}" STREQUAL "" OR "$ENV{WindowsSDKVersion}" STREQUAL "")
message(FATAL_ERROR "CMake should be called within a VS developer command prompt.")
endif()

cmake_path(CONVERT "$ENV{WindowsSdkDir}References\\$ENV{WindowsSDKVersion}" TO_CMAKE_PATH_LIST WINSDK_REFERENCES_DIR NORMALIZE)

file(GLOB FOUNDATIONCONTRACT_WINMD "${WINSDK_REFERENCES_DIR}/Windows.Foundation.FoundationContract/*/Windows.Foundation.FoundationContract.winmd")
if("${FOUNDATIONCONTRACT_WINMD}" STREQUAL "" OR "${FOUNDATIONCONTRACT_WINMD}" MATCHES ";")
message(FATAL_ERROR "Zero or multiple Windows.Foundation.FoundationContract assemblies found under ${WINSDK_REFERENCES_DIR}")
endif()
cmake_path(GET FOUNDATIONCONTRACT_WINMD PARENT_PATH FOUNDATIONCONTRACT_DIR)

file(GLOB UNIVERSALAPICONTRACT_WINMD "${WINSDK_REFERENCES_DIR}/Windows.Foundation.UniversalApiContract/*/Windows.Foundation.UniversalApiContract.winmd")
if("${UNIVERSALAPICONTRACT_WINMD}" STREQUAL "" OR "${UNIVERSALAPICONTRACT_WINMD}" MATCHES ";")
message(FATAL_ERROR "Zero or multiple Windows.Foundation.UniversalApiContract assemblies found under ${WINSDK_REFERENCES_DIR}")
endif()

cmake_path(CONVERT "$ENV{WindowsSdkVerBinPath}$ENV{VSCMD_ARG_HOST_ARCH}\\midlrt.exe" TO_CMAKE_PATH_LIST MIDLRT_EXE NORMALIZE)

# Generate a single idl source file that includes all idl files in the directory.
set(IDL_SOURCE "${CMAKE_CURRENT_BINARY_DIR}/WinRTComponent.idl")
file(GLOB IDL_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.idl")
set(IDL_SOURCE_CODE "")
foreach(IDL_SOURCE_FILE IN LISTS IDL_SOURCE_FILES)
set(IDL_SOURCE_CODE "${IDL_SOURCE_CODE}#include \"${IDL_SOURCE_FILE}\"\n")
endforeach()
file(WRITE "${IDL_SOURCE}" "${IDL_SOURCE_CODE}")

set(OUTPUT_WINMD "${CMAKE_CURRENT_BINARY_DIR}/WinRTComponent.winmd")
set(OUTPUT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/WinRTComponent.h")
set(OUTPUT_XMLDOCS "${CMAKE_CURRENT_BINARY_DIR}/WinRTComponent.xml")

# Generate the WinMD
add_custom_command(
OUTPUT "${OUTPUT_WINMD}" "${OUTPUT_HEADER}"
DEPENDS ${IDL_SOURCES} ${FOUNDATIONCONTRACT_WINMD} ${UNIVERSALAPICONTRACT_WINMD}
COMMAND "$<SHELL_PATH:${MIDLRT_EXE}>"
/W1 /nologo /nomidl
/metadata_dir "$<SHELL_PATH:${FOUNDATIONCONTRACT_DIR}>"
/reference "$<SHELL_PATH:${FOUNDATIONCONTRACT_WINMD}>"
/reference "$<SHELL_PATH:${UNIVERSALAPICONTRACT_WINMD}>"
/winmd "$<SHELL_PATH:${OUTPUT_WINMD}>"
/header "$<SHELL_PATH:${OUTPUT_HEADER}>"
"$<SHELL_PATH:${IDL_SOURCE}>")

add_custom_command(
OUTPUT "${OUTPUT_XMLDOCS}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/WinRTComponent.xml"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_SOURCE_DIR}/WinRTComponent.xml"
"${OUTPUT_XMLDOCS}")

add_custom_target(WinRTComponentWinMD ALL
DEPENDS "${OUTPUT_WINMD}" "${OUTPUT_HEADER}" "${OUTPUT_XMLDOCS}")
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit a5da873

Please sign in to comment.