CMakeLists.txt 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. # Copyright (c) 2015-2023 The Khronos Group Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. cmake_minimum_required(VERSION 3.22.1)
  15. project(spirv-tools)
  16. # Avoid a bug in CMake 3.22.1. By default it will set -std=c++11 for
  17. # targets in test/*, when those tests need -std=c++17.
  18. # https://github.com/KhronosGroup/SPIRV-Tools/issues/5340
  19. # The bug is fixed in CMake 3.22.2
  20. if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.22.1")
  21. if (${CMAKE_VERSION} VERSION_LESS "3.22.2")
  22. cmake_policy(SET CMP0128 NEW)
  23. endif()
  24. endif()
  25. set_property(GLOBAL PROPERTY USE_FOLDERS ON)
  26. enable_testing()
  27. set(SPIRV_TOOLS "SPIRV-Tools")
  28. include(GNUInstallDirs)
  29. set(CMAKE_POSITION_INDEPENDENT_CODE ON)
  30. # Require at least C++17
  31. if(NOT CMAKE_CXX_STANDARD)
  32. set(CMAKE_CXX_STANDARD 17)
  33. endif()
  34. if(${CMAKE_CXX_STANDARD} LESS 17)
  35. message(FATAL_ERROR "SPIRV-Tools requires C++17 or later, but is configured for C++${CMAKE_CXX_STANDARD})")
  36. endif()
  37. set(CMAKE_CXX_EXTENSIONS OFF)
  38. option(ENABLE_RTTI "Enables RTTI" OFF)
  39. option(SPIRV_ALLOW_TIMERS "Allow timers via clock_gettime on supported platforms" ON)
  40. if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
  41. set(SPIRV_TIMER_ENABLED ${SPIRV_ALLOW_TIMERS})
  42. elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
  43. add_definitions(-DSPIRV_WINDOWS)
  44. elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
  45. add_definitions(-DSPIRV_WINDOWS)
  46. elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
  47. set(SPIRV_TIMER_ENABLED ${SPIRV_ALLOW_TIMERS})
  48. endif()
  49. if (${SPIRV_TIMER_ENABLED})
  50. add_definitions(-DSPIRV_TIMER_ENABLED)
  51. endif()
  52. if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
  53. message(STATUS "No build type selected, default to Debug")
  54. set(CMAKE_BUILD_TYPE "Debug")
  55. endif()
  56. option(SKIP_SPIRV_TOOLS_INSTALL "Skip installation" ${SKIP_SPIRV_TOOLS_INSTALL})
  57. if(NOT ${SKIP_SPIRV_TOOLS_INSTALL})
  58. set(ENABLE_SPIRV_TOOLS_INSTALL ON)
  59. endif()
  60. option(SPIRV_BUILD_COMPRESSION "Build SPIR-V compressing codec" OFF)
  61. if(SPIRV_BUILD_COMPRESSION)
  62. message(FATAL_ERROR "SPIR-V compression codec has been removed from SPIR-V tools. "
  63. "Please remove SPIRV_BUILD_COMPRESSION from your build options.")
  64. endif(SPIRV_BUILD_COMPRESSION)
  65. option(SPIRV_BUILD_FUZZER "Build spirv-fuzz" OFF)
  66. set(SPIRV_LIB_FUZZING_ENGINE_LINK_OPTIONS "" CACHE STRING "Used by OSS-Fuzz to control, via link options, which fuzzing engine should be used")
  67. option(SPIRV_BUILD_LIBFUZZER_TARGETS "Build libFuzzer targets" OFF)
  68. option(SPIRV_WERROR "Enable error on warning" ON)
  69. if(("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") AND (NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")))
  70. set(COMPILER_IS_LIKE_GNU TRUE)
  71. endif()
  72. if(${COMPILER_IS_LIKE_GNU})
  73. set(SPIRV_WARNINGS -Wall -Wextra -Wnon-virtual-dtor -Wno-missing-field-initializers)
  74. if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  75. set(SPIRV_WARNINGS ${SPIRV_WARNINGS} -Wno-self-assign)
  76. endif()
  77. option(SPIRV_WARN_EVERYTHING "Enable -Weverything" ${SPIRV_WARN_EVERYTHING})
  78. if(${SPIRV_WARN_EVERYTHING})
  79. if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
  80. set(SPIRV_WARNINGS ${SPIRV_WARNINGS}
  81. -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded)
  82. elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  83. set(SPIRV_WARNINGS ${SPIRV_WARNINGS} -Wpedantic -pedantic-errors)
  84. else()
  85. message(STATUS "Unknown compiler ${CMAKE_CXX_COMPILER_ID}, "
  86. "so SPIRV_WARN_EVERYTHING has no effect")
  87. endif()
  88. endif()
  89. if(${SPIRV_WERROR})
  90. set(SPIRV_WARNINGS ${SPIRV_WARNINGS} -Werror)
  91. endif()
  92. elseif(MSVC)
  93. set(SPIRV_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS /wd4800 /wd4819)
  94. if(${SPIRV_WERROR})
  95. set(SPIRV_WARNINGS ${SPIRV_WARNINGS} /WX)
  96. endif()
  97. endif()
  98. include_directories(${CMAKE_CURRENT_SOURCE_DIR}/)
  99. option(SPIRV_COLOR_TERMINAL "Enable color terminal output" ON)
  100. if(${SPIRV_COLOR_TERMINAL})
  101. add_definitions(-DSPIRV_COLOR_TERMINAL)
  102. endif()
  103. option(SPIRV_LOG_DEBUG "Enable excessive debug output" OFF)
  104. if(${SPIRV_LOG_DEBUG})
  105. add_definitions(-DSPIRV_LOG_DEBUG)
  106. endif()
  107. if (DEFINED SPIRV_TOOLS_EXTRA_DEFINITIONS)
  108. add_definitions(${SPIRV_TOOLS_EXTRA_DEFINITIONS})
  109. endif()
  110. # Library build setting definitions:
  111. #
  112. # * SPIRV_TOOLS_BUILD_STATIC - ON or OFF - Defaults to ON.
  113. # If enabled the following targets will be created:
  114. # ${SPIRV_TOOLS}-static - STATIC library.
  115. # Has full public symbol visibility.
  116. # ${SPIRV_TOOLS}-shared - SHARED library.
  117. # Has default-hidden symbol visibility.
  118. # ${SPIRV_TOOLS} - will alias to one of above, based on BUILD_SHARED_LIBS.
  119. # If disabled the following targets will be created:
  120. # ${SPIRV_TOOLS} - either STATIC or SHARED based on SPIRV_TOOLS_LIBRARY_TYPE.
  121. # Has full public symbol visibility.
  122. # ${SPIRV_TOOLS}-shared - SHARED library.
  123. # Has default-hidden symbol visibility.
  124. #
  125. # * SPIRV_TOOLS_LIBRARY_TYPE - SHARED or STATIC.
  126. # Specifies the library type used for building SPIRV-Tools libraries.
  127. # Defaults to SHARED when BUILD_SHARED_LIBS=1, otherwise STATIC.
  128. #
  129. # * SPIRV_TOOLS_FULL_VISIBILITY - "${SPIRV_TOOLS}-static" or "${SPIRV_TOOLS}"
  130. # Evaluates to the SPIRV_TOOLS target library name that has no hidden symbols.
  131. # This is used by internal targets for accessing symbols that are non-public.
  132. # Note this target provides no API stability guarantees.
  133. #
  134. # Ideally, all of these will go away - see https://github.com/KhronosGroup/SPIRV-Tools/issues/3909.
  135. option(ENABLE_EXCEPTIONS_ON_MSVC "Build SPIRV-TOOLS with c++ exceptions enabled in MSVC" ON)
  136. option(SPIRV_TOOLS_BUILD_STATIC "Build ${SPIRV_TOOLS}-static target. ${SPIRV_TOOLS} will alias to ${SPIRV_TOOLS}-static or ${SPIRV_TOOLS}-shared based on BUILD_SHARED_LIBS" ON)
  137. if(SPIRV_TOOLS_BUILD_STATIC)
  138. set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-static)
  139. set(SPIRV_TOOLS_LIBRARY_TYPE "STATIC")
  140. else(SPIRV_TOOLS_BUILD_STATIC)
  141. set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS})
  142. if (NOT DEFINED SPIRV_TOOLS_LIBRARY_TYPE)
  143. if(BUILD_SHARED_LIBS)
  144. set(SPIRV_TOOLS_LIBRARY_TYPE "SHARED")
  145. else()
  146. set(SPIRV_TOOLS_LIBRARY_TYPE "STATIC")
  147. endif()
  148. endif()
  149. endif(SPIRV_TOOLS_BUILD_STATIC)
  150. function(spvtools_default_compile_options TARGET)
  151. target_compile_options(${TARGET} PRIVATE ${SPIRV_WARNINGS})
  152. if (${COMPILER_IS_LIKE_GNU})
  153. target_compile_options(${TARGET} PRIVATE
  154. -Wall -Wextra -Wno-long-long -Wshadow -Wundef -Wconversion
  155. -Wno-sign-conversion -fno-exceptions)
  156. if(NOT ENABLE_RTTI)
  157. add_compile_options(-fno-rtti)
  158. endif()
  159. # For good call stacks in profiles, keep the frame pointers.
  160. if(NOT "${SPIRV_PERF}" STREQUAL "")
  161. target_compile_options(${TARGET} PRIVATE -fno-omit-frame-pointer)
  162. endif()
  163. if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
  164. set(SPIRV_USE_SANITIZER "" CACHE STRING
  165. "Use the clang sanitizer [address|memory|thread|...]")
  166. if(NOT "${SPIRV_USE_SANITIZER}" STREQUAL "")
  167. target_compile_options(${TARGET} PRIVATE
  168. -fsanitize=${SPIRV_USE_SANITIZER})
  169. set_target_properties(${TARGET} PROPERTIES
  170. LINK_FLAGS -fsanitize=${SPIRV_USE_SANITIZER})
  171. endif()
  172. target_compile_options(${TARGET} PRIVATE
  173. -ftemplate-depth=1024)
  174. else()
  175. target_compile_options(${TARGET} PRIVATE
  176. -Wno-missing-field-initializers)
  177. endif()
  178. endif()
  179. if (MSVC)
  180. # Specify /EHs for exception handling. This makes using SPIRV-Tools as
  181. # dependencies in other projects easier.
  182. if(ENABLE_EXCEPTIONS_ON_MSVC)
  183. target_compile_options(${TARGET} PRIVATE /EHs)
  184. endif()
  185. endif()
  186. # For MinGW cross compile, statically link to the C++ runtime.
  187. # But it still depends on MSVCRT.dll.
  188. if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
  189. if (NOT MSVC)
  190. set_target_properties(${TARGET} PROPERTIES
  191. LINK_FLAGS -static -static-libgcc -static-libstdc++)
  192. endif()
  193. endif()
  194. endfunction()
  195. if(NOT COMMAND find_host_package)
  196. macro(find_host_package)
  197. find_package(${ARGN})
  198. endmacro()
  199. endif()
  200. if(NOT COMMAND find_host_program)
  201. macro(find_host_program)
  202. find_program(${ARGN})
  203. endmacro()
  204. endif()
  205. # Tests require Python3
  206. find_host_package(Python3 REQUIRED)
  207. # Check for symbol exports on Linux.
  208. # At the moment, this check will fail on the OSX build machines for the Android NDK.
  209. # It appears they don't have objdump.
  210. if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
  211. macro(spvtools_check_symbol_exports TARGET)
  212. if (NOT "${SPIRV_SKIP_TESTS}")
  213. add_test(NAME spirv-tools-symbol-exports-${TARGET}
  214. COMMAND Python3::Interpreter
  215. ${spirv-tools_SOURCE_DIR}/utils/check_symbol_exports.py "$<TARGET_FILE:${TARGET}>")
  216. endif()
  217. endmacro()
  218. else()
  219. macro(spvtools_check_symbol_exports TARGET)
  220. if (NOT "${SPIRV_SKIP_TESTS}")
  221. message("Skipping symbol exports test for ${TARGET}")
  222. endif()
  223. endmacro()
  224. endif()
  225. if(ENABLE_SPIRV_TOOLS_INSTALL)
  226. if(WIN32 AND NOT MINGW)
  227. macro(spvtools_config_package_dir TARGET PATH)
  228. set(${PATH} ${TARGET}/cmake)
  229. endmacro()
  230. else()
  231. macro(spvtools_config_package_dir TARGET PATH)
  232. set(${PATH} ${CMAKE_INSTALL_LIBDIR}/cmake/${TARGET})
  233. endmacro()
  234. endif()
  235. macro(spvtools_generate_config_file TARGET)
  236. file(WRITE ${CMAKE_BINARY_DIR}/${TARGET}Config.cmake
  237. "include(CMakeFindDependencyMacro)\n"
  238. "find_dependency(${SPIRV_TOOLS})\n"
  239. "include(\${CMAKE_CURRENT_LIST_DIR}/${TARGET}Targets.cmake)\n"
  240. "set(${TARGET}_LIBRARIES ${TARGET})\n"
  241. "get_target_property(${TARGET}_INCLUDE_DIRS ${TARGET} INTERFACE_INCLUDE_DIRECTORIES)\n")
  242. endmacro()
  243. endif()
  244. # Currently iOS and Android are very similar.
  245. # They both have their own packaging (APP/APK).
  246. # Which makes regular executables/testing problematic.
  247. #
  248. # Currently the only deliverables for these platforms are
  249. # libraries (either STATIC or SHARED).
  250. #
  251. # Furthermore testing is equally problematic.
  252. set(SPIRV_SKIP_EXECUTABLES ON)
  253. option(SPIRV_SKIP_EXECUTABLES "Skip building the executable and tests along with the library")
  254. if (SPIRV_SKIP_EXECUTABLES)
  255. set(SPIRV_SKIP_TESTS ON)
  256. endif()
  257. option(SPIRV_SKIP_TESTS "Skip building tests along with the library")
  258. # Defaults to ON. The checks can be time consuming.
  259. # Turn off if they take too long.
  260. option(SPIRV_CHECK_CONTEXT "In a debug build, check if the IR context is in a valid state." ON)
  261. if (${SPIRV_CHECK_CONTEXT})
  262. add_compile_options($<$<CONFIG:Debug>:-DSPIRV_CHECK_CONTEXT>)
  263. endif()
  264. # Precompiled header macro. Parameters are source file list and filename for pch cpp file.
  265. macro(spvtools_pch SRCS PCHPREFIX)
  266. if(MSVC AND CMAKE_GENERATOR MATCHES "^Visual Studio" AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  267. set(PCH_NAME "$(IntDir)\\${PCHPREFIX}.pch")
  268. # make source files use/depend on PCH_NAME
  269. set_source_files_properties(${${SRCS}} PROPERTIES COMPILE_FLAGS "/Yu${PCHPREFIX}.h /FI${PCHPREFIX}.h /Fp${PCH_NAME} /Zm300" OBJECT_DEPENDS "${PCH_NAME}")
  270. # make PCHPREFIX.cpp file compile and generate PCH_NAME
  271. set_source_files_properties("${PCHPREFIX}.cpp" PROPERTIES COMPILE_FLAGS "/Yc${PCHPREFIX}.h /Fp${PCH_NAME} /Zm300" OBJECT_OUTPUTS "${PCH_NAME}")
  272. list(APPEND ${SRCS} "${PCHPREFIX}.cpp")
  273. endif()
  274. endmacro(spvtools_pch)
  275. add_subdirectory(external)
  276. # Warning about extra semi-colons.
  277. #
  278. # This is not supported on all compilers/versions. so enabling only
  279. # for clang, since that works for all versions that our bots run.
  280. #
  281. # This is intentionally done after adding the external subdirectory,
  282. # so we don't enforce this flag on our dependencies, some of which do
  283. # not pass it.
  284. #
  285. # If the minimum version of CMake supported is updated to 3.0 or
  286. # later, then check_cxx_compiler_flag could be used instead.
  287. if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  288. add_compile_options("-Wextra-semi")
  289. endif()
  290. add_subdirectory(source)
  291. add_subdirectory(tools)
  292. add_subdirectory(test)
  293. add_subdirectory(examples)
  294. if(ENABLE_SPIRV_TOOLS_INSTALL)
  295. install(
  296. FILES
  297. ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/libspirv.h
  298. ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/libspirv.hpp
  299. ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/optimizer.hpp
  300. ${CMAKE_CURRENT_SOURCE_DIR}/include/spirv-tools/linker.hpp
  301. DESTINATION
  302. ${CMAKE_INSTALL_INCLUDEDIR}/spirv-tools/)
  303. endif(ENABLE_SPIRV_TOOLS_INSTALL)
  304. if (NOT "${SPIRV_SKIP_TESTS}")
  305. add_test(NAME spirv-tools-copyrights
  306. COMMAND Python3::Interpreter utils/check_copyright.py
  307. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
  308. endif()
  309. set(SPIRV_LIBRARIES "-lSPIRV-Tools-opt -lSPIRV-Tools -lSPIRV-Tools-link")
  310. set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools-shared")
  311. # Build pkg-config file
  312. # Use a first-class target so it's regenerated when relevant files are updated.
  313. add_custom_command(
  314. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc
  315. COMMAND ${CMAKE_COMMAND}
  316. -DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
  317. -DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in
  318. -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc
  319. -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
  320. -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
  321. -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
  322. -DSPIRV_LIBRARIES=${SPIRV_LIBRARIES}
  323. -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
  324. DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
  325. add_custom_command(
  326. OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
  327. COMMAND ${CMAKE_COMMAND}
  328. -DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
  329. -DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in
  330. -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
  331. -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
  332. -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
  333. -DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
  334. -DSPIRV_SHARED_LIBRARIES=${SPIRV_SHARED_LIBRARIES}
  335. -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
  336. DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
  337. add_custom_target(spirv-tools-pkg-config
  338. ALL
  339. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc)
  340. # Install pkg-config file
  341. if (ENABLE_SPIRV_TOOLS_INSTALL)
  342. install(
  343. FILES
  344. ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc
  345. ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
  346. DESTINATION
  347. ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
  348. endif()