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