Skip to content

Commit 67bd47f

Browse files
committed
Added some support for WIDL - IDL compiler used in free toolchains like Wine SDK, ReactOS SDK and MinGW-w64
Quoted some usage of variables to prevent bugs.
1 parent 6ca44e4 commit 67bd47f

File tree

3 files changed

+132
-44
lines changed

3 files changed

+132
-44
lines changed

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[submodule "cmakeProcessCrashWorkaround"]
2+
path = cmake/thirdparty/cmakeProcessCrashWorkaround
3+
url = https://github.com/KOLANICH/cmakeProcessCrashWorkaround
4+
branch = master

cmake/FindIDL.cmake

Lines changed: 127 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,161 @@
11
# Redistribution and use is allowed under the OSI-approved 3-clause BSD license.
22
# Copyright (c) 2018 Apriorit Inc. All rights reserved.
33

4-
set(IDL_FOUND TRUE)
4+
if(MINGW)
5+
set(COM_IDL_COMPILER_NAME "widl")
6+
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_LIST_DIR}/thirdparty/cmakeProcessCrashWorkaround")
7+
include(cmakeProcessCrashWorkaround)
8+
programCrashWorkaroundInit(widlCrashWorkaround)
9+
else()
10+
set(COM_IDL_COMPILER_NAME "midl")
11+
set(COM_IDL_COMPILER_NAME_PATH_HINTS "C:/Program Files*/Microsoft SDKs/Windows/v*/bin/")
12+
endif()
13+
14+
if(NOT DEFINED COM_IDL_COMPILER_PATH OR NOT CACHE{COM_IDL_COMPILER_PATH})
15+
message(STATUS "Searching for ${COM_IDL_COMPILER_NAME}")
16+
find_program (
17+
COM_IDL_COMPILER_PATH
18+
NAMES "${COM_IDL_COMPILER_NAME}"
19+
HINTS ${COM_IDL_COMPILER_NAME_PATH_HINTS}
20+
DOC "COM IDL compiler executable"
21+
CACHE
22+
REQUIRED
23+
)
24+
set(COM_IDL_COMPILER_PATH "${COM_IDL_COMPILER_PATH}" CACHE FILEPATH "COM IDL compiler executable")
25+
endif()
26+
27+
if(NOT MINGW)
28+
if(NOT DEFINED CACHE{COM_TLB_COMPILER_PATH})
29+
find_program (
30+
COM_TLB_COMPILER_PATH
31+
NAMES "tlbimp"
32+
HINTS ${COM_IDL_COMPILER_NAME_PATH_HINTS}
33+
DOC "COM Type Library compiler executable"
34+
)
35+
set(COM_TLB_COMPILER_PATH "${COM_IDL_COMPILER_PATH}" CACHE FILEPATH "COM Type Library compiler executable")
36+
endif()
37+
endif()
38+
39+
if(NOT COM_IDL_COMPILER_PATH EQUAL "COM_IDL_COMPILER_PATH-NOTFOUND")
40+
set(IDL_COMPILER_FOUND ON)
41+
else()
42+
set(IDL_COMPILER_FOUND OFF)
43+
endif()
44+
if(NOT COM_TLB_COMPILER_PATH EQUAL "COM_TLB_COMPILER_PATH-NOTFOUND")
45+
set(TLB_COMPILER_FOUND ON)
46+
else()
47+
set(TLB_COMPILER_FOUND OFF)
48+
endif()
49+
50+
51+
function(compile_widl_target_lowlevel file2compile outPath includes enableWinRt additionalFlags varForArtifacts varForBaseName)
52+
# may crash for some IDLs, https://bugs.winehq.org/show_bug.cgi?id=49772
53+
get_filename_component(fileDir "${file2compile}" DIRECTORY)
54+
get_filename_component(fileName "${fileName}" NAME)
55+
get_filename_component(fileBaseName "${file2compile}" NAME_WLE)
56+
set(HEADER_NAME "${fileBaseName}.h")
57+
set(TYPE_LIB_NAME "${fileBaseName}.tbl")
58+
set(artifacts "${fileDir}/${HEADER_NAME}" "${fileDir}/${TYPE_LIB_NAME}" "${fileDir}/${fileBaseName}_i.c" "${fileDir}/${fileBaseName}_p.c" "${fileDir}/${fileBaseName}_r.rgs")
59+
file(RELATIVE_PATH idlRelativePath "${CMAKE_CURRENT_BINARY_DIR}" "${file2compile}")
60+
set(argz "")
61+
if(enableWinRt)
62+
list(APPEND argz "--winrt")
63+
endif()
64+
if(includes)
65+
list(JOIN includes ";-I;" otherHeadersDirs)
66+
list(APPEND argz "-I;${otherHeadersDirs}")
67+
endif()
68+
if(outPath)
69+
list(APPEND argz "--output=${outPath}")
70+
endif()
71+
72+
if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4)
73+
set(bitness "32")
74+
else()
75+
set(bitness "64")
76+
endif()
77+
list(APPEND argz "-m${bitness}")
78+
list(APPEND argz "--win${bitness}")
79+
80+
list(APPEND argz "${additionalFlags}")
81+
list(APPEND argz "${file2compile}")
82+
#message(STATUS "argz ${argz}")
83+
add_custom_command(
84+
OUTPUT ${artifacts}
85+
#COMMAND "${COM_IDL_COMPILER_PATH}" ARGS ${argz} # for now, as a workaround for WIDL crashes
86+
COMMAND "$<TARGET_FILE:widlCrashWorkaround>" ARGS "${COM_IDL_COMPILER_PATH}" ${argz}
87+
MAIN_DEPENDENCY "${file2compile}"
88+
DEPENDS "${file2compile}"
89+
WORKING_DIRECTORY "${WDK_IDLS_COMPILED}"
90+
COMMENT "Compiling ${idlRelativePath} with WIDL"
91+
)
92+
set("${varForArtifacts}" "${artifacts}" PARENT_SCOPE)
93+
set("${varForBaseName}" "${fileBaseName}" PARENT_SCOPE)
94+
endfunction()
95+
96+
97+
function(compile_midl_target_lowlevel file2compile outPath includes enableWinRt additionalFlags varForArtifacts varForBaseName)
98+
get_filename_component(IDL_FILE_NAME_WE "${file2compile}" NAME_WE)
99+
set(MIDL_OUTPUT "${IDL_FILE_NAME_WE}_i.h")
100+
add_custom_command(
101+
OUTPUT "${MIDL_OUTPUT}"
102+
COMMAND "${COM_IDL_COMPILER_PATH}" ARGS "/${MIDL_ARCH}" "/env" "${MIDL_ARCH}" "/nologo" "${file2compile}" "/out" "${outPath}" ${additionalFlags} "/h" "${MIDL_OUTPUT}"
103+
DEPENDS "${file2compile}"
104+
VERBATIM
105+
)
106+
endfunction()
5107

