# # Brisk # # Cross-platform application framework # -------------------------------------------------------------- # # Copyright (C) 2025 Brisk Developers # # This file is part of the Brisk library. # # Brisk is dual-licensed under the GNU General Public License, version 2 (GPL-2.0+), and a commercial license. You may # use, modify, and distribute this software under the terms of the GPL-2.0+ license if you comply with its conditions. # # You should have received a copy of the GNU General Public License along with this program. If not, see # . # # If you do not wish to be bound by the GPL-2.0+ license, you must purchase a commercial license. For commercial # licensing options, please visit: https://brisklib.com # cmake_minimum_required(VERSION 3.22) if (NOT BRISK_ROOT) set(BRISK_ROOT ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "" FORCE) endif () include(cmake/init.cmake) file(STRINGS ${CMAKE_CURRENT_LIST_DIR}/include/brisk/core/Version.hpp BRISK_VERSION REGEX "#define BRISK_VERSION_(MINOR|MAJOR|PATCH)") string(REGEX MATCHALL "[0-9]+" BRISK_VERSION_MATCH ${BRISK_VERSION}) string(REPLACE ";" "." BRISK_VERSION "${BRISK_VERSION_MATCH}") project( brisk VERSION ${BRISK_VERSION} LANGUAGES CXX C) if (WIN32 AND NOT MSVC) message(FATAL_ERROR "Brisk requires MSVC or an MSVC-compatible compiler (e.g., clang-cl) on Windows") endif () if (MSVC) add_compile_options(-Zc:inline) add_compile_options($<$>:-Gy>) add_link_options($<$>:-OPT:REF> $<$>:-OPT:ICF>) endif () get_directory_property(BRISK_PARENT_DIR PARENT_DIRECTORY) if (NOT BRISK_PARENT_DIR) set(BRISK_STANDALONE TRUE) endif () if (DEBUG_CMAKE) get_cmake_property(VARS VARIABLES) list(SORT VARS) foreach (VAR ${VARS}) message(STATUS "${VAR}=${${VAR}}") endforeach () endif () option(BRISK_LTO ON "Use Link Time Optimization in Release builds") option(BRISK_BROTLI "Enable Brotli compression" ON) cmake_dependent_option(BRISK_WEBGPU "Enable WebGPU" OFF "WIN32" ON) cmake_dependent_option(BRISK_D3D11 "Enable D3D11 backend (Windows only)" ON "WIN32" OFF) option(BRISK_ICU "Link to ICU by default for full Unicode support" ON) option(BRISK_LOG_TO_STDERR "Write log output to stderr (Windows-specific)" OFF) option(BRISK_INTERACTIVE_TESTS "Enable interactive tests" OFF) option(BRISK_RTTI "Enable RTTI for Brisk builds" ON) option(BRISK_EXCEPTIONS "Enable C++ exceptions for Brisk builds" ON) message(STATUS "BRISK_D3D11: ${BRISK_D3D11}") message(STATUS "BRISK_WEBGPU: ${BRISK_WEBGPU}") if (NOT BRISK_D3D11 AND NOT BRISK_WEBGPU) message(FATAL_ERROR "Either BRISK_D3D11 or BRISK_WEBGPU must be defined, or both") endif () if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) set(TESTS_AND_EXAMPLES ON) else () set(TESTS_AND_EXAMPLES OFF) endif () option(BRISK_TESTS "Enable Brisk tests building" ${TESTS_AND_EXAMPLES}) option(BRISK_EXAMPLES "Enable Brisk examples building" ${TESTS_AND_EXAMPLES}) if (BRISK_LTO AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options($<$:-flto=thin>) endif () if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") add_compile_options(-utf-8) endif () set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) if (WIN32 AND BRISK_GENERATE_MAP) add_link_options(/Map) endif () if (BRISK_SAN) add_compile_options(-fsanitize=${BRISK_SAN}) add_link_options(-fsanitize=${BRISK_SAN}) endif () if (NOT BRISK_RTTI) if (MSVC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) add_compile_options(/GR-) else () add_compile_options(-fno-rtti) endif () endif () if (NOT BRISK_EXCEPTIONS) if (MSVC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) add_compile_options(/EHs-c-) else () add_compile_options(-fno-exceptions) endif () endif () set(DEPS_DIR "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}" CACHE STRING "DEPS_DIR") if (WIN32) set(PLATFORM_SPECIFIC_CPP "_Windows.cpp") elseif (APPLE) set(PLATFORM_SPECIFIC_CPP "_Darwin.mm") else () set(PLATFORM_SPECIFIC_CPP "_Linux.cpp") endif () file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/licenses.txt" "") include(GNUInstallDirs) include(cmake/add_autotests.cmake) include(cmake/scripts/compile_resources.cmake) include(cmake/scripts/setup_executable.cmake) include(cmake/scripts/metadata.cmake) if (BRISK_LOG_TO_STDERR) add_compile_definitions(BRISK_LOG_TO_STDERR=1) endif () include(cmake/add_license.cmake) file(GLOB_RECURSE LICENSE_LIST ${DEPS_DIR}/share/copyright) # CONFIGURE_DEPENDS foreach (license_path ${LICENSE_LIST}) get_filename_component(PKG_PATH ${license_path} DIRECTORY) get_filename_component(PKG_NAME ${PKG_PATH} NAME) add_license(${PKG_NAME} ${license_path}) endforeach () set(BRISK_RESOURCES_DIR ${PROJECT_SOURCE_DIR}/resources) set(FONTS_DIR ${BRISK_RESOURCES_DIR}/fonts) set(IMAGES_DIR ${BRISK_RESOURCES_DIR}/images) if (NOT BRISK_DBG_SUFFIX) set(BRISK_DBG_SUFFIX "/debug" CACHE STRING "") endif () add_subdirectory(src) add_library(brisk-executable INTERFACE) set_property(TARGET brisk-executable PROPERTY EXPORT_NAME Executable) add_library(Brisk::Executable ALIAS brisk-executable) if (WIN32) target_sources( brisk-executable INTERFACE $$>/include/brisk/window/internal/Windows.manifest ) endif () if (BRISK_TESTS) set(TESTS_GRAPHICS_LIBS) set(TESTS_GRAPHICS_DEFS) find_package(glfw3 CONFIG) if (glfw3_FOUND) message(STATUS "GLFW3 is found. It will be used for interactive tests") list(APPEND TESTS_GRAPHICS_LIBS glfw) list(APPEND TESTS_GRAPHICS_DEFS HAVE_GLFW3) else () message(STATUS "GLFW3 is not found, skipping interactive tests") endif () file(GLOB TESTS_CORE ${CMAKE_CURRENT_SOURCE_DIR}/src/core/*_test.cpp) file(GLOB TESTS_NETWORK ${CMAKE_CURRENT_SOURCE_DIR}/src/network/*_test.cpp) file(GLOB TESTS_GRAPHICS ${CMAKE_CURRENT_SOURCE_DIR}/src/graphics/*_test.cpp) file(GLOB TESTS_WINDOW ${CMAKE_CURRENT_SOURCE_DIR}/src/window/*_test.cpp) file(GLOB TESTS_GUI ${CMAKE_CURRENT_SOURCE_DIR}/src/gui/*_test.cpp) file(GLOB TESTS_WIDGETS ${CMAKE_CURRENT_SOURCE_DIR}/src/widgets/*_test.cpp) enable_testing() add_autotests(core SOURCES ${TESTS_CORE} LIBRARIES brisk-core) add_autotests(network SOURCES ${TESTS_NETWORK} LIBRARIES brisk-network) add_autotests( graphics SOURCES ${TESTS_GRAPHICS} LIBRARIES brisk-graphics brisk-i18n-icu ${TESTS_GRAPHICS_LIBS} DEFINITIONS ${TESTS_GRAPHICS_DEFS}) add_autotests(window SOURCES ${TESTS_WINDOW} LIBRARIES brisk-window brisk-i18n-icu) add_autotests(gui SOURCES ${TESTS_GUI} LIBRARIES brisk-gui brisk-i18n-icu) add_autotests(widgets SOURCES ${TESTS_WIDGETS} LIBRARIES brisk-widgets brisk-i18n-icu) endif () if (BRISK_EXAMPLES) add_subdirectory(examples) endif () install(DIRECTORY include/brisk DESTINATION include) include(CMakePackageConfigHelpers) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/BriskConfigVersion.cmake VERSION ${BRISK_VERSION} COMPATIBILITY SameMinorVersion) set(BRISK_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/brisk" CACHE STRING "Path to Brisk CMake files") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/BriskConfigVersion.cmake DESTINATION ${BRISK_INSTALL_CMAKEDIR}) configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/BriskConfig.cmake INSTALL_DESTINATION "lib/cmake/brisk") set(EXTRA_INSTALL_TARGETS) if (TARGET brisk-renderer-d3d11) list(APPEND EXTRA_INSTALL_TARGETS brisk-renderer-d3d11) endif () if (TARGET brisk-renderer-webgpu) list(APPEND EXTRA_INSTALL_TARGETS brisk-renderer-webgpu) endif () install( TARGETS brisk-core brisk-graphics brisk-network brisk-window brisk-gui brisk-widgets brisk-executable brisk-i18n brisk-i18n-icu ${EXTRA_INSTALL_TARGETS} EXPORT BriskTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}$<$:${BRISK_DBG_SUFFIX}> LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}$<$:${BRISK_DBG_SUFFIX}> RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}$<$:${BRISK_DBG_SUFFIX}>) install(DIRECTORY cmake/scripts/ DESTINATION "${BRISK_INSTALL_CMAKEDIR}/scripts") install( FILES src/core/Deps.cmake RENAME Core.cmake DESTINATION "${BRISK_INSTALL_CMAKEDIR}/deps") install( FILES src/graphics/Deps.cmake RENAME Graphics.cmake DESTINATION "${BRISK_INSTALL_CMAKEDIR}/deps") install( FILES src/network/Deps.cmake RENAME Network.cmake DESTINATION "${BRISK_INSTALL_CMAKEDIR}/deps") install( FILES src/window/Deps.cmake RENAME Window.cmake DESTINATION "${BRISK_INSTALL_CMAKEDIR}/deps") install( FILES src/gui/Deps.cmake RENAME Gui.cmake DESTINATION "${BRISK_INSTALL_CMAKEDIR}/deps") install(DIRECTORY resources/ DESTINATION "resources") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/BriskConfig.cmake DESTINATION "${BRISK_INSTALL_CMAKEDIR}") install( EXPORT BriskTargets NAMESPACE Brisk:: DESTINATION "${BRISK_INSTALL_CMAKEDIR}" CONFIGURATIONS Debug Release) set(DEP_HASH_SILENT ON) include(cmake/dep-hash.cmake) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Package-README.md.in ${CMAKE_CURRENT_BINARY_DIR}/Package-README.md) write_file(${CMAKE_CURRENT_BINARY_DIR}/DEP_HASH ${DEP_HASH}) write_file(${CMAKE_CURRENT_BINARY_DIR}/VCPKG_TARGET_TRIPLET ${VCPKG_TARGET_TRIPLET}) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/Package-README.md RENAME README.md DESTINATION .) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/DEP_HASH ${CMAKE_CURRENT_BINARY_DIR}/VCPKG_TARGET_TRIPLET DESTINATION ${BRISK_INSTALL_CMAKEDIR}) if (BRISK_VERIFY_HEADERS) function (create_header_object_library library_name source_dir binary_dir link_libraries) # Find all header files recursively file(GLOB_RECURSE header_files "${source_dir}/*.hpp" "${source_dir}/*.h") list(FILTER header_files EXCLUDE REGEX "\\.inc\\.") # Create a list to store generated cpp files set(generated_cpp_files "") # Create binary directory if it doesn't exist file(MAKE_DIRECTORY ${binary_dir}) # Process each header file foreach (header_file ${header_files}) # Get the relative path from source_dir to header_file file(RELATIVE_PATH relative_path ${source_dir} ${header_file}) # Get the filename without extension get_filename_component(header_name ${relative_path} NAME_WE) # Get the directory path (if any) get_filename_component(header_dir ${relative_path} PATH) # Create a unique filename by incorporating the directory structure if (header_dir) # Replace path separators with underscores and create unique name string(REPLACE "/" "_" unique_prefix "${header_dir}") set(unique_name "${unique_prefix}_${header_name}") else () set(unique_name "${header_name}") endif () # Create the corresponding cpp filename set(cpp_file "${binary_dir}/${unique_name}_generated.cpp") # Generate the cpp file that includes the header using absolute path file( GENERATE OUTPUT ${cpp_file} CONTENT "#include \"${header_file}\"\n") # Add to list of generated files list(APPEND generated_cpp_files ${cpp_file}) endforeach () # Create object library from generated cpp files if (generated_cpp_files) add_library(${library_name} OBJECT ${generated_cpp_files}) target_link_libraries(${library_name} PUBLIC ${link_libraries}) else () message(WARNING "No header files found in ${source_dir}") endif () endfunction () create_header_object_library(inc-test-core ${CMAKE_SOURCE_DIR}/include/brisk/core ${CMAKE_BINARY_DIR}/inc-core brisk-core) create_header_object_library(inc-test-graphics ${CMAKE_SOURCE_DIR}/include/brisk/graphics ${CMAKE_BINARY_DIR}/inc-graphics brisk-graphics) create_header_object_library(inc-test-network ${CMAKE_SOURCE_DIR}/include/brisk/network ${CMAKE_BINARY_DIR}/inc-network brisk-network) create_header_object_library(inc-test-window ${CMAKE_SOURCE_DIR}/include/brisk/window ${CMAKE_BINARY_DIR}/inc-window brisk-window) create_header_object_library(inc-test-gui ${CMAKE_SOURCE_DIR}/include/brisk/gui ${CMAKE_BINARY_DIR}/inc-gui brisk-gui) create_header_object_library(inc-test-widgets ${CMAKE_SOURCE_DIR}/include/brisk/widgets ${CMAKE_BINARY_DIR}/inc-widgets brisk-widgets) endif ()