Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build the WinRTComponent winmd file as a CMake subproject #453

Merged
merged 4 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

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}")
Loading