6108
function(add_idl _target _idlfile)
7-
get_filename_component(IDL_FILE_NAME_WE ${_idlfile} NAME_WE)
8-
set(MIDL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/Generated)
9-
set(MIDL_OUTPUT ${MIDL_OUTPUT_PATH}/${IDL_FILE_NAME_WE}_i.h)
109+
get_filename_component(IDL_FILE_NAME_WE "${_idlfile}" NAME_WE)
110+
set(MIDL_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/Generated")
111+
set(MIDL_OUTPUT "${MIDL_OUTPUT_PATH}/${IDL_FILE_NAME_WE}_i.h")
10112

11-
if(${CMAKE_SIZEOF_VOID_P} EQUAL 4)
113+
if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4)
12114
set(MIDL_ARCH win32)
13115
else()
14116
set(MIDL_ARCH x64)
15117
endif()
16118

17-
add_custom_command(
18-
OUTPUT ${MIDL_OUTPUT}
19-
COMMAND midl.exe ARGS /${MIDL_ARCH} /env ${MIDL_ARCH} /nologo ${CMAKE_CURRENT_LIST_DIR}/${_idlfile} /out ${MIDL_OUTPUT_PATH} ${MIDL_FLAGS} /h ${MIDL_OUTPUT}
20-
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/${_idlfile}
21-
VERBATIM
22-
)
119+
compile_midl_lowlevel("${_idlfile}" "${MIDL_OUTPUT_PATH}" "" OFF "" varForArtifacts varForBaseName)
23120

24-
set(FINDIDL_TARGET ${_target}_gen)
121+
set(FINDIDL_TARGET "${_target}_gen")
25122

26-
cmake_parse_arguments(FINDIDL "" "TLBIMP" "" ${ARGN})
123+
cmake_parse_arguments(FINDIDL "" "TLBIMP" "" "${ARGN}")
27124

