# Copyright 2015-2023 The Khronos Group Inc. # Copyright 2022-2023 RasterGrid Kft. # SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.22) include(CMakePrintHelpers) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules/") find_package(Bash REQUIRED) include(cmake/version.cmake) if(POLICY CMP0149) # Ignore CMAKE_SYSTEM_VERSION and select either latest available # Windows SDK or that specified in WindowsSDKVersion environment # variable Needed because OLD policy picks SDK that matches # system version, CI uses Windows Server 2022 and its matching # SDK lacks the arm64 glu32.lib which causes builds to fail. # MUST be set before project() command. cmake_policy(SET CMP0149 NEW) endif() include(CMakeDependentOption) include(cmake/codesign.cmake) include(cmake/cputypetest.cmake) # OPTIONS # N.B IOS and, in the Darwin case, CMAKE_SYSTEM_NAME are not set # until after the project() command. The latter is most strange. if(APPLE) if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS") set( APPLE_LOCKED_OS ON ) else() set( APPLE_MAC_OS ON ) endif() endif() option( KTX_FEATURE_DOC "Create KTX documentation." OFF ) option( KTX_FEATURE_JNI "Create Java bindings for libktx." OFF ) option( KTX_FEATURE_PY "Create Python source distribution." OFF ) option( KTX_FEATURE_TESTS "Create unit tests." ON ) option( KTX_FEATURE_TOOLS_CTS "Enable KTX CLI Tools CTS tests (requires CTS submodule)." OFF ) option( KTX_FEATURE_ETC_UNPACK "ETC decoding support." ON ) if(KTX_FEATURE_TOOLS_CTS AND NOT KTX_FEATURE_TOOLS) message(WARNING "KTX_FEATURE_TOOLS is not set -> disabling KTX_FEATURE_TOOLS_CTS.") set(KTX_FEATURE_TOOLS_CTS "OFF") endif() if(POLICY CMP0127) # cmake_dependent_option() supports full Condition Syntax. Introduced in # 3.22. Not all build environments have 3.22+. Set policy to avoid warning. # Seems the parens in the match string trigger the warning. cmake_policy(SET CMP0127 NEW) endif() CMAKE_DEPENDENT_OPTION( KTX_EMBED_BITCODE "Embed bitcode in binaries." OFF "APPLE AND APPLE_LOCKED_OS" OFF ) option( KTX_FEATURE_KTX1 "Enable KTX 1 support." ON ) option( KTX_FEATURE_KTX2 "Enable KTX 2 support." ON ) option( KTX_FEATURE_VK_UPLOAD "Enable Vulkan texture upload." ON ) option( KTX_FEATURE_GL_UPLOAD "Enable OpenGL texture upload." ON ) # When a variable like this is set via CMakeUserPresets.json, it no longer # shows the selectable options provided by the STRINGS property. set( KTX_FEATURE_LOADTEST_APPS "" CACHE STRING "Load test apps test the upload feature by displaying various KTX textures. Select which to create. \"OpenGL\" includes OpenGL ES." ) set_property( CACHE KTX_FEATURE_LOADTEST_APPS PROPERTY STRINGS OFF OpenGL Vulkan OpenGL+Vulkan ) if(NOT KTX_FEATURE_LOADTEST_APPS MATCHES OFF) set(VCPKG_MANIFEST_FEATURES loadtests) if (KTX_FEATURE_LOADTEST_APPS MATCHES OpenGL) list(APPEND VCPKG_MANIFEST_FEATURES glloadtests) endif() if(CMAKE_SYSTEM_NAME STREQUAL "iOS") # Explicitly set the triplet to avoid potential trouble. # Automatic triplet selection in CI, which runs on x86_64, selects # x64-ios, which is the simulator. Works locally on arm64 so # presumably running on an x86_64 is the reason. set(VCPKG_TARGET_TRIPLET arm64-ios) endif() endif() option( KTX_GENERATE_VK_FILES "Include targets for generating VkFormat related files. For project developers only." OFF ) mark_as_advanced(FORCE KTX_GENERATE_VK_FILES) # Platform specific settings if(APPLE) # Signing set(XCODE_CODE_SIGN_IDENTITY "Development" CACHE STRING "Xcode code sign ID") set(XCODE_DEVELOPMENT_TEAM "" CACHE STRING "Xcode development team ID") set(PRODUCTBUILD_IDENTITY_NAME "" CACHE STRING "productbuild identity name") set(PRODUCTBUILD_KEYCHAIN_PATH "" CACHE FILEPATH "pkgbuild keychain file") if(APPLE_LOCKED_OS) set(XCODE_PROVISIONING_PROFILE_SPECIFIER "" CACHE STRING "Xcode provisioning profile specifier") endif() # Deployment # When changing the target you must also edit the triplet files in # vcpkg-triplets to reflect the new target. if(APPLE_MAC_OS) set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "macOS Deployment Target") elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "tvOS") set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "iOS/tvOS Deployment Target") set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH NO) elseif(CMAKE_SYSTEM_NAME STREQUAL "visionOS") set(CMAKE_OSX_DEPLOYMENT_TARGET "1.0" CACHE STRING "visionOS Deployment Target") endif() endif() if(WIN32) if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.18.0") include(KtxDependentVariable) # Signing set(CODE_SIGN_KEY_VAULT "" CACHE STRING "Name of the vault to search for signing certificate. Enables related code signing variables when set.") set_property(CACHE CODE_SIGN_KEY_VAULT PROPERTY STRINGS "" Azure Machine User) # Common signing variables KTX_DEPENDENT_VARIABLE( CODE_SIGN_TIMESTAMP_URL STRING "URL of timestamp server for code signing. Signed code should be timestamped so the signature will remain valid even after the certificate expires." "" "CODE_SIGN_KEY_VAULT" "" ) # Variables for signing with local certificate. KTX_DEPENDENT_VARIABLE( LOCAL_KEY_VAULT_SIGNING_IDENTITY STRING "Subject Name of Windows code signing certificate. Displayed in 'Issued To' field of cert{lm,mgr}. Overriden by LOCAL_KEY_VAULT_CERTIFICATE_THUMBPRINT." "" "CODE_SIGN_KEY_VAULT;${CODE_SIGN_KEY_VAULT} MATCHES Machine OR ${CODE_SIGN_KEY_VAULT} MATCHES User" "" ) KTX_DEPENDENT_VARIABLE( LOCAL_KEY_VAULT_CERTIFICATE_THUMBPRINT STRING "Thumbprint of the certificate to use. Use this instead of LOCAL_KEY_VAULT_SIGNING_IDENTITY when you have multiple certificates with the same identity. Overrides LOCAL_KEY_VAULT_SIGNING_IDENTITY." "" "CODE_SIGN_KEY_VAULT;${CODE_SIGN_KEY_VAULT} MATCHES Machine OR ${CODE_SIGN_KEY_VAULT} MATCHES User" "" ) # Variables for signing with certificate from Azure KTX_DEPENDENT_VARIABLE( AZURE_KEY_VAULT_URL STRING "The URL of your Azure key vault." "" "CODE_SIGN_KEY_VAULT;${CODE_SIGN_KEY_VAULT} MATCHES Azure" "" ) KTX_DEPENDENT_VARIABLE( AZURE_KEY_VAULT_CERTIFICATE STRING "The name of the certificate in Azure Key Vault." "" "CODE_SIGN_KEY_VAULT;${CODE_SIGN_KEY_VAULT} MATCHES Azure" "" ) KTX_DEPENDENT_VARIABLE( AZURE_KEY_VAULT_CLIENT_ID STRING "The id of an application (Client) registered with Azure that has permission to access the certificate." "" "CODE_SIGN_KEY_VAULT;${CODE_SIGN_KEY_VAULT} MATCHES Azure" "" ) KTX_DEPENDENT_VARIABLE( AZURE_KEY_VAULT_TENANT_ID STRING "The id of the Azure Active Directory (Tenant) holding the Client." "" "CODE_SIGN_KEY_VAULT;${CODE_SIGN_KEY_VAULT} MATCHES Azure" "" ) KTX_DEPENDENT_VARIABLE( AZURE_KEY_VAULT_CLIENT_SECRET STRING "The secret to authenticate access to the Client." "" "CODE_SIGN_KEY_VAULT;${CODE_SIGN_KEY_VAULT} MATCHES Azure" "" ) else() # KTX_DEPENDENT_VARIABLE won't work. Force disable signing. unset(CODE_SIGN_KEY_VAULT CACHE) endif() endif() set(bitness 64) if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8 OR FORCE32) set(bitness 32) endif() option( KTX_WERROR "Make all warnings in KTX code into errors." OFF) # After most option settings so settings can be used to affect vcpkg. project(KTX-Software VERSION ${KTX_VERSION} DESCRIPTION "Libraries and tools to create and read KTX image texture files." ) include(GNUInstallDirs) # Must be after project. include(CTest) # " set_target_processor_type(CPU_ARCHITECTURE) # Must be after project. if (CPU_ARCHITECTURE STREQUAL x86) message(FATAL_ERROR "This project cannot be built for x86 cpu.") endif() CMAKE_DEPENDENT_OPTION( BASISU_SUPPORT_SSE "Compile with SSE support so applications can choose to use it." ON "NOT CMAKE_OSX_ARCHITECTURES STREQUAL \"$(ARCHS_STANDARD)\"; CPU_ARCHITECTURE STREQUAL x86_64" OFF ) CMAKE_DEPENDENT_OPTION( BASISU_SUPPORT_OPENCL "Compile with OpenCL support so applications can choose to use it." OFF "OpenCL_FOUND OR WIN32" OFF ) if(BASISU_SUPPORT_OPENCL) find_package(OpenCL) # Must be after project as needs language defined. endif() if(BASISU_SUPPORT_OPENCL AND WIN32 AND NOT OpenCL_FOUND) # To avoid fiddly setting up of OpenCL on Windows CI VMs, use copy in repo. set(OpenCL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/basisu/opencl" # FORCE to override *-NOTFOUND set by the failed find. CACHE PATH "" FORCE ) set(OpenCL_LIBRARY "${CMAKE_CURRENT_SOURCE_DIR}/external/basisu/opencl/lib/OpenCL64.lib" CACHE FILEPATH "" FORCE ) set(OpenCL_INCLUDE_DIRS ${OpenCL_INCLUDE_DIR}) set(OpenCL_LIBRARIES ${OpenCL_LIBRARY}) endif() # Windows Store Compatibility. # In this case CMAKE_SYSTEM_NAME is not set until after project. if (${CMAKE_SYSTEM_NAME} STREQUAL "WindowsStore") # Disable OpenGL upload on Universal Windows Platform set(KTX_FEATURE_GL_UPLOAD OFF) endif() # Uses IOS, so included after project to avoid modifying it. if(KTX_GENERATE_VK_FILES) include(cmake/mkvk.cmake) endif() # EMSCRIPTEN is not set until project so all these must be after. if(KTX_FEATURE_TESTS AND (APPLE_LOCKED_OS OR ANDROID OR EMSCRIPTEN)) message(WARNING "Building unit tests for Android, Apple locked OSes or the web is not supported -> disabling KTX_FEATURE_TESTS.") set(KTX_FEATURE_TESTS "OFF") endif() if(KTX_FEATURE_TOOLS_CTS AND NOT KTX_FEATURE_TESTS) message(WARNING "KTX_FEATURE_TESTS is not set -> disabling KTX_FEATURE_TOOLS_CTS.") set(KTX_FEATURE_TOOLS_CTS "OFF") endif() if(APPLE_LOCKED_OS OR EMSCRIPTEN) set( LIB_TYPE_DEFAULT OFF ) else() set( LIB_TYPE_DEFAULT ON ) endif() option(BUILD_SHARED_LIBS "Create shared libraries (static otherwise)." ${LIB_TYPE_DEFAULT} ) # Used to reset BUILD_SHARED_LIBS after forcing static builds set(BUILD_SHARED_LIBS_RESET ${BUILD_SHARED_LIBS}) CMAKE_DEPENDENT_OPTION( KTX_FEATURE_TOOLS "Create KTX tools" ON "NOT APPLE_LOCKED_OS;NOT ANDROID;NOT EMSCRIPTEN" OFF ) if(UNIX AND NOT APPLE AND NOT EMSCRIPTEN AND NOT ANDROID) set(LINUX TRUE) endif() if(EMSCRIPTEN) set( KTX_FEATURE_VK_UPLOAD OFF ) endif() if(NOT BUILD_SHARED_LIBS) set(LIB_TYPE STATIC) else() if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR EMSCRIPTEN) message(SEND_ERROR "Library type cannot be shared for the current platform. Set BUILD_SHARED_LIBS to OFF!") endif() set(LIB_TYPE SHARED) endif() # Global compile & link options including optimization flags if(MSVC) add_compile_options( /W4;$<$:/WX> ) add_compile_options( $,/Gz,/O2> ) # Enable UTF-8 support add_compile_options( $<$:/utf-8> ) add_compile_options( $<$:/utf-8> ) elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") add_compile_options( -Wall -Wextra $<$:-Werror>) add_compile_options( $,-O0$-g,-O3> ) if(EMSCRIPTEN) add_link_options( $,-gsource-map,-O3> ) else() add_link_options( $,-g,-O3> ) endif() else() message(FATAL_ERROR "${CMAKE_CXX_COMPILER_ID} not yet supported.") endif() # To improve output determinism enable precise floating point operations globally # This code was based on external/astc-encoder/Source/cmake_core.cmake # For Visual Studio prior to 2022 (compiler < 19.30) /fp:strict # For Visual Studio 2022 (compiler >= 19.30) /fp:precise # For Visual Studio 2022 ClangCL has enabled contraction by default, # which is the same as standard clang, so behaves differently to # CL.exe. Use the -Xclang argument to access GNU-style switch to # control contraction and force disable. # On CMake 3.25 or older CXX_COMPILER_FRONTEND_VARIANT is not always set if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "") set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "${CMAKE_CXX_COMPILER_ID}") endif() #cmake_print_variables( # CMAKE_CXX_COMPILER_ID # CMAKE_CXX_COMPILER_VERSION # CMAKE_CXX_COMPILER_FRONTEND_VARIANT #) # Compiler accepts MSVC-style command line options set(is_msvc_fe "$") # Compiler accepts GNU-style command line options set(is_gnu_fe1 "$") # Compiler accepts AppleClang-style command line options, which is also GNU-style set(is_gnu_fe2 "$") # Compiler accepts GNU-style command line options set(is_gnu_fe "$") #add_custom_target(debug_isgnufe1 COMMAND ${CMAKE_COMMAND} -E echo "is_gnufe1_exp = $") # Compiler is Visual Studio cl.exe set(is_msvccl "$>") # Compiler is Visual Studio clangcl.exe set(is_clangcl "$>") # Compiler is upstream clang with the standard frontend set(is_clang "$>") add_compile_options( $<$,19.30>>:/fp:strict> $<$,19.30>>:/fp:precise> $<${is_clangcl}:/fp:precise> $<$,14.0.0>>:-Xclang$-ffp-contract=off> $<$,10.0.0>>:-ffp-model=precise> $<${is_gnu_fe}:-ffp-contract=off> # Hide noise from clang and clangcl 20 warning the 2nd fp option changes # one of the settings made the first. $<$,20.0.0>>:-Wno-overriding-option> ) #add_custom_target(debug_gnufe_ffpcontract COMMAND ${CMAKE_COMMAND} -E echo "ffp_contract = $<${is_gnu_fe}:-ffp-contract=off>") set(KTX_BUILD_DIR "${CMAKE_BINARY_DIR}") set(KTX_MAIN_SRC include/KHR/khr_df.h include/ktx.h lib/astc_codec.cpp lib/basis_sgd.h lib/basis_transcode.cpp lib/miniz_wrapper.cpp external/basisu/transcoder/basisu_containers.h external/basisu/transcoder/basisu_containers_impl.h external/basisu/transcoder/basisu_file_headers.h external/basisu/transcoder/basisu_transcoder_internal.h external/basisu/transcoder/basisu_transcoder_uastc.h external/basisu/transcoder/basisu_transcoder.cpp external/basisu/transcoder/basisu_transcoder.h external/basisu/transcoder/basisu.h external/basisu/zstd/zstd.c lib/checkheader.c external/dfdutils/createdfd.c external/dfdutils/colourspaces.c external/dfdutils/dfd.h external/dfdutils/interpretdfd.c external/dfdutils/printdfd.c external/dfdutils/queries.c external/dfdutils/vk2dfd.c external/dfdutils/vk2dfd.inl external/dfdutils/vulkan/vk_platform.h external/dfdutils/vulkan/vulkan_core.h lib/etcunpack.cxx lib/filestream.c lib/filestream.h lib/formatsize.h lib/gl_format.h lib/hashlist.c lib/info.c lib/ktxint.h lib/memstream.c lib/memstream.h lib/strings.c lib/swap.c lib/texture.c lib/texture.h lib/texture2.c lib/texture2.h lib/texture_funcs.inl lib/uthash.h lib/vk2gl.h lib/vk_format.h lib/vkFormat2glFormat.inl lib/vkFormat2glInternalFormat.inl lib/vkFormat2glType.inl lib/vkformat_check.c lib/vkformat_check_variant.c lib/vkformat_enum.h lib/vkformat_str.c lib/vkformat_typesize.c ) if (KTX_FEATURE_ETC_UNPACK) list(APPEND KTX_MAIN_SRC external/etcdec/etcdec.cxx ) endif() set(BASISU_ENCODER_CXX_SRC external/basisu/encoder/basisu_backend.cpp external/basisu/encoder/basisu_backend.h external/basisu/encoder/basisu_basis_file.cpp external/basisu/encoder/basisu_basis_file.h external/basisu/encoder/basisu_bc7enc.cpp external/basisu/encoder/basisu_bc7enc.h external/basisu/encoder/basisu_comp.cpp external/basisu/encoder/basisu_comp.h external/basisu/encoder/basisu_enc.cpp external/basisu/encoder/basisu_enc.h external/basisu/encoder/basisu_etc.cpp external/basisu/encoder/basisu_etc.h external/basisu/encoder/basisu_frontend.cpp external/basisu/encoder/basisu_frontend.h external/basisu/encoder/basisu_gpu_texture.cpp external/basisu/encoder/basisu_gpu_texture.h external/basisu/encoder/basisu_kernels_declares.h external/basisu/encoder/basisu_kernels_imp.h external/basisu/encoder/basisu_kernels_sse.cpp external/basisu/encoder/basisu_miniz.h external/basisu/encoder/basisu_opencl.cpp external/basisu/encoder/basisu_opencl.h external/basisu/encoder/basisu_pvrtc1_4.cpp external/basisu/encoder/basisu_pvrtc1_4.h external/basisu/encoder/basisu_resample_filters.cpp external/basisu/encoder/basisu_resampler_filters.h external/basisu/encoder/basisu_resampler.cpp external/basisu/encoder/basisu_resampler.h external/basisu/encoder/basisu_ssim.cpp external/basisu/encoder/basisu_ssim.h external/basisu/encoder/basisu_uastc_enc.cpp external/basisu/encoder/basisu_uastc_enc.h external/basisu/encoder/cppspmd_flow.h external/basisu/encoder/cppspmd_math.h external/basisu/encoder/cppspmd_math_declares.h external/basisu/encoder/cppspmd_sse.h external/basisu/encoder/cppspmd_type_aliases.h ) if(KTX_FEATURE_GL_UPLOAD) list(APPEND KTX_MAIN_SRC lib/gl_funclist.inl lib/gl_funcs.c lib/gl_funcs.h lib/glloader.c ) endif() if(APPLE OR LINUX OR WIN32) # By wrapping in generator expression we force multi configuration # generators (like Visual Studio, Xcode or Ninja multi-config) to # take the exact path and not change it. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${KTX_BUILD_DIR}/$>) if(APPLE OR LINUX) # Use a common RUNTIME_OUTPUT_DIR and LIBRARY_OUTPUT_DIR for all # targets so that the INSTALL RPATH we need for installed binaries # is functional in the build directory as well. INSTALL_RPATH cannot # be altered during install because that would break code signing # which happens after building. Therefore BUILD_WITH_INSTALL_RPATH # is necessary for working code signing. Although Linux code is not # yet being signed, make it symmetrical with macOS. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY $<1:${KTX_BUILD_DIR}/$>) set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) # Notes about install names, rpaths and code signing # -------------------------------------------------- # Changing the install name of a library by setting INSTALL_NAME_DIR # on a library target will invalidate the signature as it causes # cmake to run `install_name_tool` after building and signing. The # default install name is the library target's name prefixed by # `@rpath/`. With this, `dyld` will load the library provided it is # in one of the directories specified by a program's INSTALL_RPATH # or is in the directory part of a full-path name passed to `dlopen`. # # A bad signature in either executable or shared library is # indicated by the executable exiting with "Killed: 9". endif() endif() set(KTX_BASISU_INCLUDE_DIRS $ ) # Main library add_library( ktx ${LIB_TYPE} ${KTX_MAIN_SRC} ) # Read-only library add_library( ktx_read ${LIB_TYPE} ${KTX_MAIN_SRC} ) macro(common_libktx_settings target enable_write library_type) if(TARGET mkvk) # Creating vulkan headers only required after Vulkan Spec/SDK updates. add_dependencies(${target} mkvk) endif() set_target_properties(${target} PROPERTIES PUBLIC_HEADER # "${CMAKE_CURRENT_SOURCE_DIR}/include/ktx.h;${CMAKE_CURRENT_SOURCE_DIR}/include/KHR/khr_df.h" # Omit khr_df.h. Its installation has to be handled separately to # workaround CMake's failure to preserve the directory hierarchy. "${CMAKE_CURRENT_SOURCE_DIR}/include/ktx.h" VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "YES" ) if(APPLE_LOCKED_OS) set_target_properties(${target} PROPERTIES FRAMEWORK TRUE ) endif() if( NOT ${library_type} STREQUAL STATIC ) # Must not call this macro for static libs on Windows. To keep # the if test simple, never call it for static libs. On macOS # and iOS Xcode knows libs aren't signed so it would ignore the # settings made by this macro. set_code_sign(${target} "NOPPS") endif() target_compile_definitions( ${target} PUBLIC "$<$:_DEBUG;DEBUG>" PRIVATE LIBKTX SUPPORT_SOFTWARE_ETC_UNPACK=$ ) # C/C++ Standard # Need c11 for Unicode string literals target_compile_features(${target} PUBLIC c_std_11 cxx_std_11) # Compiler Warning Flags if(EMSCRIPTEN) target_compile_options(${target} PRIVATE -Wno-nested-anon-types -Wno-gnu-anonymous-struct ) else() target_compile_options(${target} PRIVATE # clang options $<$: -Wno-nested-anon-types -Wno-gnu-anonymous-struct > $<$: -Wno-cast-function-type > # not clang options $<$>: -Wno-pedantic > ) endif() target_include_directories( ${target} PUBLIC $ $ PRIVATE ${KTX_BASISU_INCLUDE_DIRS} external $ $ $ $ ) target_include_directories( ${target} SYSTEM PRIVATE $ $ ) if( ${library_type} STREQUAL STATIC ) target_compile_definitions(${target} PUBLIC KHRONOS_STATIC) endif() # To reduce size, don't support transcoding to ancient formats. target_compile_definitions(${target} PRIVATE BASISD_SUPPORT_FXT1=0) # TODO: make options for all formats and good per-platform defaults # - BASISD_SUPPORT_UASTC # - BASISD_SUPPORT_DXT1 (BC1) # - BASISD_SUPPORT_DXT5A (BC3/4/5) # - BASISD_SUPPORT_BC7 # - BASISD_SUPPORT_BC7_MODE5 # - BASISD_SUPPORT_PVRTC1 # - BASISD_SUPPORT_ETC2_EAC_A8 # - BASISD_SUPPORT_ASTC # - BASISD_SUPPORT_ATC # - BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY # - BASISD_SUPPORT_ETC2_EAC_RG11 # - BASISD_SUPPORT_FXT1 # - BASISD_SUPPORT_PVRTC2 if(WIN32) target_compile_definitions( ${target} PRIVATE # Only set dllexport when building a shared library. $<$:KTX_API=__declspec\(dllexport\)> # Code compiled with the versions shown defaults to a constexpr # std::mutex constructor and requires a mscvp140.dll of at least # version 14.40.33810.00 otherwise code creating a mutex # crashes mysteriously. Since many JVM installations bundle # their own version of the VC++ redistributables chances are # high they will not have a modern enough version so JNI modules # linked with libktx will crash when multiple threads are used, # as they are in the BasisU and ASTC encoders. # # To avoid this set a define to prevent the compiler using # constexpr mutex constructors. Remove this eventually after # in-use JVM installations have at least this VC runtime. Remove # also from ASTCENC_LIB_TARGET settings around line 1169. $<$,19.40.33811>>:_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR> $<$,17.0.3>>:_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR> PUBLIC # only for basisu_c_binding. BASISU_NO_ITERATOR_DEBUG_LEVEL ) # The generator automatically sets the needed VCLinker # option when a .def file is seen in sources. # The def files that we add have a different syntax depending on the ABI if(MINGW) target_sources( ${target} PRIVATE lib/internalexport_mingw.def $<${enable_write}:lib/internalexport_write_mingw.def> ) # Need these flags if mingw happens to target the ucrt (new) rather # than the legacy msvcrt. Otherwise tests will fail to run because # the necessary dlls will be missing. If we statically link # them instead it's fine. This does not cause any abberations if # the mingw toolchain targets msvcrt instead. target_link_options(${target} PUBLIC -static-libgcc -static-libstdc++) else() target_sources( ${target} PRIVATE lib/internalexport.def $<${enable_write}:lib/internalexport_write.def> ) endif() elseif(EMSCRIPTEN) target_compile_definitions(${target} PRIVATE # To reduce size, don't support transcoding to formats not # supported # by WebGL. BASISD_SUPPORT_ATC=0 BASISD_SUPPORT_PVRTC2=0 # Don't support higher quality mode to avoid 64k table. BASISD_SUPPORT_ASTC_HIGHER_OPAQUE_QUALITY=0 KTX_OMIT_VULKAN=1 ) target_link_options(${target} INTERFACE # "SHELL:-s ASSERTIONS=2" # "SHELL:-s SAFE_HEAP=1" # "SHELL:-s STACK_OVERFLOW_CHECK=2" "SHELL:-s ALLOW_MEMORY_GROWTH=1" "SHELL:-s MALLOC=emmalloc" "SHELL:-s FULL_ES3=1" "SHELL:-s GL_ENABLE_GET_PROC_ADDRESS=1" # For Emscripten 3.1.51+ ) endif() if(KTX_FEATURE_KTX1) target_compile_definitions(${target} PUBLIC KTX_FEATURE_KTX1) target_sources( ${target} PRIVATE lib/texture1.c lib/texture1.h ) endif() if(KTX_FEATURE_KTX2) target_compile_definitions(${target} PUBLIC KTX_FEATURE_KTX2) endif() if(WIN32) if(MINGW) # Check if the Threads package is provided; if using Mingw it MIGHT be find_package(Threads) if(Threads_FOUND AND CMAKE_USE_PTHREADS_INIT) target_compile_definitions(${target} PRIVATE WIN32_HAS_PTHREADS) target_link_libraries(${target} PRIVATE Threads::Threads) endif() endif() elseif(APPLE) if(KTX_EMBED_BITCODE) target_compile_options(${target} PRIVATE "-fembed-bitcode") endif() elseif(LINUX) find_package(Threads REQUIRED) target_link_libraries( ${target} PRIVATE dl Threads::Threads ) endif() if(KTX_FEATURE_VK_UPLOAD) target_sources( ${target} PRIVATE include/ktxvulkan.h lib/vk_funcs.c lib/vk_funcs.h lib/vkloader.c ) target_include_directories( ${target} PRIVATE $ $ ) get_target_property( KTX_PUBLIC_HEADER ${target} PUBLIC_HEADER ) list(APPEND KTX_PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/include/ktxvulkan.h) set_target_properties(${target} PROPERTIES PUBLIC_HEADER "${KTX_PUBLIC_HEADER}" ) else() target_compile_definitions( ${target} PRIVATE KTX_OMIT_VULKAN=1 ) endif() # Adding write capability to target ktx if(${enable_write}) target_sources( ${target} PRIVATE lib/basis_encode.cpp ${BASISU_ENCODER_CXX_SRC} lib/writer1.c lib/writer2.c ) target_include_directories( ${target} PRIVATE $ $ $<$:${OpenCL_INCLUDE_DIRS}> ) target_compile_definitions( ${target} PUBLIC KTX_FEATURE_WRITE PRIVATE # BASISD_SUPPORT_KTX2 has to be 1 to compile the encoder. We # don't use it. Hopefully it doesn't add too much code. We're using # the zstd encoder in basisu by explicitly including the file in our # source list. We don't need the related code in the encoder. BASISD_SUPPORT_KTX2_ZSTD=0 BASISD_SUPPORT_KTX2=1 $<$:BASISU_SUPPORT_SSE=1> $<$>:BASISU_SUPPORT_SSE=0> $<$:BASISU_SUPPORT_OPENCL=1> $<$>:BASISU_SUPPORT_OPENCL=0> ) target_compile_options( ${target} PRIVATE $<$,$>: -msse4.1 > ) if(EMSCRIPTEN) target_link_options( ${target} INTERFACE # Default 64kb not enough for encode_uastc. "SHELL:-s STACK_SIZE=96kb" ) endif() target_link_libraries( ${target} PRIVATE $<$:${OpenCL_LIBRARIES}> ) endif() endmacro(common_libktx_settings) common_libktx_settings(ktx 1 ${LIB_TYPE}) common_libktx_settings(ktx_read 0 ${LIB_TYPE}) if(KTX_FEATURE_JNI) add_subdirectory(interface/java_binding) endif() if(KTX_FEATURE_PY) add_subdirectory(interface/python_binding) endif() create_version_header(lib ktx) create_version_file() target_compile_definitions( ktx_read PRIVATE # We're reading the files ourselves so don't need Basis KTX v2 support. BASISD_SUPPORT_KTX2_ZSTD=0 BASISD_SUPPORT_KTX2=0 ) # helper function to append COMPILE_OPTIONS to source file properties # !! if SRCFILES is a list, remember to quote it !! # !! like add_source_file_compile_options("${MY_SRC_LIST}" "-Wall") !! # !! or add_source_file_compile_options("dir/foo.cpp;dir/bar.cpp" "-Wextra") !! function(add_source_file_compile_options SRCFILES OPTIONS) foreach(src_file ${SRCFILES}) get_source_file_property(cur_options "${src_file}" COMPILE_OPTIONS ) if(cur_options) set_source_files_properties( "${src_file}" PROPERTIES COMPILE_OPTIONS "${cur_options};${OPTIONS}" ) else() # if cur_options were undefined or empty ("") set_source_files_properties( "${src_file}" PROPERTIES COMPILE_OPTIONS "${OPTIONS}" ) endif() endforeach() endfunction() # Turn off these warnings until Rich fixes the occurences. # It it not clear to me if generator expressions can be used here # hence the long-winded way. if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") # Currently no need to disable any warnings in basisu code. Rich fixed them. elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set_source_files_properties( # It's too much work to discriminate which files need which warnings # disabled. ${BASISU_ENCODER_CXX_SRC} PROPERTIES COMPILE_OPTIONS "-fno-strict-aliasing;-Wno-sign-compare;-Wno-unused-variable;-Wno-class-memaccess;-Wno-misleading-indentation;-Wno-extra;-Wno-deprecated-copy;-Wno-parentheses" ) set_source_files_properties( external/basisu/transcoder/basisu_transcoder.cpp PROPERTIES COMPILE_OPTIONS "-fno-strict-aliasing;-Wno-sign-compare;-Wno-unused-function;-Wno-unused-variable;-Wno-class-memaccess;-Wno-maybe-uninitialized" ) if (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "11") if (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS "12" ) # Version 11 raises several stringop-overflow warnings in some # very hard to decipher code. They appear to be bogus based on # the facts that we have never seen a crash and version 12 no # longer raises the warnings. add_source_file_compile_options( external/basisu/encoder/basisu_comp.cpp "-Wno-stringop-overflow" ) endif() endif() if (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "12.0") # Version 12 newly raises this warning on basisu_uastc_enc.cpp. # There seems no way for the index calculated by the code at # line 326, where the error is raised, to be > the array length. # Also we have never seen any crashes. add_source_file_compile_options( external/basisu/encoder/basisu_uastc_enc.cpp "-Wno-stringop-overflow" ) endif() if (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "14.0") # Version 14 raises stringop-overflow on these files. add_source_file_compile_options( "external/basisu/transcoder/basisu_transcoder.cpp;external/basisu/encoder/basisu_bc7enc.cpp" "-Wno-stringop-overflow" ) endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") # Versions equivalency from https://en.wikipedia.org/wiki/Xcode#Xcode_11.x_-_14.x_(since_SwiftUI_framework)_2 if (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "14") set( clang_version ${CMAKE_CXX_COMPILER_VERSION}) elseif (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "13.1.0") set( clang_version "13.0.0") elseif (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "13.0.0") set( clang_version "12.0.0") elseif (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "12.0.5") set( clang_version "11.1.0") elseif (${CMAKE_CXX_COMPILER_VERSION} VERSION_EQUAL "12.0.0") set( clang_version "10.0.0") else() message(FATAL_ERROR "Unsupported AppleClang version") endif() else() set( clang_version ${CMAKE_CXX_COMPILER_VERSION} ) endif() # BEWARE: set_source_files_properties is not additive; it replaces. set_source_files_properties( ${BASISU_ENCODER_CXX_SRC} PROPERTIES COMPILE_OPTIONS "-fno-strict-aliasing" ) set_source_files_properties( external/basisu/transcoder/basisu_transcoder.cpp PROPERTIES COMPILE_OPTIONS "-fno-strict-aliasing" ) if (${clang_version} VERSION_GREATER_EQUAL "12.0.0") add_source_file_compile_options( external/basisu/encoder/basisu_kernels_sse.cpp "-Wno-unused-parameter;-Wno-deprecated-copy;-Wno-uninitialized-const-reference" ) else() add_source_file_compile_options( external/basisu/encoder/basisu_kernels_sse.cpp "-Wno-unused-parameter" ) endif() if (${clang_version} VERSION_GREATER_EQUAL "14.0") add_source_file_compile_options( "${BASISU_ENCODER_CXX_SRC}" "-Wno-sign-compare;-Wno-unused-variable;-Wno-unused-parameter;-Wno-deprecated-copy-with-user-provided-copy" ) add_source_file_compile_options( external/basisu/transcoder/basisu_transcoder.cpp "-Wno-sign-compare;-Wno-unused-function;-Wno-unused-variable" ) set_source_files_properties( external/basisu/zstd/zstd.c PROPERTIES COMPILE_OPTIONS "-Wno-unused-function" ) endif() else() message(FATAL_ERROR "${CMAKE_CXX_COMPILER_ID} not yet supported.") endif() # Retrieve the final set of properties for use by the transcodetests. # We do this because the CMake feature that would allow the transcodetests # target to retrieve these from the ktx target is not available until # v18 and we still need to work with v16 in the Emscripten Docker image. get_source_file_property(transcoder_options external/basisu/transcoder/basisu_transcoder.cpp COMPILE_OPTIONS ) get_source_file_property(zstd_options external/basisu/zstd/zstd.c COMPILE_OPTIONS) if(EMSCRIPTEN) set( KTX_EM_COMMON_LINK_FLAGS --bind "SHELL:-s MODULARIZE=1" "SHELL:-s EXPORTED_RUNTIME_METHODS=[\'GL,HEAP8\']" "SHELL:-s GL_PREINITIALIZED_CONTEXT=1" ) set( KTX_EM_COMMON_KTX_LINK_FLAGS --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/interface/js_binding/class_compat.js --extern-post-js ${CMAKE_CURRENT_SOURCE_DIR}/interface/js_binding/module_create_compat.js ${KTX_EM_COMMON_LINK_FLAGS} ) set( KTX_JS_COMMON_SOURCE interface/js_binding/ktx_wrapper.cpp interface/js_binding/class_compat.js interface/js_binding/module_create_compat.js ) add_executable( ktx_js ${KTX_JS_COMMON_SOURCE} interface/js_binding/vk_format.inl ) target_compile_definitions(ktx_js PUBLIC KTX_FEATURE_WRITE) target_link_libraries( ktx_js ktx ) target_include_directories( ktx_js PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/other_include ${CMAKE_CURRENT_SOURCE_DIR}/lib $ ) target_link_options( ktx_js PUBLIC ${KTX_EM_COMMON_KTX_LINK_FLAGS} "SHELL:-s EXPORT_NAME=createKtxModule" ) set_target_properties( ktx_js PROPERTIES OUTPUT_NAME "libktx") add_custom_command( TARGET ktx_js POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$/$$.js" "${PROJECT_SOURCE_DIR}/tests/webgl" COMMAND ${CMAKE_COMMAND} -E copy "$/$$.wasm" "${PROJECT_SOURCE_DIR}/tests/webgl" COMMENT "Copy libktx.js and libktx.wasm to tests/webgl" ) install(TARGETS ktx_js RUNTIME DESTINATION . COMPONENT ktx_js ) install(FILES ${CMAKE_BINARY_DIR}/libktx.wasm DESTINATION . COMPONENT ktx_js ) add_executable( ktx_js_read ${KTX_JS_COMMON_SOURCE} ) target_link_libraries( ktx_js_read ktx_read ) target_include_directories( ktx_js_read PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/other_include ${CMAKE_CURRENT_SOURCE_DIR}/lib $ ) target_link_options( ktx_js_read PUBLIC ${KTX_EM_COMMON_KTX_LINK_FLAGS} "SHELL:-s EXPORT_NAME=createKtxReadModule" ) set_target_properties( ktx_js_read PROPERTIES OUTPUT_NAME "libktx_read") add_custom_command( TARGET ktx_js_read POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$/$$.js" "${PROJECT_SOURCE_DIR}/tests/webgl" COMMAND ${CMAKE_COMMAND} -E copy "$/$$.wasm" "${PROJECT_SOURCE_DIR}/tests/webgl" COMMENT "Copy libktx_read.js and libktx_read.wasm to tests/webgl" ) install(TARGETS ktx_js_read RUNTIME DESTINATION . COMPONENT ktx_js_read ) install(FILES ${CMAKE_BINARY_DIR}/libktx_read.wasm DESTINATION . COMPONENT ktx_js_read ) add_executable( msc_basis_transcoder_js interface/js_binding/transcoder_wrapper.cpp ) target_link_libraries( msc_basis_transcoder_js ktx_read ) target_include_directories( msc_basis_transcoder_js PRIVATE lib external external/basisu/transcoder ) # Re-use ktx's compile options target_compile_options(msc_basis_transcoder_js PRIVATE $ ) target_link_options( msc_basis_transcoder_js PUBLIC ${KTX_EM_COMMON_LINK_FLAGS} "SHELL:-s EXPORT_NAME=MSC_TRANSCODER" # Re-use ktx's link options $ ) set_target_properties( msc_basis_transcoder_js PROPERTIES OUTPUT_NAME "msc_basis_transcoder") add_custom_command( TARGET msc_basis_transcoder_js POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$/$$.js" "${PROJECT_SOURCE_DIR}/tests/webgl" COMMAND ${CMAKE_COMMAND} -E copy "$/$$.wasm" "${PROJECT_SOURCE_DIR}/tests/webgl" COMMENT "Copy msc_basis_transcoder.js and msc_basis_transcoder.wasm to tests/webgl" ) install(TARGETS msc_basis_transcoder_js RUNTIME DESTINATION . COMPONENT msc_basis_transcoder_js ) install(FILES ${CMAKE_BINARY_DIR}/msc_basis_transcoder.wasm DESTINATION . COMPONENT msc_basis_transcoder_js ) endif() add_library( objUtil STATIC utils/argparser.cpp utils/argparser.h utils/ktxapp.h utils/sbufstream.h utils/scapp.h utils/stdafx.h utils/platform_utils.h utils/unused.h ) target_include_directories( objUtil PUBLIC utils ) target_compile_features( objUtil PUBLIC cxx_std_11 ) # In C++ apps that use statically linked Libraries all compilatiom units must # be compiled with matching symbol visibility settings to avoid warnings from # clang. Many 3rd party libraries, including libassimp which is used by the # load test apps that statically link also to several internal libraries, use # "hidden" to avoid conflicts with other libraries. # # TODO: set "hidden" as a global option. I do not want to take the time right # now to deal with the fallout from hiding globals in libktx. Apart from # having to mark all the public symbols of libktx for clang and gcc with # __attribute__((visibility("default"))) there will be ramifications to # texturetests and unittests. Marking the public symbols is easy for those # already tagged with KTX_API. But all the symbols exported via # internalexport.def and internalexport_write.def have to be tagged with # KTX_API which may also require additional inclusion of ktx.h to get the # definition. set (STATIC_APP_LIB_SYMBOL_VISIBILITY hidden) set_target_properties(objUtil PROPERTIES CXX_VISIBILITY_PRESET ${STATIC_APP_LIB_SYMBOL_VISIBILITY} ) if(NOT BUILD_SHARED_LIBS AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")) set_source_files_properties( lib/astc_encode.cpp PROPERTIES COMPILE_OPTIONS "-fvisibility=hidden" ) endif() add_subdirectory(interface/basisu_c_binding) #################################################### # ASTC Encoder. #################################################### # Determine most of the ASTC-related settings automatically. # On Linux and Windows only one architecture is supported at once. On # macOS simultaneous multiple architectures are supported by the ASTC # encoder but not by the BasisU encoder. The latter supports only SSE # SIMD that is enabled by compile time defines which makes it not amenable # to a standard Xcode universal binary build. To ensure BASISU_SUPPORT_SSE # is disabled when building for multiple architectures use only the # value of CMAKE_OSX_ARCHITECTURES to decide if a universal build # has been requested. Do not expose the astc-encoder's # ASTCENC_UNIVERSAL_BUILD configuration option. set(universal_build OFF) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") # Check CMAKE_OSX_ARCHITECTURES for multiple architectures. list(FIND CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD)" archs_standard) list(LENGTH CMAKE_OSX_ARCHITECTURES architecture_count) if(NOT ${archs_standard} EQUAL -1 OR architecture_count GREATER 1) set(universal_build ON) endif() # Set ordinary variable to override astc-encoder option's ON default # and hide the option. set(ASTCENC_UNIVERSAL_BUILD ${universal_build}) endif() # If we detect the user is doing a universal build defer to astc-encoder # to pick the architectures. If a universal build has not been requested, # present options to the user to turn off SIMD and, if running on x86_64 # to choose which SIMD ISA to use. On arm64 always use Neon. On unknown # CPUs use None. # # On x86_64, if neither ASTCENC_ISA_SSE41 nor ASTCENC_ISA_SSE2 are defined, # choose ASTCENC_ISA_AVX2. If ASTCENC_ISA_AVX2 fails to compile user must # choose another x86_64 option. if(NOT ${universal_build}) set(ASTCENC_ISA_NATIVE OFF) set(ASTCENC_ISA_NEON OFF) if(NOT CPU_ARCHITECTURE STREQUAL x86_64) set(ASTCENC_ISA_AVX2 OFF) set(ASTCENC_ISA_SSE41 OFF) set(ASTCENC_ISA_SSE2 OFF) endif() # "" in the CACHE sets causes use of the existing documentation string. if(${ASTCENC_ISA_NONE}) set(ASTCENC_LIB_TARGET astcenc-none-static) if(CPU_ARCHITECTURE STREQUAL x86_64) set(ASTCENC_ISA_AVX2 OFF CACHE BOOL "" FORCE) set(ASTCENC_ISA_SSE41 OFF CACHE BOOL "" FORCE) set(ASTCENC_ISA_SSE2 OFF CACHE BOOL "" FORCE) endif() else() if(CPU_ARCHITECTURE STREQUAL x86_64) if (${ASTCENC_ISA_SSE41}) set(ASTCENC_LIB_TARGET astcenc-sse4.1-static) set(ASTCENC_ISA_AVX2 OFF CACHE BOOL "" FORCE) set(ASTCENC_ISA_SSE2 OFF CACHE BOOL "" FORCE) elseif (${ASTCENC_ISA_SSE2}) set(ASTCENC_LIB_TARGET astcenc-sse2-static) set(ASTCENC_ISA_AVX2 OFF CACHE BOOL "" FORCE) set(ASTCENC_ISA_SSE41 OFF CACHE BOOL "" FORCE) else() set(ASTCENC_LIB_TARGET astcenc-avx2-static) set(ASTCENC_ISA_AVX2 ON CACHE BOOL "" FORCE) set(ASTCENC_ISA_SSE41 OFF CACHE BOOL "" FORCE) set(ASTCENC_ISA_SSE2 OFF CACHE BOOL "" FORCE) endif() elseif(CPU_ARCHITECTURE STREQUAL armv8 OR CPU_ARCHITECTURE STREQUAL arm64) set(ASTCENC_LIB_TARGET astcenc-neon-static) set(ASTCENC_ISA_NEON ON) set(ASTCENC_ISA_NONE OFF CACHE BOOL "" FORCE) else() message(STATUS "Unsupported ISA for ASTC on ${CPU_ARCHITECTURE} arch, using ASTCENC_ISA_NONE.") set(ASTCENC_ISA_NONE ON CACHE BOOL "" FORCE) set(ASTCENC_LIB_TARGET astcenc-none-static) endif() endif() endif() # setting ASTCENC_DECOMPRESSOR to ON breaks the build, so force it to OFF # and hide it from cmake-gui (by using type INTERNAL) set(ASTCENC_DECOMPRESSOR OFF CACHE INTERNAL "") set(ASTCENC_CLI OFF) # Only build as library not the CLI astcencoder # Force static build for astc-encoder set(BUILD_SHARED_LIBS OFF) add_subdirectory(external/astc-encoder) set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_RESET}) set_property(TARGET ${ASTCENC_LIB_TARGET} PROPERTY POSITION_INDEPENDENT_CODE ON) target_compile_definitions( ${ASTCENC_LIB_TARGET} PRIVATE # ASTC encoder uses std::mutex. For more info. see comment about # same setting in libktx starting about line 633. To be eventually # removed as noted in that comment. $<$,19.40.33811>>:_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR> $<$,17.0.3>>:_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR> ) macro(set_astc_dependencies target) if(NOT BUILD_SHARED_LIBS AND APPLE) # Make a single static library to simplify linking. add_dependencies(${target} ${ASTCENC_LIB_TARGET}) add_custom_command( TARGET ${target} POST_BUILD COMMAND libtool -static -o $ $ $ ) # Don't know libtool equivalent on Windows or Emscripten. Applications # will have to link with both ktx and ${ASTCENC_LIB_TARGET}. Static libs # are unlikely to be used on Windows so not a problem there. For Emscripten # everything is built into the JS module so not an issue there either. else() target_link_libraries(${target} PRIVATE ${ASTCENC_LIB_TARGET}) endif() endmacro(set_astc_dependencies) set_astc_dependencies(ktx) set_astc_dependencies(ktx_read) # Other external projects # `NOT TARGET`s here are a precaution. They would only be exercised if # this CMakeLists is included in another project which is unlikely # except for building the ktx library. if((KTX_FEATURE_TOOLS OR KTX_FEATURE_TESTS) AND NOT TARGET fmt::fmt) # Always build fmt static set(BUILD_SHARED_LIBS OFF) set(FMT_INSTALL OFF) set(FMT_SYSTEM_HEADERS ON) add_subdirectory(external/fmt) set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_RESET}) endif() if(KTX_FEATURE_TOOLS AND NOT TARGET cxxopts::cxxopts) add_subdirectory(external/cxxopts) endif() # Tools if(KTX_FEATURE_TOOLS) add_subdirectory(tools) endif() # Tests add_subdirectory(tests) # Documentation if(KTX_FEATURE_DOC) include(cmake/docs.cmake) endif() set(KTX_INSTALL_TARGETS ktx) if(NOT BUILD_SHARED_LIBS AND NOT APPLE) list(APPEND KTX_INSTALL_TARGETS ${ASTCENC_LIB_TARGET}) endif() # Install if(APPLE OR LINUX) # Have library's name links as separate component set(KTX_NAMELINKS ON) install(TARGETS ${KTX_INSTALL_TARGETS} EXPORT KTXTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library NAMELINK_SKIP PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT dev ) install(TARGETS ${KTX_INSTALL_TARGETS} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library NAMELINK_ONLY ) else() # No name links on Windows set(KTX_NAMELINKS OFF) install(TARGETS ${KTX_INSTALL_TARGETS} EXPORT KTXTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT dev LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT library RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT library PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT dev ) endif() # Use of this to install KHR/khr_df.h is due to CMake's failure to # preserve the include source folder hierarchy. # See https://gitlab.kitware.com/cmake/cmake/-/issues/16739. if (APPLE_LOCKED_OS) set_source_files_properties( include/KHR/khr_df.h PROPERTIES MACOSX_PACKAGE_LOCATION Headers/KHR ) else() include(GNUInstallDirs) install(FILES include/KHR/khr_df.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/KHR COMPONENT dev ) endif() install(EXPORT KTXTargets FILE KtxTargets.cmake NAMESPACE KTX:: DESTINATION lib/cmake/ktx COMPONENT dev ) include(CMakePackageConfigHelpers) write_basic_package_version_file( "KtxConfigVersion.cmake" COMPATIBILITY SameMajorVersion ) install( FILES "cmake/KtxConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KtxConfigVersion.cmake" DESTINATION lib/cmake/ktx COMPONENT dev ) # CPack include(CPackComponent) set(CPACK_PACKAGE_NAME "KTX-Software") set(CPACK_PACKAGE_VENDOR "Khronos Group") set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.khronos.org/KTX-Software") set(CPACK_PACKAGE_CONTACT "khronos@callow.im" ) set(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Welcome.rtf") set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/cmake/ReadMe.rtf") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/License.rtf") # Custom package file name # This does not use the ${CPU_ARCHITECTURE} set earlier because the hope is # that the BasisU SIMD code will be changed to no longer need compile time # definitions and we can remove the complex cputypetest.cmake. if( APPLE AND CMAKE_OSX_ARCHITECTURES ) # CMAKE_SYSTEM_PROCESSOR typically set to build host processor here. # CMAKE_OSX_ARCHITECTURES governs target of build. list(LENGTH CMAKE_OSX_ARCHITECTURES archs_len) list(GET CMAKE_OSX_ARCHITECTURES 0 arch0) # Cannot use CMAKE_OSX_ARCHITECTURES instead of arch0 due to if() being # confused by potentially multiple architectures between OR and STREQUAL. # It's okay in the else() clause but as we've already set arch0... if( ${archs_len} GREATER 1 OR ${arch0} STREQUAL "$(ARCHS_STANDARD)" ) set(processor_name "universal") else() set(processor_name ${arch0}) endif() elseif( CMAKE_CXX_COMPILER_ARCHITECTURE_ID ) # When targeting Windows arm64 CMAKE_SYSTEM_PROCESSOR will incorrectly # return AMD64. See: https://gitlab.kitware.com/cmake/cmake/-/issues/15170. # We assume that when building for Windows arm64 that we are using MSVC # or ClangCL so we can detect the processor arch name with # CMAKE_CXX_COMPILER_ARCHITECTURE_ID set(processor_name ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}) elseif( CMAKE_SYSTEM_PROCESSOR ) if( ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" ) # Use consistent package name for all platforms. set(processor_name "arm64") else() set(processor_name ${CMAKE_SYSTEM_PROCESSOR}) endif() elseif( APPLE_LOCKED_OS ) # CMAKE_SYSTEM_PROCESSOR not set when building for iOS/tvOS/visionOS. set(processor_name "arm64") endif() string(TOLOWER "${processor_name}" processor_name) #message(STATUS "processor_name is ${processor_name}, CPU_ARCHITECTURE is ${CPU_ARCHITECTURE}") set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${KTX_VERSION_FULL}-${CMAKE_SYSTEM_NAME}-${processor_name}") if(APPLE) if(APPLE_MAC_OS) install(FILES tools/package/mac/ktx-uninstall DESTINATION ${CMAKE_INSTALL_BINDIR} PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE COMPONENT tools ) set(CPACK_GENERATOR productbuild) # Trick the productbuild generator into creating more useful package IDs set(CPACK_PACKAGE_NAME "ktx") set(CPACK_PACKAGE_VENDOR "khronos") # Install at root level set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local") set(CPACK_PRODUCTBUILD_IDENTITY_NAME ${PRODUCTBUILD_IDENTITY_NAME}) set(CPACK_PRODUCTBUILD_KEYCHAIN_PATH ${PRODUCTBUILD_KEYCHAIN_PATH}) # Contains the `summary.html` file, shown at end of installation set(CPACK_PRODUCTBUILD_RESOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tools/package/mac/Resources") set(CPACK_PRODUCTBUILD_BACKGROUND "ktx_logo_190_xp.png") set(CPACK_PRODUCTBUILD_BACKGROUND_MIME_TYPE "image/png") set(CPACK_PRODUCTBUILD_BACKGROUND_ALIGNMENT "bottomleft") else() set(CPACK_GENERATOR ZIP) set(CPACK_ARCHIVE_KTX_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}") set(CPACK_ARCHIVE_COMPONENT_INSTALL OFF) set(CPACK_PACKAGE_CHECKSUM SHA1) endif() elseif(LINUX) set(CPACK_GENERATOR DEB RPM TBZ2) set(CPACK_PACKAGE_CHECKSUM SHA1) set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/ReadMe.txt") # This fixes the directory permission derived from Ubuntu ${BUILD_DIR} of 0775 to 0755. # otherwise when installing the RPM, it conflicts with the base filesystem.rpm that is # setting the directory permissions and owns them to 0755. # See GitHub Issue #827. # NOTE: Alternatively It would be better build the RPM through a docker or RedHat OS in the CI set(CPACK_RPM_DEFAULT_DIR_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) elseif(WIN32) set(CPACK_GENERATOR "NSIS") # Add logo to top left of installer pages. Despite the installer- # independent variable name, this does nothing for PRODUCTBUILD # hence setting here only. Format has to be old BMP (use # BMP3: with ImageMagick `convert`) and the final # separator must be as shown. Recommended size is 150x57 pixels but # to my eye on my screen 200x111 is much less aliased than the 150x83 # proportionally scaled logo. set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icons/win\\\\ktx_logo_200_bmp3.bmp") # Set the icon for the installer and uninstaller set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icons/win/ktx_app.ico") set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/icons/win/ktx_app.ico") # Set icon in Windows' add/remove control panel. Must be an .exe file. set(CPACK_NSIS_INSTALLED_ICON_NAME uninstall.exe) set(CPACK_NSIS_MANIFEST_DPI_AWARE ON) set(CPACK_NSIS_URL_INFO_ABOUT ${CPACK_PACKAGE_HOMEPAGE_URL}) set(CPACK_NSIS_CONTACT ${CPACK_PACKAGE_CONTACT}) set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_UNINSTALL_NAME "Uninstall") set(CPACK_PACKAGE_INSTALL_DIRECTORY "KTX-Software") if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.20") set(CPACK_NSIS_BRANDING_TEXT "KTX for Windows") endif() ## Alternative: add major version at end #set(CPACK_PACKAGE_INSTALL_DIRECTORY "KTX-Software-${PROJECT_VERSION_MAJOR}") if (CODE_SIGN_KEY_VAULT) set_nsis_installer_codesign_cmd() else() # We're not signing the package so provide a checksum file. set(CPACK_PACKAGE_CHECKSUM SHA1) endif() elseif(EMSCRIPTEN) set(CPACK_GENERATOR ZIP) set(CPACK_ARCHIVE_KTX_JS_FILE_NAME "${CMAKE_PROJECT_NAME}-${KTX_VERSION_FULL}-Web-libktx") set(CPACK_ARCHIVE_KTX_JS_READ_FILE_NAME "${CMAKE_PROJECT_NAME}-${KTX_VERSION_FULL}-Web-libktx_read") set(CPACK_ARCHIVE_MSC_BASIS_TRANSCODER_JS_FILE_NAME "${CMAKE_PROJECT_NAME}-${KTX_VERSION_FULL}-Web-msc_basis_transcoder") set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) set(CPACK_PACKAGE_CHECKSUM SHA1) else() set(CPACK_PACKAGE_CHECKSUM SHA1) endif() cpack_add_component(library DISPLAY_NAME "Library" DESCRIPTION "Main KTX library." REQUIRED ) #cpack_add_component(Namelinks # DEPENDS library # HIDDEN #) cpack_add_component(jni DISPLAY_NAME "Java wrapper" DESCRIPTION "Java wrapper and native interface for KTX library." DEPENDS library DISABLED ) cpack_add_component(tools DISPLAY_NAME "Command line tools" DESCRIPTION "Command line tools for creating, converting and inspecting KTX files." DEPENDS library ) cpack_add_component(dev DISPLAY_NAME "Development" DESCRIPTION "Additional resources for development (header files and documentation)." DEPENDS library DISABLED ) cpack_add_component(GlLoadTestApps GROUP LoadTestApps DISPLAY_NAME "OpenGL Test Applications" DISABLED ) cpack_add_component(VkLoadTestApp GROUP LoadTestApps DISPLAY_NAME "Vulkan Test Application" DISABLED ) cpack_add_component_group(LoadTestApps DISPLAY_NAME "Load Test Applications" ) if(EMSCRIPTEN) set(CPACK_COMPONENTS_ALL ktx_js ktx_js_read msc_basis_transcoder_js ) else() set(CPACK_COMPONENTS_ALL library dev ) if(KTX_FEATURE_TOOLS) list(APPEND CPACK_COMPONENTS_ALL tools ) endif() if(KTX_FEATURE_JNI) list(APPEND CPACK_COMPONENTS_ALL jni ) endif() # if(${KTX_FEATURE_LOADTEST_APPS} MATCHES "OpenGL") # list(APPEND CPACK_COMPONENTS_ALL # GLLoadTestApps # ) # endif() # if(${KTX_FEATURE_LOADTEST_APP} MATCHES "Vulkan") # list(APPEND CPACK_COMPONENTS_ALL # VkLoadTestApp # ) # endif() endif() # if(KTX_NAMELINKS) # list(APPEND CPACK_COMPONENTS_ALL # Namelinks # ) # endif() include(CPack) # vim:ai:ts=4:sts=2:sw=2:expandtab