llvm.org GIT mirror llvm / 7810c44
[cmake] Add support for case-sensitive Windows SDKs When the Windows SDK is hosted on a case-sensitive filesystem (e.g. when compiling on Linux and not using ciopfs), we can automatically generate a VFS overlay for headers and symlinks for libraries. Differential Revision: https://reviews.llvm.org/D41156 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320657 91177308-0d34-0410-b5e6-96231b3b80d8 Shoaib Meenai 1 year, 10 months ago
1 changed file(s) with 77 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
7979 #
8080 # IMPORTANT: In order for this to work, you will need a valid copy of the Windows
8181 # SDK and C++ STL headers and libraries on your host. Additionally, since the
82 # Windows libraries and headers are not case-correct, you will need to have these
83 # mounted in a case-insensitive mount. This requires one command to set up.
84 #
85 # ~/src: mkdir winsdk
86 # ~/src: mkdir winsdk.icase
87 # ~/src: ciopfs winsdk/ winsdk.icase
88 #
89 # Now copy or otherwise install your headers and libraries to the winsdk.icase folder
90 # and use *that* folder as the path when configuring CMake.
91 #
92 # TODO: We could also provide a CMake option -DUSE_ICASE_VFS_OVERLAY=ON/OFF that would
93 # make this optional. For now, we require ciopfs.
82 # Windows libraries and headers are not case-correct, this toolchain file sets
83 # up a VFS overlay for the SDK headers and case-correcting symlinks for the
84 # libraries when running on a case-sensitive filesystem.
9485
9586
9687 # When configuring CMake with a toolchain file against a top-level CMakeLists.txt,
109100 endif()
110101 endfunction()
111102
103 function(generate_winsdk_vfs_overlay winsdk_include_dir output_path)
104 set(include_dirs)
105 file(GLOB_RECURSE entries LIST_DIRECTORIES true "${winsdk_include_dir}/*")
106 foreach(entry ${entries})
107 if(IS_DIRECTORY "${entry}")
108 list(APPEND include_dirs "${entry}")
109 endif()
110 endforeach()
111
112 file(WRITE "${output_path}" "version: 0\n")
113 file(APPEND "${output_path}" "case-sensitive: false\n")
114 file(APPEND "${output_path}" "roots:\n")
115
116 foreach(dir ${include_dirs})
117 file(GLOB headers RELATIVE "${dir}" "${dir}/*.h")
118 if(NOT headers)
119 continue()
120 endif()
121
122 file(APPEND "${output_path}" " - name: \"${dir}\"\n")
123 file(APPEND "${output_path}" " type: directory\n")
124 file(APPEND "${output_path}" " contents:\n")
125
126 foreach(header ${headers})
127 file(APPEND "${output_path}" " - name: \"${header}\"\n")
128 file(APPEND "${output_path}" " type: file\n")
129 file(APPEND "${output_path}" " external-contents: \"${dir}/${header}\"\n")
130 endforeach()
131 endforeach()
132 endfunction()
133
134 function(generate_winsdk_lib_symlinks winsdk_um_lib_dir output_dir)
135 execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${output_dir}")
136 file(GLOB libraries RELATIVE "${winsdk_um_lib_dir}" "${winsdk_um_lib_dir}/*")
137 foreach(library ${libraries})
138 string(TOLOWER "${library}" symlink_name)
139 execute_process(COMMAND "${CMAKE_COMMAND}"
140 -E create_symlink
141 "${winsdk_um_lib_dir}/${library}"
142 "${output_dir}/${symlink_name}")
143 endforeach()
144 endfunction()
145
112146 set(CMAKE_SYSTEM_NAME Windows)
113147 set(CMAKE_SYSTEM_VERSION 10.0)
114148 set(CMAKE_SYSTEM_PROCESSOR AMD64)
169203 "Windows SDK installation")
170204 endif()
171205
206 if(NOT EXISTS "${WINSDK_INCLUDE}/um/Windows.h")
207 message(SEND_ERROR "Cannot find Windows.h")
208 endif()
209 if(NOT EXISTS "${WINSDK_INCLUDE}/um/WINDOWS.H")
210 set(case_sensitive_filesystem TRUE)
211 endif()
212
172213 set(CMAKE_C_COMPILER "${LLVM_NATIVE_TOOLCHAIN}/bin/clang-cl" CACHE FILEPATH "")
173214 set(CMAKE_CXX_COMPILER "${LLVM_NATIVE_TOOLCHAIN}/bin/clang-cl" CACHE FILEPATH "")
174215 set(CMAKE_LINKER "${LLVM_NATIVE_TOOLCHAIN}/bin/lld-link" CACHE FILEPATH "")
194235 -imsvc "${WINSDK_INCLUDE}/um"
195236 -imsvc "${WINSDK_INCLUDE}/winrt")
196237
238 if(case_sensitive_filesystem)
239 # Ensure all sub-configures use the top-level VFS overlay instead of generating their own.
240 init_user_prop(winsdk_vfs_overlay_path)
241 if(NOT winsdk_vfs_overlay_path)
242 set(winsdk_vfs_overlay_path "${CMAKE_BINARY_DIR}/winsdk_vfs_overlay.yaml")
243 generate_winsdk_vfs_overlay("${WINSDK_BASE}/Include/${WINSDK_VER}" "${winsdk_vfs_overlay_path}")
244 init_user_prop(winsdk_vfs_overlay_path)
245 endif()
246 list(APPEND COMPILE_FLAGS
247 -Xclang -ivfsoverlay -Xclang "${winsdk_vfs_overlay_path}")
248 endif()
249
197250 string(REPLACE ";" " " COMPILE_FLAGS "${COMPILE_FLAGS}")
198251
199252 # We need to preserve any flags that were passed in by the user. However, we
216269 -libpath:"${WINSDK_LIB}/ucrt/${WINSDK_ARCH}"
217270 -libpath:"${WINSDK_LIB}/um/${WINSDK_ARCH}")
218271
272 if(case_sensitive_filesystem)
273 # Ensure all sub-configures use the top-level symlinks dir instead of generating their own.
274 init_user_prop(winsdk_lib_symlinks_dir)
275 if(NOT winsdk_lib_symlinks_dir)
276 set(winsdk_lib_symlinks_dir "${CMAKE_BINARY_DIR}/winsdk_lib_symlinks")
277 generate_winsdk_lib_symlinks("${WINSDK_BASE}/Lib/${WINSDK_VER}/um/${WINSDK_ARCH}" "${winsdk_lib_symlinks_dir}")
278 init_user_prop(winsdk_lib_symlinks_dir)
279 endif()
280 list(APPEND LINK_FLAGS
281 -libpath:"${winsdk_lib_symlinks_dir}")
282 endif()
283
219284 string(REPLACE ";" " " LINK_FLAGS "${LINK_FLAGS}")
220285
221286 # See explanation for compiler flags above for the _INITIAL variables.