28125
if(FINDIDL_TLBIMP)
29-
file(GLOB TLBIMPv7_FILES "C:/Program Files*/Microsoft SDKs/Windows/v7*/bin/TlbImp.exe")
30-
file(GLOB TLBIMPv8_FILES "C:/Program Files*/Microsoft SDKs/Windows/v8*/bin/*/TlbImp.exe")
31-
file(GLOB TLBIMPv10_FILES "C:/Program Files*/Microsoft SDKs/Windows/v10*/bin/*/TlbImp.exe")
32-
33-
list(APPEND TLBIMP_FILES ${TLBIMPv7_FILES} ${TLBIMPv8_FILES} ${TLBIMPv10_FILES})
34-
35-
if(TLBIMP_FILES)
36-
list(GET TLBIMP_FILES -1 TLBIMP_FILE)
37-
endif()
38-
39-
if (NOT TLBIMP_FILE)
40-
message(FATAL_ERROR "Cannot found tlbimp.exe. Try to download .NET Framework SDK and .NET Framework targeting pack.")
41-
return()
42-
endif()
43-
44-
message(STATUS "Found tlbimp.exe: " ${TLBIMP_FILE})
126+
127+
message(STATUS "Found tlbimp.exe: " "${COM_TLB_COMPILER_PATH}")
45128

46-
set(TLBIMP_OUTPUT_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
129+
set(TLBIMP_OUTPUT_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
47130

48131
if("${TLBIMP_OUTPUT_PATH}" STREQUAL "")
49-
set(TLBIMP_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
132+
set(TLBIMP_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
50133
endif()
51134

52-
set(TLBIMP_OUTPUT ${TLBIMP_OUTPUT_PATH}/${FINDIDL_TLBIMP}.dll)
135+
set(TLBIMP_OUTPUT "${TLBIMP_OUTPUT_PATH}/${FINDIDL_TLBIMP}.dll")
53136

54137
add_custom_command(
55-
OUTPUT ${TLBIMP_OUTPUT}
56-
COMMAND ${TLBIMP_FILE} "${MIDL_OUTPUT_PATH}/${IDL_FILE_NAME_WE}.tlb" "/out:${TLBIMP_OUTPUT}" ${TLBIMP_FLAGS}
57-
DEPENDS ${MIDL_OUTPUT_PATH}/${IDL_FILE_NAME_WE}.tlb
138+
OUTPUT "${TLBIMP_OUTPUT}"
139+
COMMAND "${COM_TLB_COMPILER_PATH}" "${MIDL_OUTPUT_PATH}/${IDL_FILE_NAME_WE}.tlb" "/out:${TLBIMP_OUTPUT}" "${TLBIMP_FLAGS}"
140+
DEPENDS "${MIDL_OUTPUT_PATH}/${IDL_FILE_NAME_WE}.tlb"
58141
VERBATIM
59142
)
60143

61-
add_custom_target(${FINDIDL_TARGET} DEPENDS ${MIDL_OUTPUT} ${TLBIMP_OUTPUT} SOURCES ${_idlfile})
144+
add_custom_target("${FINDIDL_TARGET}" DEPENDS "${MIDL_OUTPUT}" "${TLBIMP_OUTPUT}" SOURCES "${_idlfile}")
62145

63-
add_library(${FINDIDL_TLBIMP} SHARED IMPORTED GLOBAL)
64-
add_dependencies(${FINDIDL_TLBIMP} ${FINDIDL_TARGET})
146+
add_library("${FINDIDL_TLBIMP}" SHARED IMPORTED GLOBAL)
147+
add_dependencies("${FINDIDL_TLBIMP}" "${FINDIDL_TARGET}")
65148

66-
set_target_properties(${FINDIDL_TLBIMP}
149+
set_target_properties("${FINDIDL_TLBIMP}"
67150
PROPERTIES
68151
IMPORTED_LOCATION "${TLBIMP_OUTPUT}"
69152
IMPORTED_COMMON_LANGUAGE_RUNTIME "CSharp"
70153
)
71154
else()
72-
add_custom_target(${FINDIDL_TARGET} DEPENDS ${MIDL_OUTPUT} SOURCES ${_idlfile})
155+
add_custom_target("${FINDIDL_TARGET}" DEPENDS "${MIDL_OUTPUT}" SOURCES "${_idlfile}")
73156
endif()
74157

75-
add_library(${_target} INTERFACE)
76-
add_dependencies(${_target} ${FINDIDL_TARGET})
77-
target_include_directories(${_target} INTERFACE ${MIDL_OUTPUT_PATH})
78-
endfunction()
158+
add_library("${_target}" INTERFACE)
159+
add_dependencies("${_target}" "${FINDIDL_TARGET}")
160+
target_include_directories("${_target}" INTERFACE "${MIDL_OUTPUT_PATH}")
161+
endfunction()

0 commit comments

Comments
 (0)