# Copyright 2020 The SwiftShader Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. cmake_minimum_required(VERSION 3.13) project(SwiftShader C CXX ASM) set(CMAKE_CXX_STANDARD 17) set(CXX_STANDARD_REQUIRED ON) # MSVC doesn't define __cplusplus by default if(MSVC) string(APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus") endif() ########################################################### # Detect system ########################################################### if(CMAKE_SYSTEM_NAME MATCHES "Linux") set(LINUX TRUE) elseif(CMAKE_SYSTEM_NAME MATCHES "Android") set(ANDROID TRUE) set(CMAKE_CXX_FLAGS "-DANDROID_NDK_BUILD") elseif(WIN32) elseif(APPLE) elseif(FUCHSIA) # NOTE: Building for Fuchsia requires a Fuchsia CMake-based SDK. # See https://fuchsia-review.googlesource.com/c/fuchsia/+/379673 find_package(FuchsiaLibraries) else() message(FATAL_ERROR "Platform is not supported") endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm" OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch") if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH "aarch64") else() set(ARCH "arm") endif() elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "mips*") if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH "mips64el") else() set(ARCH "mipsel") endif() elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc*") if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH "ppc64le") else() message(FATAL_ERROR "Architecture is not supported") endif() else() if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(ARCH "x86_64") else() set(ARCH "x86") endif() endif() # Cross compiling on macOS. The cross compiling architecture should override # auto-detected system architecture settings. if(CMAKE_OSX_ARCHITECTURES) if(CMAKE_OSX_ARCHITECTURES MATCHES "arm64") set(ARCH "aarch64") elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64") set(ARCH "x86_64") elseif(CMAKE_OSX_ARCHITECTURES MATCHES "i386") set(ARCH "x86") else() message(FATAL_ERROR "Architecture ${CMAKE_OSX_ARCHITECTURES} is not " "supported. Only one architecture (arm64, x86_64 " "or i386) could be specified at build time.") endif() endif() set(CMAKE_MACOSX_RPATH TRUE) if ((CMAKE_GENERATOR MATCHES "Visual Studio") AND (CMAKE_GENERATOR_TOOLSET STREQUAL "")) message(WARNING "Visual Studio generators use the x86 host compiler by " "default, even for 64-bit targets. This can result in linker " "instability and out of memory errors. To use the 64-bit " "host compiler, pass -Thost=x64 on the CMake command line.") endif() # Use CCache if available find_program(CCACHE_FOUND ccache) if(CCACHE_FOUND) message(STATUS "Using ccache") set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) endif() ########################################################### # Host libraries ########################################################### find_library(X11 X11) find_library(XCB xcb) if(SWIFTSHADER_BUILD_WSI_WAYLAND) find_library(WAYLAND wayland-client) endif(SWIFTSHADER_BUILD_WSI_WAYLAND) if(SWIFTSHADER_BUILD_WSI_DIRECTFB) find_library(DIRECTFB directfb) find_path(DIRECTFB_INCLUDE_DIR directfb/directfb.h) endif(SWIFTSHADER_BUILD_WSI_DIRECTFB) if(SWIFTSHADER_BUILD_WSI_D2D) find_library(D2D drm) find_path(D2D_INCLUDE_DIR libdrm/drm.h) endif(SWIFTSHADER_BUILD_WSI_D2D) ########################################################### # Options ########################################################### if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "The type of build: Debug Release MinSizeRel RelWithDebInfo." FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo) endif() function (option_if_not_defined name description default) if(NOT DEFINED ${name}) option(${name} ${description} ${default}) endif() endfunction() function (set_if_not_defined name value) if(NOT DEFINED ${name}) set(${name} ${value} PARENT_SCOPE) endif() endfunction() option_if_not_defined(SWIFTSHADER_BUILD_EGL "Build the EGL library" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_GLESv2 "Build the OpenGL ES 2 library" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_GLES_CM "Build the OpenGL ES 1.1 library" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_VULKAN "Build the Vulkan library" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_WSI_WAYLAND "Build the Wayland WSI support" FALSE) option_if_not_defined(SWIFTSHADER_BUILD_WSI_DIRECTFB "Build the DirectFB WSI support" FALSE) option_if_not_defined(SWIFTSHADER_BUILD_WSI_D2D "Build the Direct-to-Display WSI support" FALSE) option_if_not_defined(SWIFTSHADER_BUILD_PVR "Build the PowerVR examples" TRUE) option_if_not_defined(SWIFTSHADER_GET_PVR "Check out the PowerVR submodule" FALSE) option_if_not_defined(SWIFTSHADER_BUILD_ANGLE "Build angle" FALSE) option_if_not_defined(SWIFTSHADER_USE_GROUP_SOURCES "Group the source files in a folder tree for Visual Studio" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_TESTS "Build unit tests" TRUE) option_if_not_defined(SWIFTSHADER_BUILD_BENCHMARKS "Build benchmarks" FALSE) option_if_not_defined(SWIFTSHADER_MSAN "Build with memory sanitizer" FALSE) option_if_not_defined(SWIFTSHADER_ASAN "Build with address sanitizer" FALSE) option_if_not_defined(SWIFTSHADER_TSAN "Build with thread sanitizer" FALSE) option_if_not_defined(SWIFTSHADER_UBSAN "Build with undefined behavior sanitizer" FALSE) option_if_not_defined(SWIFTSHADER_EMIT_COVERAGE "Emit code coverage information" FALSE) option_if_not_defined(SWIFTSHADER_WARNINGS_AS_ERRORS "Treat all warnings as errors" TRUE) option_if_not_defined(SWIFTSHADER_DCHECK_ALWAYS_ON "Check validation macros even in release builds" FALSE) option_if_not_defined(REACTOR_EMIT_DEBUG_INFO "Emit debug info for JIT functions" FALSE) option_if_not_defined(REACTOR_EMIT_PRINT_LOCATION "Emit printing of location info for JIT functions" FALSE) option_if_not_defined(REACTOR_EMIT_ASM_FILE "Emit asm files for JIT functions" FALSE) option_if_not_defined(REACTOR_ENABLE_PRINT "Enable RR_PRINT macros" FALSE) option_if_not_defined(REACTOR_VERIFY_LLVM_IR "Check reactor-generated LLVM IR is valid even in release builds" FALSE) # TODO(b/155148722): Remove when unconditionally instrumenting for all build systems. option_if_not_defined(REACTOR_ENABLE_MEMORY_SANITIZER_INSTRUMENTATION "Include JIT in MSAN instrumentation (LLVM backend)" TRUE) option_if_not_defined(SWIFTSHADER_LESS_DEBUG_INFO "Generate less debug info to reduce file size" FALSE) option_if_not_defined(SWIFTSHADER_ENABLE_VULKAN_DEBUGGER "Enable Vulkan debugger support" FALSE) option_if_not_defined(SWIFTSHADER_ENABLE_ASTC "Enable ASTC compressed textures support" TRUE) # TODO(b/150130101) set(BUILD_MARL ${SWIFTSHADER_BUILD_VULKAN}) if(${SWIFTSHADER_BUILD_VULKAN} AND ${SWIFTSHADER_ENABLE_VULKAN_DEBUGGER}) set_if_not_defined(SWIFTSHADER_BUILD_CPPDAP TRUE) else() set_if_not_defined(SWIFTSHADER_BUILD_CPPDAP FALSE) endif() set(DEFAULT_REACTOR_BACKEND "LLVM") set(REACTOR_BACKEND ${DEFAULT_REACTOR_BACKEND} CACHE STRING "JIT compiler back-end used by Reactor") set_property(CACHE REACTOR_BACKEND PROPERTY STRINGS LLVM Subzero) set(DEFAULT_SWIFTSHADER_LLVM_VERSION "10.0") set(SWIFTSHADER_LLVM_VERSION ${DEFAULT_SWIFTSHADER_LLVM_VERSION} CACHE STRING "LLVM version to use") set_property(CACHE SWIFTSHADER_LLVM_VERSION PROPERTY STRINGS "10.0") # If defined, overrides the default optimization level of the current reactor backend. # Set to one of the rr::Optimization::Level enum values. set(REACTOR_DEFAULT_OPT_LEVEL "" CACHE STRING "Reactor default optimization level") set_property(CACHE REACTOR_DEFAULT_OPT_LEVEL PROPERTY STRINGS "None" "Less" "Default" "Aggressive") if(NOT DEFINED SWIFTSHADER_LOGGING_LEVEL) set(SWIFTSHADER_LOGGING_LEVEL "Info" CACHE STRING "SwiftShader logging level") set_property(CACHE SWIFTSHADER_LOGGING_LEVEL PROPERTY STRINGS "Verbose" "Debug" "Info" "Warn" "Error" "Fatal" "Disabled") endif() # LLVM disallows calling cmake . from the main LLVM dir, the reason is that # it builds header files that could overwrite the orignal ones. Here we # want to include LLVM as a subdirectory and even though it wouldn't cause # the problem, if cmake . is called from the main dir, the condition that # LLVM checkes, "CMAKE_CURRENT_SOURCE_DIR == CMAKE_CURRENT_BINARY_DIR" will be true. So we # disallow it ourselves too to. In addition if there are remining CMakeFiles # and CMakeCache in the directory, cmake .. from a subdirectory will still # try to build from the main directory so we instruct users to delete these # files when they get the error. if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) message(FATAL_ERROR "In source builds are not allowed by LLVM, please create a build/ directory and build from there. You may have to delete the CMakeCache.txt file and CMakeFiles directory that are next to the CMakeLists.txt.") endif() set_property(GLOBAL PROPERTY USE_FOLDERS TRUE) ########################################################### # Directories ########################################################### set(SWIFTSHADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(SOURCE_DIR ${SWIFTSHADER_DIR}/src) set(THIRD_PARTY_DIR ${SWIFTSHADER_DIR}/third_party) set(TESTS_DIR ${SWIFTSHADER_DIR}/tests) ########################################################### # Initialize submodules ########################################################### function(InitSubmodule target submodule_dir) if (NOT TARGET ${target}) if(NOT EXISTS ${submodule_dir}/.git) message(WARNING " Target ${target} from submodule ${submodule_dir} missing. Running 'git submodule update --init' to download it: ") execute_process(COMMAND git -C ${SWIFTSHADER_DIR} submodule update --init ${submodule_dir}) endif() endif() endfunction() if (SWIFTSHADER_BUILD_TESTS OR SWIFTSHADER_BUILD_BENCHMARKS) set(BUILD_VULKAN_WRAPPER TRUE) endif() if (BUILD_VULKAN_WRAPPER) InitSubmodule(glslang ${THIRD_PARTY_DIR}/glslang) endif() if (SWIFTSHADER_BUILD_TESTS) InitSubmodule(gtest ${THIRD_PARTY_DIR}/googletest) endif() if(SWIFTSHADER_BUILD_BENCHMARKS) InitSubmodule(benchmark::benchmark ${THIRD_PARTY_DIR}/benchmark) endif() if(REACTOR_EMIT_DEBUG_INFO) InitSubmodule(libbacktrace ${THIRD_PARTY_DIR}/libbacktrace/src) endif() if(SWIFTSHADER_GET_PVR) InitSubmodule(PVRCore ${THIRD_PARTY_DIR}/PowerVR_Examples) set(SWIFTSHADER_GET_PVR FALSE CACHE BOOL "Check out the PowerVR submodule" FORCE) endif() if(EXISTS ${THIRD_PARTY_DIR}/PowerVR_Examples/.git) set(HAVE_PVR_SUBMODULE TRUE) endif() if(SWIFTSHADER_BUILD_CPPDAP) InitSubmodule(json ${THIRD_PARTY_DIR}/json) InitSubmodule(cppdap ${THIRD_PARTY_DIR}/cppdap) endif() if(SWIFTSHADER_BUILD_ANGLE) InitSubmodule(angle ${THIRD_PARTY_DIR}/angle/angle) endif() ########################################################### # Convenience macros ########################################################### # Recursively calls source_group on the files of the directory # so that Visual Studio has the files in a folder tree macro(group_all_sources directory) file(GLOB files RELATIVE ${SWIFTSHADER_DIR}/${directory} ${SWIFTSHADER_DIR}/${directory}/*) foreach(file ${files}) if(IS_DIRECTORY ${SWIFTSHADER_DIR}/${directory}/${file}) group_all_sources(${directory}/${file}) else() string(REPLACE "/" "\\" groupname ${directory}) source_group(${groupname} FILES ${SWIFTSHADER_DIR}/${directory}/${file}) endif() endforeach() endmacro() # Takes target library and a directory where the export map is # and add the linker options so that only the API symbols are # exported. macro(set_shared_library_export_map TARGET DIR) if(MSVC) set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " /DEF:\"${DIR}/${TARGET}.def\"") elseif(APPLE) # The exported symbols list only exports the API functions and # hides all the others. set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS "-exported_symbols_list ${DIR}/${TARGET}.exports") set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_DEPENDS "${DIR}/${TARGET}.exports;") # Don't allow undefined symbols, unless it's a Sanitizer build. if(NOT SWIFTSHADER_MSAN AND NOT SWIFTSHADER_ASAN AND NOT SWIFTSHADER_TSAN AND NOT SWIFTSHADER_UBSAN) set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-undefined,error") endif() elseif(LINUX OR FUCHSIA) # NOTE: The Fuchsia linker script is needed to export the vk_icdInitializeConnectToServiceCallback # entry point (a private implementation detail betwen the Fuchsia Vulkan loader and the ICD). if ((FUCHSIA) AND ("${TARGET}" STREQUAL "vk_swiftshader")) set(LINKER_VERSION_SCRIPT "fuchsia_vk_swiftshader.lds") else() set(LINKER_VERSION_SCRIPT "${TARGET}.lds") endif() # The version script only exports the API functions and # hides all the others. set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--version-script=${DIR}/${LINKER_VERSION_SCRIPT}") set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_DEPENDS "${DIR}/${LINKER_VERSION_SCRIPT};") # -Bsymbolic binds symbol references to their global definitions within # a shared object, thereby preventing symbol preemption. set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-Bsymbolic") if(ARCH STREQUAL "mipsel" OR ARCH STREQUAL "mips64el") # MIPS supports sysv hash-style only. set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--hash-style=sysv") elseif(LINUX) # Both hash-style are needed, because we want both gold and # GNU ld to be able to read our libraries. set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--hash-style=both") endif() if(NOT ${SWIFTSHADER_EMIT_COVERAGE}) # Gc sections is used in combination with each functions being # in its own section, to reduce the binary size. set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--gc-sections") endif() # Don't allow undefined symbols, unless it's a Sanitizer build. if(NOT SWIFTSHADER_MSAN AND NOT SWIFTSHADER_ASAN AND NOT SWIFTSHADER_TSAN AND NOT SWIFTSHADER_UBSAN) set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--no-undefined") endif() endif() endmacro() if(SWIFTSHADER_USE_GROUP_SOURCES) group_all_sources(src) endif() ########################################################### # Compile flags ########################################################### # Flags for project code (non 3rd party) set(SWIFTSHADER_COMPILE_OPTIONS "") set(SWIFTSHADER_LINK_FLAGS "") set(SWIFTSHADER_LIBS "") macro(set_cpp_flag FLAG) if(${ARGC} GREATER 1) set(CMAKE_CXX_FLAGS_${ARGV1} "${CMAKE_CXX_FLAGS_${ARGV1}} ${FLAG}") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}") endif() endmacro() macro(set_linker_flag FLAG) if(${ARGC} GREATER 1) set(CMAKE_EXE_LINKER_FLAGS_${ARGV1} "${CMAKE_EXE_LINKER_FLAGS_${ARGV1}} ${FLAG}") set(CMAKE_SHARED_LINKER_FLAGS_${ARGV1} "${CMAKE_EXE_LINKER_FLAGS_${ARGV1}} ${FLAG}") else() set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}") endif() endmacro() if(MSVC) set_cpp_flag("/MP") add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_SCL_SECURE_NO_WARNINGS) add_definitions(-D_SBCS) # Single Byte Character Set (ASCII) add_definitions(-D_ENABLE_EXTENDED_ALIGNED_STORAGE) # Disable MSVC warnings about std::aligned_storage being broken before VS 2017 15.8 set_linker_flag("/DEBUG:FASTLINK" DEBUG) set_linker_flag("/DEBUG:FASTLINK" RELWITHDEBINFO) # Disable specific warnings # TODO: Not all of these should be disabled, but for now, we want a warning-free msvc build. Remove these one by one # and fix the actual warnings in code. list(APPEND SWIFTSHADER_COMPILE_OPTIONS "/wd4005" # 'identifier' : macro redefinition "/wd4018" # 'expression' : signed/unsigned mismatch "/wd4065" # switch statement contains 'default' but no 'case' labels "/wd4141" # 'modifier' : used more than once "/wd4244" # 'conversion' conversion from 'type1' to 'type2', possible loss of data "/wd4267" # 'var' : conversion from 'size_t' to 'type', possible loss of data "/wd4291" # 'void X new(size_t,unsigned int,unsigned int)': no matching operator delete found; memory will not be freed if initialization throws an exception "/wd4309" # 'conversion' : truncation of constant value "/wd4624" # 'derived class' : destructor was implicitly defined as deleted because a base class destructor is inaccessible or deleted "/wd4800" # 'type' : forcing value to bool 'true' or 'false' (performance warning) "/wd4838" # conversion from 'type_1' to 'type_2' requires a narrowing conversion "/wd5030" # attribute 'attribute' is not recognized "/wd5038" # data member 'member1' will be initialized after data member 'member2' data member 'member' will be initialized after base class 'base_class' ) # Treat specific warnings as errors list(APPEND SWIFTSHADER_COMPILE_OPTIONS "/we4018" # 'expression' : signed/unsigned mismatch "/we4471" # 'enumeration': a forward declaration of an unscoped enumeration must have an underlying type (int assumed) "/we4838" # conversion from 'type_1' to 'type_2' requires a narrowing conversion "/we5038" # data member 'member1' will be initialized after data member 'member2' data member 'member' will be initialized after base class 'base_class' ) else() # Explicitly enable these warnings. list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-Wall" "-Wreorder" "-Wsign-compare" "-Wmissing-braces" ) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-Wextra" "-Wunreachable-code-loop-increment" "-Wunused-lambda-capture" "-Wstring-conversion" "-Wextra-semi" "-Wignored-qualifiers" ) endif() if (SWIFTSHADER_EMIT_COVERAGE) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") list(APPEND SWIFTSHADER_COMPILE_OPTIONS "--coverage") list(APPEND SWIFTSHADER_LIBS "gcov") elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-fprofile-instr-generate" "-fcoverage-mapping") list(APPEND SWIFTSHADER_LINK_FLAGS "-fprofile-instr-generate" "-fcoverage-mapping") else() message(FATAL_ERROR "Coverage generation not supported for the ${CMAKE_CXX_COMPILER_ID} toolchain") endif() endif() # Disable pedanitc warnings if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-Wno-ignored-attributes" # ignoring attributes on template argument 'X' "-Wno-attributes" # 'X' attribute ignored "-Wno-strict-aliasing" # dereferencing type-punned pointer will break strict-aliasing rules "-Wno-comment" # multi-line comment ) if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-Wno-init-list-lifetime" # assignment from temporary initializer_list does not extend the lifetime of the underlying array ) endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-Wno-unneeded-internal-declaration" # function 'X' is not needed and will not be emitted "-Wno-unused-private-field" # private field 'offset' is not used - TODO: Consider enabling this once Vulkan is further implemented. "-Wno-comment" # multi-line comment "-Wno-undefined-var-template" # instantiation of variable 'X' required here, but no definition is available "-Wno-extra-semi" # extra ';' after member function definition "-Wno-unused-parameter" # unused parameter 'X' "-Wno-deprecated-copy" # implicit copy constructor for 'X' is deprecated because of user-declared copy assignment operator. # Silence errors caused by unknown warnings when building with older # versions of Clang. This demands checking that warnings added above # are spelled correctly and work as intended! "-Wno-unknown-warning-option" ) endif() # Remove xor, and, or and friends from the list of keywords, they are used # by Reactor list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-fno-operator-names" ) if(ARCH STREQUAL "x86") set_cpp_flag("-m32") set_cpp_flag("-msse2") set_cpp_flag("-mfpmath=sse") set_cpp_flag("-march=pentium4") set_cpp_flag("-mtune=generic") endif() if(ARCH STREQUAL "x86_64") set_cpp_flag("-m64") set_cpp_flag("-fPIC") set_cpp_flag("-march=x86-64") set_cpp_flag("-mtune=generic") endif() if(ARCH STREQUAL "mipsel") set_cpp_flag("-EL") set_cpp_flag("-march=mips32r2") set_cpp_flag("-fPIC") set_cpp_flag("-mhard-float") set_cpp_flag("-mfp32") set_cpp_flag("-mxgot") endif() if(ARCH STREQUAL "mips64el") set_cpp_flag("-EL") set_cpp_flag("-march=mips64r2") set_cpp_flag("-mabi=64") set_cpp_flag("-fPIC") set_cpp_flag("-mxgot") endif() if(SWIFTSHADER_LESS_DEBUG_INFO) # Use -g1 to be able to get stack traces set_cpp_flag("-g -g1" DEBUG) set_cpp_flag("-g -g1" RELWITHDEBINFO) else() # Use -g3 to have even more debug info set_cpp_flag("-g -g3" DEBUG) set_cpp_flag("-g -g3" RELWITHDEBINFO) endif() if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") # Treated as an unused argument with clang set_cpp_flag("-s" RELEASE) endif() # For distribution it is more important to be slim than super optimized set_cpp_flag("-Os" RELEASE) set_cpp_flag("-Os" RELWITHDEBINFO) set_cpp_flag("-DNDEBUG" RELEASE) set_cpp_flag("-DNDEBUG" RELWITHDEBINFO) set_cpp_flag("-DANGLE_DISABLE_TRACE" RELEASE) set_cpp_flag("-DANGLE_DISABLE_TRACE" RELWITHDEBINFO) # Put each variable and function in its own section so that when linking # with -gc-sections unused functions and variables are removed. set_cpp_flag("-ffunction-sections" RELEASE) set_cpp_flag("-fdata-sections" RELEASE) set_cpp_flag("-fomit-frame-pointer" RELEASE) if(SWIFTSHADER_MSAN) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") message(FATAL_ERROR " \n" " MemorySanitizer usage requires compiling with Clang.") endif() if(NOT DEFINED ENV{SWIFTSHADER_MSAN_INSTRUMENTED_LIBCXX_PATH}) message(FATAL_ERROR " \n" " MemorySanitizer usage requires an instrumented build of libc++.\n" " Set the SWIFTSHADER_MSAN_INSTRUMENTED_LIBCXX_PATH environment variable to the\n" " build output path. See\n" " https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo#instrumented-libc\n" " for details on how to build an MSan instrumented libc++.") endif() set_cpp_flag("-fsanitize=memory") set_linker_flag("-fsanitize=memory") set_cpp_flag("-stdlib=libc++") set_linker_flag("-L$ENV{SWIFTSHADER_MSAN_INSTRUMENTED_LIBCXX_PATH}/lib") set_cpp_flag("-I$ENV{SWIFTSHADER_MSAN_INSTRUMENTED_LIBCXX_PATH}/include") set_cpp_flag("-I$ENV{SWIFTSHADER_MSAN_INSTRUMENTED_LIBCXX_PATH}/include/c++/v1") set_linker_flag("-Wl,-rpath,$ENV{SWIFTSHADER_MSAN_INSTRUMENTED_LIBCXX_PATH}/lib") elseif(SWIFTSHADER_ASAN) set_cpp_flag("-fsanitize=address") set_linker_flag("-fsanitize=address") elseif(SWIFTSHADER_TSAN) set_cpp_flag("-fsanitize=thread") set_linker_flag("-fsanitize=thread") elseif(SWIFTSHADER_UBSAN) set_cpp_flag("-fsanitize=undefined") set_linker_flag("-fsanitize=undefined") endif() endif() if(SWIFTSHADER_DCHECK_ALWAYS_ON) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DDCHECK_ALWAYS_ON") endif() if(SWIFTSHADER_WARNINGS_AS_ERRORS) if(MSVC) set(WARNINGS_AS_ERRORS "/WX") # Treat all warnings as errors else() set(WARNINGS_AS_ERRORS "-Werror") # Treat all warnings as errors endif() endif() # Enable Reactor Print() functionality in Debug/RelWithDebInfo builds or when explicitly enabled. if(CMAKE_BUILD_TYPE MATCHES "Deb") set(REACTOR_ENABLE_PRINT TRUE) endif() if(REACTOR_EMIT_PRINT_LOCATION) # This feature depends on REACTOR_EMIT_DEBUG_INFO and REACTOR_ENABLE_PRINT set(REACTOR_EMIT_DEBUG_INFO TRUE) set(REACTOR_ENABLE_PRINT TRUE) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_EMIT_PRINT_LOCATION") endif() if(REACTOR_EMIT_ASM_FILE) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_EMIT_ASM_FILE") endif() if(REACTOR_EMIT_DEBUG_INFO) message(WARNING "REACTOR_EMIT_DEBUG_INFO is enabled. This will likely affect performance.") list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_DEBUG_INFO") endif() if(REACTOR_ENABLE_PRINT) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_PRINT") endif() if(REACTOR_VERIFY_LLVM_IR) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_LLVM_IR_VERIFICATION") endif() if(REACTOR_DEFAULT_OPT_LEVEL) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DREACTOR_DEFAULT_OPT_LEVEL=${REACTOR_DEFAULT_OPT_LEVEL}") endif() if(DEFINED SWIFTSHADER_LOGGING_LEVEL) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DSWIFTSHADER_LOGGING_LEVEL=${SWIFTSHADER_LOGGING_LEVEL}") endif() if(WIN32) add_definitions(-DWINVER=0x501 -DNOMINMAX -DSTRICT) set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} "" "lib") endif() set(USE_EXCEPTIONS ${REACTOR_EMIT_DEBUG_INFO} # boost::stacktrace uses exceptions ) if(NOT MSVC) if (${USE_EXCEPTIONS}) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-fexceptions") else() list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-fno-exceptions") endif() endif() unset(USE_EXCEPTIONS) ########################################################### # libbacktrace and boost ########################################################### if(REACTOR_EMIT_DEBUG_INFO) add_subdirectory(${THIRD_PARTY_DIR}/libbacktrace EXCLUDE_FROM_ALL) add_subdirectory(${THIRD_PARTY_DIR}/boost EXCLUDE_FROM_ALL) endif() ########################################################### # LLVM ########################################################### add_subdirectory(${THIRD_PARTY_DIR}/llvm-${SWIFTSHADER_LLVM_VERSION} EXCLUDE_FROM_ALL) set_target_properties(llvm PROPERTIES FOLDER "third_party") ########################################################### # Subzero ########################################################### add_subdirectory(${THIRD_PARTY_DIR}/llvm-subzero EXCLUDE_FROM_ALL) add_subdirectory(${THIRD_PARTY_DIR}/subzero EXCLUDE_FROM_ALL) set_target_properties(llvm-subzero PROPERTIES FOLDER "third_party") set_target_properties(subzero PROPERTIES FOLDER "third_party") ########################################################### # marl ########################################################### if(BUILD_MARL) set(MARL_THIRD_PARTY_DIR ${THIRD_PARTY_DIR}) add_subdirectory(${THIRD_PARTY_DIR}/marl) set_target_properties(marl PROPERTIES FOLDER "third_party") endif() if(MARL_THREAD_SAFETY_ANALYSIS_SUPPORTED) list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-Wthread-safety") endif() ########################################################### # cppdap ########################################################### if(SWIFTSHADER_BUILD_CPPDAP) set(CPPDAP_THIRD_PARTY_DIR ${THIRD_PARTY_DIR}) add_subdirectory(${THIRD_PARTY_DIR}/cppdap) endif() ########################################################### # astc-encoder ########################################################### if(SWIFTSHADER_ENABLE_ASTC) add_subdirectory(${THIRD_PARTY_DIR}/astc-encoder) set_target_properties(astc-encoder PROPERTIES FOLDER "third_party") endif() ########################################################### # gtest and gmock ########################################################### if(SWIFTSHADER_BUILD_TESTS) # For Win32, force gtest to match our CRT (shared) set(gtest_force_shared_crt TRUE CACHE BOOL "" FORCE) add_subdirectory(${THIRD_PARTY_DIR}/googletest EXCLUDE_FROM_ALL) # gtest finds python, which picks python 2 first, if present. # We need to undo this so that SPIR-V can later find python3. unset(PYTHON_EXECUTABLE CACHE) set_target_properties(gmock PROPERTIES FOLDER "third_party") set_target_properties(gmock_main PROPERTIES FOLDER "third_party") set_target_properties(gtest PROPERTIES FOLDER "third_party") set_target_properties(gtest_main PROPERTIES FOLDER "third_party") endif() ########################################################### # File Lists ########################################################### ########################################################### # Append OS specific files to lists ########################################################### if(WIN32) set(OS_LIBS odbc32 odbccp32 WS2_32 dxguid) elseif(LINUX) set(OS_LIBS dl pthread) if(SWIFTSHADER_BUILD_WSI_WAYLAND) list(APPEND OS_LIBS "${WAYLAND}") endif(SWIFTSHADER_BUILD_WSI_WAYLAND) if(SWIFTSHADER_BUILD_WSI_DIRECTFB) list(APPEND OS_LIBS "${DIRECTFB}") include_directories(${DIRECTFB_INCLUDE_DIR}/directfb) endif(SWIFTSHADER_BUILD_WSI_DIRECTFB) if(SWIFTSHADER_BUILD_WSI_D2D) list(APPEND OS_LIBS "${D2D}") include_directories(${D2D_INCLUDE_DIR}/libdrm) endif(SWIFTSHADER_BUILD_WSI_D2D) elseif(FUCHSIA) set(OS_LIBS zircon) elseif(APPLE) find_library(COCOA_FRAMEWORK Cocoa) find_library(QUARTZ_FRAMEWORK Quartz) find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) find_library(IOSURFACE_FRAMEWORK IOSurface) find_library(METAL_FRAMEWORK Metal) set(OS_LIBS "${COCOA_FRAMEWORK}" "${QUARTZ_FRAMEWORK}" "${CORE_FOUNDATION_FRAMEWORK}" "${IOSURFACE_FRAMEWORK}" "${METAL_FRAMEWORK}") endif() ########################################################### # SwiftShader Targets ########################################################### add_subdirectory(src/Reactor) # Add ReactorSubzero and ReactorLLVM targets if(${REACTOR_BACKEND} STREQUAL "LLVM") set(Reactor ReactorLLVM) elseif(${REACTOR_BACKEND} STREQUAL "Subzero") set(Reactor ReactorSubzero) else() message(FATAL_ERROR "REACTOR_BACKEND must be 'LLVM' or 'Subzero'") endif() add_subdirectory(src/Common) # Add gl_common target add_subdirectory(src/Main) # Add gl_main target add_subdirectory(src/Shader) # Add gl_shader target add_subdirectory(src/Renderer) # Add gl_renderer target # Combine all gl_* targets into an interface target # along with other dependencies add_library(gl_swiftshader_core INTERFACE) target_link_libraries(gl_swiftshader_core INTERFACE # Transitively depends on shader, main, core, Reactor, # OS_LIBS and SWIFTSHADER_LIBS gl_renderer ) add_subdirectory(src/OpenGL/common EXCLUDE_FROM_ALL) # Add libGLESCommon target add_subdirectory(src/OpenGL/compiler EXCLUDE_FROM_ALL) # Add GLCompiler target if(SWIFTSHADER_BUILD_EGL) add_subdirectory(src/OpenGL/libEGL) # Add libEGL target endif() if(SWIFTSHADER_BUILD_GLESv2) add_subdirectory(src/OpenGL/libGLESv2) # Add libGLESv2 target endif() if(SWIFTSHADER_BUILD_GLES_CM) add_subdirectory(src/OpenGL/libGLES_CM) # Add libGLES_CM target endif(SWIFTSHADER_BUILD_GLES_CM) if(SWIFTSHADER_BUILD_VULKAN) if (NOT TARGET SPIRV-Tools) # This variable is also used by SPIRV-Tools to locate SPIRV-Headers set(SPIRV-Headers_SOURCE_DIR "${THIRD_PARTY_DIR}/SPIRV-Headers") set(SPIRV_SKIP_TESTS TRUE CACHE BOOL "" FORCE) add_subdirectory(${THIRD_PARTY_DIR}/SPIRV-Tools) # Add SPIRV-Tools target endif() # Add a vk_base interface library for shared vulkan build options. # TODO: Create src/Base and make this a lib target, and move stuff from # src/Vulkan into it that is needed by vk_pipeline, vk_device, and vk_wsi. add_library(vk_base INTERFACE) if(SWIFTSHADER_ENABLE_VULKAN_DEBUGGER) target_compile_definitions(vk_base INTERFACE "ENABLE_VK_DEBUGGER") endif() if(WIN32) target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_WIN32_KHR") elseif(LINUX) if(X11) target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_XLIB_KHR") endif() if(XCB) target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_XCB_KHR") endif() if(SWIFTSHADER_BUILD_WSI_WAYLAND) if(WAYLAND) target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_WAYLAND_KHR") endif() endif(SWIFTSHADER_BUILD_WSI_WAYLAND) if(SWIFTSHADER_BUILD_WSI_DIRECTFB) if(DIRECTFB AND DIRECTFB_INCLUDE_DIR) target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_DIRECTFB_EXT") endif() endif(SWIFTSHADER_BUILD_WSI_DIRECTFB) if(SWIFTSHADER_BUILD_WSI_D2D) if(D2D) target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_DISPLAY_KHR") endif() endif(SWIFTSHADER_BUILD_WSI_D2D) elseif(APPLE) target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_MACOS_MVK") elseif(FUCHSIA) target_compile_definitions(vk_base INTERFACE "VK_USE_PLATFORM_FUCHSIA") else() message(FATAL_ERROR "Platform does not support Vulkan yet") endif() add_subdirectory(src/System) # Add vk_system target add_subdirectory(src/Pipeline) # Add vk_pipeline target add_subdirectory(src/WSI) # Add vk_wsi target add_subdirectory(src/Device) # Add vk_device target add_subdirectory(src/Vulkan) # Add vk_swiftshader target if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND # turbo-cov is only useful for clang coverage info SWIFTSHADER_EMIT_COVERAGE) add_subdirectory(${TESTS_DIR}/regres/cov/turbo-cov) endif() endif() if(SWIFTSHADER_BUILD_ANGLE) add_subdirectory(${THIRD_PARTY_DIR}/angle) # Make angle depend on vk_swiftshader so we can test SWANGLE if (TARGET vk_swiftshader) add_dependencies(angle vk_swiftshader) endif() endif() ########################################################### # Sample programs and tests ########################################################### # TODO(b/161976310): Add support for building PowerVR on MacOS if(APPLE AND HAVE_PVR_SUBMODULE AND SWIFTSHADER_BUILD_PVR) message(WARNING "Building PowerVR examples for SwiftShader is not yet supported on Apple platforms.") set(SWIFTSHADER_BUILD_PVR FALSE) endif() if(HAVE_PVR_SUBMODULE AND SWIFTSHADER_BUILD_PVR) if(UNIX AND NOT APPLE) set(PVR_WINDOW_SYSTEM XCB) # Set the RPATH of the next defined build targets to $ORIGIN, # allowing them to load shared libraries from the execution directory. set(CMAKE_BUILD_RPATH "$ORIGIN") endif() set(PVR_BUILD_EXAMPLES TRUE CACHE BOOL "Build the PowerVR SDK Examples" FORCE) add_subdirectory(${THIRD_PARTY_DIR}/PowerVR_Examples) # Samples known to work well set(PVR_VULKAN_TARGET_GOOD VulkanBumpmap VulkanExampleUI VulkanGaussianBlur VulkanGlass VulkanGnomeHorde VulkanHelloAPI VulkanImageBasedLighting VulkanIntroducingPVRUtils VulkanMultiSampling VulkanNavigation2D VulkanParticleSystem VulkanSkinning ) set(PVR_GLES_TARGET_GOOD OpenGLESHelloAPI OpenGLESIntroducingPVRUtils OpenGLESNavigation2D ) set(PVR_VULKAN_TARGET_OTHER VulkanDeferredShading VulkanDeferredShadingPFX VulkanGameOfLife VulkanIBLMapsGenerator VulkanIMGTextureFilterCubic VulkanIntroducingPVRShell VulkanIntroducingPVRVk VulkanIntroducingUIRenderer VulkanMultithreading VulkanNavigation3D VulkanPostProcessing VulkanPVRScopeExample VulkanPVRScopeRemote ) set(PVR_GLES_TARGET_OTHER OpenGLESDeferredShading OpenGLESGaussianBlur OpenGLESImageBasedLighting OpenGLESIMGFramebufferDownsample OpenGLESIMGTextureFilterCubic OpenGLESIntroducingPVRCamera OpenGLESIntroducingPVRShell OpenGLESIntroducingUIRenderer OpenGLESMultiviewVR OpenGLESNavigation3D OpenGLESOpenCLExample OpenGLESParticleSystem OpenGLESPostProcessing OpenGLESPVRScopeExample OpenGLESPVRScopeRemote OpenGLESSkinning ) set(PVR_TARGET_OTHER glslang glslangValidator glslang-default-resource-limits OGLCompiler OSDependent OpenCLMatrixMultiplication pugixml PVRAssets PVRCamera PVRCore PVRPfx PVRShell PVRUtilsGles PVRUtilsVk PVRVk SPIRV spirv-remap SPVRemapper uninstall ) set(PVR_VULKAN_TARGET ${PVR_VULKAN_TARGET_GOOD} ${PVR_VULKAN_TARGET_OTHER} ) set(PVR_GLES_TARGET ${PVR_GLES_TARGET_GOOD} ${PVR_GLES_TARGET_OTHER} ) foreach(pvr_target ${PVR_VULKAN_TARGET}) add_dependencies(${pvr_target} vk_swiftshader) endforeach() foreach(pvr_target ${PVR_GLES_TARGET}) add_dependencies(${pvr_target} libGLESv2) add_dependencies(${pvr_target} libEGL) endforeach() foreach(pvr_target ${PVR_VULKAN_TARGET_GOOD} ${PVR_GLES_TARGET_GOOD}) set_target_properties(${pvr_target} PROPERTIES FOLDER Samples) endforeach() foreach(pvr_target ${PVR_TARGET_OTHER} ${PVR_VULKAN_TARGET_OTHER} ${PVR_GLES_TARGET_OTHER}) set_target_properties(${pvr_target} PROPERTIES FOLDER Samples/PowerVR-Build) endforeach() # Make angle target depend on PowerVR GL examples if (TARGET angle) foreach(pvr_target ${PVR_GLES_TARGET}) add_dependencies(angle ${pvr_target}) endforeach() endif() endif() if(BUILD_VULKAN_WRAPPER) if (NOT TARGET glslang) add_subdirectory(${THIRD_PARTY_DIR}/glslang) endif() add_subdirectory(${TESTS_DIR}/VulkanWrapper) # Add VulkanWrapper target endif() if(SWIFTSHADER_BUILD_TESTS) add_subdirectory(${TESTS_DIR}/ReactorUnitTests) # Add ReactorUnitTests target add_subdirectory(${TESTS_DIR}/GLESUnitTests) # Add gles-unittests target add_subdirectory(${TESTS_DIR}/MathUnitTests) # Add math-unittests target add_subdirectory(${TESTS_DIR}/SystemUnitTests) # Add system-unittests target endif() if(SWIFTSHADER_BUILD_BENCHMARKS) if (NOT TARGET benchmark::benchmark) set(BENCHMARK_ENABLE_TESTING FALSE CACHE BOOL FALSE FORCE) add_subdirectory(${THIRD_PARTY_DIR}/benchmark) set_target_properties(benchmark PROPERTIES FOLDER "third_party") set_target_properties(benchmark_main PROPERTIES FOLDER "third_party") endif() add_subdirectory(${TESTS_DIR}/ReactorBenchmarks) # Add ReactorBenchmarks target add_subdirectory(${TESTS_DIR}/SystemBenchmarks) # Add system-benchmarks target add_subdirectory(${TESTS_DIR}/VulkanBenchmarks) # Add VulkanBenchmarks target endif() if(SWIFTSHADER_BUILD_TESTS AND SWIFTSHADER_BUILD_VULKAN) add_subdirectory(${TESTS_DIR}/VulkanUnitTests) # Add VulkanUnitTests target endif()