master
cmake 129 lines 4.98 KB
Raw
1 function(add_idl target idl_files_with_proxy idl_files_no_proxy)
2 set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE})
3 file(MAKE_DIRECTORY ${OUTPUT_DIR})
4 set(TARGET_OUTPUTS)
5
6 set(IDL_DEFINITIONS "")
7
8 get_directory_property(IDL_DEFS COMPILE_DEFINITIONS )
9 foreach(e ${IDL_DEFS})
10 set(IDL_DEFINITIONS ${IDL_DEFINITIONS} /D${e})
11 endforeach()
12
13 string(TOLOWER ${TARGET_PLATFORM} IDL_ENV)
14 set(PREVIOUS_OUTPUT "")
15
16 set(IDL_DLLDATA ${OUTPUT_DIR}/dlldata_${TARGET_PLATFORM}.c)
17
18 list(LENGTH idl_files_with_proxy PROXY_IDL_COUNT)
19 set(PROXY_IDL_INDEX 0)
20
21 foreach(idl_file ${idl_files_with_proxy})
22
23 cmake_path(GET idl_file STEM IDL_NAME)
24
25 set(IDL_HEADER ${OUTPUT_DIR}/${IDL_NAME}.h)
26
27 # Adding a _${TARGET_PLATFORM} to work around object files having
28 # the same paths regardless of TARGET_PLATFORM, which can cause the linker to fail with:
29 # "fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'ARM64'"
30 set(IDL_I ${OUTPUT_DIR}/${IDL_NAME}_i_${TARGET_PLATFORM}.c)
31 set(IDL_P ${OUTPUT_DIR}/${IDL_NAME}_p_${TARGET_PLATFORM}.c)
32
33 # Only list dlldata as a tracked output of the last MIDL command.
34 math(EXPR PROXY_IDL_INDEX "${PROXY_IDL_INDEX} + 1")
35 if(PROXY_IDL_INDEX EQUAL PROXY_IDL_COUNT)
36 set(MIDL_OUTPUT ${IDL_HEADER} ${IDL_I} ${IDL_P} ${IDL_DLLDATA})
37 else()
38 set(MIDL_OUTPUT ${IDL_HEADER} ${IDL_I} ${IDL_P})
39 endif()
40
41 add_custom_command(
42 OUTPUT ${MIDL_OUTPUT}
43 COMMAND midl /nologo /target NT100 /env "${IDL_ENV}" /Zp8 /char unsigned /ms_ext /c_ext /h ${IDL_HEADER} /iid ${IDL_I} /proxy ${IDL_P} /dlldata ${IDL_DLLDATA} ${idl_file} ${IDL_DEFINITIONS}
44 WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
45 DEPENDS ${idl_file} ${PREVIOUS_OUTPUT}
46 MAIN_DEPENDENCY ${idl_file}
47 VERBATIM
48 )
49
50 set(PREVIOUS_OUTPUT ${IDL_HEADER})
51
52 set_source_files_properties(${MIDL_OUTPUT} PROPERTIES GENERATED TRUE)
53 list(APPEND TARGET_OUTPUTS ${MIDL_OUTPUT})
54
55 endforeach()
56
57 foreach(idl_file ${idl_files_no_proxy})
58
59 cmake_path(GET idl_file STEM IDL_NAME)
60
61 set(IDL_HEADER ${OUTPUT_DIR}/${IDL_NAME}.h)
62
63 add_custom_command(
64 OUTPUT ${IDL_HEADER}
65 COMMAND midl /nologo /target NT100 /env "${IDL_ENV}" /Zp8 /char unsigned /ms_ext /c_ext /h ${IDL_HEADER} /iid nul /proxy nul /dlldata nul ${idl_file} ${IDL_DEFINITIONS}
66 WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
67 DEPENDS ${idl_file}
68 MAIN_DEPENDENCY ${idl_file}
69 VERBATIM
70 )
71
72 set_source_files_properties(${IDL_HEADER} PROPERTIES GENERATED TRUE)
73 list(APPEND TARGET_OUTPUTS ${IDL_HEADER})
74
75 endforeach()
76
77 # Touch the stamp file so Visual Studio's incremental build can track the
78 # target as up-to-date.
79 add_custom_target(${target}
80 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}
81 DEPENDS ${TARGET_OUTPUTS}
82 SOURCES ${idl_files_with_proxy} ${idl_files_no_proxy})
83
84 endfunction()
85
86 function(add_idl_winrt target idl_file)
87 set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE})
88 file(TO_NATIVE_PATH ${OUTPUT_DIR} OUTPUT_DIR) # midl is picky about path formats
89 file(MAKE_DIRECTORY ${OUTPUT_DIR})
90
91 set(IDL_DEFINITIONS "")
92
93 get_directory_property(IDL_DEFS COMPILE_DEFINITIONS )
94 foreach(e ${IDL_DEFS})
95 set(IDL_DEFINITIONS ${IDL_DEFINITIONS} /D${e})
96 endforeach()
97
98 string(TOLOWER ${TARGET_PLATFORM} IDL_ENV)
99
100 cmake_host_system_information(
101 RESULT WINDOWS_SDK_DIR
102 QUERY WINDOWS_REGISTRY "HKLM/SOFTWARE/Microsoft/Windows Kits/Installed Roots"
103 VALUE "KitsRoot10")
104 set(WINRT_METADATA_DIR "${WINDOWS_SDK_DIR}\\UnionMetadata\\${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
105 set(WINRT_REFERENCE "${WINRT_METADATA_DIR}\\Windows.winmd")
106 set(WINRT_INCLUDE "${WINDOWS_SDK_DIR}\\Include\\${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}\\winrt")
107
108 cmake_path(GET idl_file STEM IDL_NAME)
109
110 set(IDL_WINMD ${OUTPUT_DIR}/${IDL_NAME}.winmd)
111
112 add_custom_command(
113 OUTPUT ${IDL_WINMD}
114 COMMAND midl /nologo /nomidl /winrt /metadata_dir "${WINRT_METADATA_DIR}" /reference "${WINRT_REFERENCE}" /I "${WINRT_INCLUDE}" /env "${IDL_ENV}" /h nul /winmd ${IDL_WINMD} ${idl_file} ${IDL_DEFINITIONS}
115 COMMAND cppwinrt -input ${IDL_WINMD} -reference "${WINRT_REFERENCE}" -output ${OUTPUT_DIR} -comp ${OUTPUT_DIR}/implementation_base -optimize -pch precomp.h -prefix
116 WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
117 DEPENDS ${idl_file}
118 MAIN_DEPENDENCY ${idl_file}
119 VERBATIM
120 )
121
122 set_source_files_properties(${IDL_WINMD} PROPERTIES GENERATED TRUE)
123
124 add_custom_target(${target}
125 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}
126 DEPENDS ${IDL_WINMD}
127 SOURCES ${idl_file})
128
129 endfunction()