1+ if (CMAKE_VERSION VERSION_LESS "3.31.0" )
2+ message (FATAL_ERROR "CMake version must be at least 3.31.0 to use this toolchain file!" )
3+ endif ()
4+
5+ if (NOT CMAKE_GENERATOR MATCHES "Ninja*" )
6+ message (FATAL_ERROR "CMAKE_GENERATOR = \" ${CMAKE_GENERATOR} \" is unsupported, use Ninja (single or multi config) generators!" )
7+ endif ()
8+
9+ # https://cmake.org/cmake/help/v3.31/variable/CMAKE_GENERATOR_INSTANCE.html#visual-studio-instance-selection
10+ cmake_path(CONVERT $ENV{VS_INSTANCE_LOCATION} TO_CMAKE_PATH_LIST VS_INSTANCE_LOCATION NORMALIZE)
11+ cmake_path(CONVERT $ENV{CMAKE_WINDOWS_KITS_10_DIR} TO_CMAKE_PATH_LIST WINDOWS_KITS_10_DIR NORMALIZE)
12+ cmake_path(CONVERT $ENV{WINDOWS_SDK_VERSION} TO_CMAKE_PATH_LIST WINDOWS_SDK_VERSION NORMALIZE)
13+ cmake_path(CONVERT $ENV{MSVC_TOOLSET_DIR} TO_CMAKE_PATH_LIST MSVC_TOOLSET_DIR NORMALIZE)
14+ cmake_path(CONVERT $ENV{LLVM_TOOLSET_DIR} TO_CMAKE_PATH_LIST LLVM_TOOLSET_DIR NORMALIZE)
15+
16+ message (STATUS "VS_INSTANCE_LOCATION = \" ${VS_INSTANCE_LOCATION} \" " )
17+ message (STATUS "WINDOWS_KITS_10_DIR = \" ${WINDOWS_KITS_10_DIR} \" " )
18+ message (STATUS "WINDOWS_SDK_VERSION = \" ${WINDOWS_SDK_VERSION} \" " )
19+ message (STATUS "MSVC_TOOLSET_DIR = \" ${MSVC_TOOLSET_DIR} \" " )
20+ message (STATUS "LLVM_TOOLSET_DIR = \" ${LLVM_TOOLSET_DIR} \" " )
21+
22+ if (NOT EXISTS "${VS_INSTANCE_LOCATION} " )
23+ message ("VS_INSTANCE_LOCATION is invalid!" )
24+ endif ()
25+
26+ macro (IS_WITHIN_VC_LOCATION VAR)
27+ string (FIND "${${VAR} }" "${VS_INSTANCE_LOCATION} " FOUND)
28+ if ("${FOUND} " MATCHES "-1" )
29+ message (FATAL_ERROR "${VAR} is not within VS_INSTANCE_LOCATION, did you move the toolset directory outside the VS installation?" )
30+ endif ()
31+ endmacro ()
32+
33+ IS_WITHIN_VC_LOCATION(MSVC_TOOLSET_DIR)
34+ IS_WITHIN_VC_LOCATION(LLVM_TOOLSET_DIR)
35+
36+ set (CMAKE_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR} )
37+
38+ if (ARCH)
39+ if (ARCH MATCHES "x64" )
40+ elseif (ARCH MATCHES "arm64" )
41+ set (CMAKE_SYSTEM_NAME Windows)
42+ set (CMAKE_SYSTEM_PROCESSOR arm64)
43+ # never tested it but I'm pretty sure _COMPILER needs to be updated depending on target ARCH
44+ message (FATAL_ERROR "TODO, Cross compilation requires ARM64 build tools compoment and updates to the toolchain file!" )
45+ else ()
46+ message (STATUS "Unsupported ARCH = \" ${ARCH} \" " )
47+ message (FATAL_ERROR "Supported ARCH = \" x64\" , \" arm64\" " )
48+ endif ()
49+ else ()
50+ set (ARCH x64)
51+ endif ()
52+
53+ set (LIB
54+ "${WINDOWS_KITS_10_DIR} /Lib/${WINDOWS_SDK_VERSION} /ucrt/${ARCH} "
55+ "${WINDOWS_KITS_10_DIR} /Lib/${WINDOWS_SDK_VERSION} /um/${ARCH} "
56+ "${MSVC_TOOLSET_DIR} /lib/${ARCH} "
57+ "${MSVC_TOOLSET_DIR} /atlmfc/lib/${ARCH} "
58+ )
59+
60+ set (INCLUDE
61+ "${WINDOWS_KITS_10_DIR} /Include/${WINDOWS_SDK_VERSION} /winrt"
62+ "${WINDOWS_KITS_10_DIR} /Include/${WINDOWS_SDK_VERSION} /cppwinrt"
63+ "${WINDOWS_KITS_10_DIR} /Include/${WINDOWS_SDK_VERSION} /shared"
64+ "${WINDOWS_KITS_10_DIR} /Include/${WINDOWS_SDK_VERSION} /ucrt"
65+ "${WINDOWS_KITS_10_DIR} /Include/${WINDOWS_SDK_VERSION} /um"
66+ "${MSVC_TOOLSET_DIR} /include"
67+ "${MSVC_TOOLSET_DIR} /atlmfc/include"
68+ )
69+
70+ set (ENV{LIB} "${LIB} " )
71+ set (ENV{INCLUDE } "${INCLUDE} " )
72+
73+ function (_VALIDATE_ENV_V_ ENVN)
74+ list (APPEND TO_VALIDATE $ENV{${ENVN} })
75+ foreach (EPATH IN LISTS TO_VALIDATE)
76+ if (NOT EXISTS "${EPATH} " )
77+ message (FATAL_ERROR "Validation failed for ${ENVN} ENV. PATH = \" ${EPATH} \" doesn't exist!" )
78+ endif ()
79+ endforeach ()
80+ endfunction ()
81+
82+ _VALIDATE_ENV_V_(LIB)
83+ _VALIDATE_ENV_V_(INCLUDE )
84+
85+ macro (_UPDATE_STANDARD_DIRECTORIES_ WHAT VARV)
86+ set (CMAKE_C_STANDARD_${WHAT} _DIRECTORIES ${VARV} CACHE FILEPATH "" )
87+ set (CMAKE_CXX_STANDARD_${WHAT} _DIRECTORIES ${VARV} CACHE FILEPATH "" )
88+ set (CMAKE_RC_STANDARD_${WHAT} _DIRECTORIES ${VARV} CACHE FILEPATH "" )
89+ set (CMAKE_ASM_STANDARD_${WHAT} _DIRECTORIES ${VARV} CACHE FILEPATH "" )
90+ set (CMAKE_NASM_STANDARD_${WHAT} _DIRECTORIES ${VARV} CACHE FILEPATH "" )
91+ set (CMAKE_MASM_STANDARD_${WHAT} _DIRECTORIES ${VARV} CACHE FILEPATH "" )
92+ endmacro ()
93+
94+ _UPDATE_STANDARD_DIRECTORIES_(INCLUDE "${INCLUDE} " )
95+ _UPDATE_STANDARD_DIRECTORIES_(LINK "${LIB} " )
96+
97+ set (CMAKE_EXPORT_COMPILE_COMMANDS TRUE )
98+
99+ # extensions
100+ # TODO: could use vswhere.exe with component IDs
101+ macro (_REQUEST_EXTENSION_ WHAT HINT)
102+ if (EXISTS "${HINT} " )
103+ set (${WHAT} "${HINT} " )
104+ message (STATUS "WITH ${WHAT} = \" ${HINT} \" " )
105+ endif ()
106+ endmacro ()
107+
108+ _REQUEST_EXTENSION_(DIASDK_INCLUDE_DIR "${VS_INSTANCE_LOCATION} /DIA SDK/include" )
109+
110+ # redists
111+ function (_REQUEST_REDIST_MODULES BASE OUTPUT )
112+ if (NOT EXISTS "${BASE} " )
113+ message (FATAL_ERROR "Internal error, base \" ${BASE} \" for redist module search directories doesn't exist - is your build tools installation corrupted?" )
114+ endif ()
115+
116+ file (GLOB_RECURSE _MODULES LIST_DIRECTORIES false "${BASE} /*.dll" )
117+
118+ set (_DIRS)
119+ foreach (f IN LISTS _MODULES)
120+ get_filename_component (d "${f} " DIRECTORY )
121+ list (APPEND _DIRS "${d} " )
122+ endforeach ()
123+
124+ list (REMOVE_DUPLICATES _DIRS)
125+
126+ set (${OUTPUT} "${_DIRS} " )
127+
128+ if (NOT ${OUTPUT} )
129+ message (FATAL_ERROR "Internal error, no redist module search directories found (CRTs) - is your build tools installation corrupted?" )
130+ endif ()
131+
132+ set (${OUTPUT} "${${OUTPUT} }" PARENT_SCOPE)
133+ endfunction ()
134+
135+ cmake_path(GET MSVC_TOOLSET_DIR FILENAME VER)
136+
137+ set (REDISTS "${VS_INSTANCE_LOCATION} /VC/Redist/MSVC" )
138+ string (REGEX REPLACE "^([0-9]+)\\ ..*" "\\ 1" REDISTS_TARGET_MAJOR "${VER} " )
139+ file (GLOB REDISTS_VERSIONS RELATIVE "${REDISTS} " "${REDISTS} /${REDISTS_TARGET_MAJOR} .*" )
140+
141+ if (NOT REDISTS_VERSIONS)
142+ message (FATAL_ERROR "No ${REDISTS_TARGET_MAJOR} .x Redists found at \" ${REDISTS} \" !" )
143+ endif ()
144+
145+ # current policy - pick latest redists since its backwards compatible
146+ # note: toolset version is not guaranteed to match 1:1 redists versioning
147+ list (GET REDISTS_VERSIONS 0 VER)
148+ foreach (IT ${REDISTS_VERSIONS} )
149+ if (IT VERSION_GREATER VER)
150+ set (VER ${IT} )
151+ endif ()
152+ endforeach ()
153+
154+ cmake_path(CONVERT "${VS_INSTANCE_LOCATION} /VC/Redist/MSVC/${VER} " TO_CMAKE_PATH_LIST MSVC_REDIST_BASE NORMALIZE)
155+ _REQUEST_REDIST_MODULES("${MSVC_REDIST_BASE} /${ARCH} " RELEASE_REDISTS)
156+ _REQUEST_REDIST_MODULES("${MSVC_REDIST_BASE} /debug_nonredist/${ARCH} " DEBUG_REDISTS)
157+ set (MSVC_REDIST_MODULE_DIRECTORIES "${RELEASE_REDISTS} ;${DEBUG_REDISTS} " CACHE FILEPATH "MSVC Redist module search directories" )
158+
159+ set (UCRTBASED_DLL_DIR "${WINDOWS_KITS_10_DIR} /bin/${WINDOWS_SDK_VERSION} /${ARCH} /ucrt" CACHE FILEPATH "Debug C++ Runtime DLL directory" )
160+ find_file (UCRTBASED_DLL_PATH NAMES ucrtbased.dll HINTS "${UCRTBASED_DLL_DIR} " REQUIRED)
161+
162+ set (BUILD_MODULE_SEARCH_DIRS
163+ ${MSVC_REDIST_MODULE_DIRECTORIES}
164+ ${UCRTBASED_DLL_DIR}
165+ )
166+
167+ # launchers
168+ if (WIN32 )
169+ set (SHELL_LAUNCHER "cmd /C" )
170+ else ()
171+ set (SHELL_LAUNCHER "sh -c" )
172+ endif ()
173+
174+ set_property (GLOBAL PROPERTY RULE_LAUNCH_CUSTOM
175+ "${CMAKE_COMMAND} -E env --modify PATH=path_list_prepend:${BUILD_MODULE_SEARCH_DIRS} -- ${SHELL_LAUNCHER} "
176+ )
177+
178+ # NASM
179+ find_program (CMAKE_ASM_NASM_COMPILER nasm HINTS ENV PATH ENV NASM_DIR NO_CACHE REQUIRED)
180+ set (CMAKE_ASM_NASM_COMPILER "${CMAKE_ASM_NASM_COMPILER} " CACHE FILEPATH "" )
181+
182+ # BINs
183+ set (CL_BIN "${MSVC_TOOLSET_DIR} /bin/Host${ARCH} /${ARCH} " )
184+ set (CLANGCL_BIN "${LLVM_TOOLSET_DIR} /${ARCH} /bin" )
185+ set (WIN_SDK_BIN "${WINDOWS_KITS_10_DIR} /bin/${WINDOWS_SDK_VERSION} /${ARCH} " )
0 commit comments