diff --git a/.gitignore b/.gitignore index 93524df8..ceab2646 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +bin/ build/ # VS project and working files diff --git a/CMakeLists.txt b/CMakeLists.txt index 97a6e3ec..3d28bc72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,39 +1,47 @@ # Important: The Basis Universal encoder and transcoder libraries must be compiled with -fno-strict-aliasing (MSVC's default, and also the Linux kernel). # It should also work without this option, but we do not test with it. -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.16) project(basisu C CXX) set(CMAKE_CXX_STANDARD 17) -option(STATIC "static linking" FALSE) -option(SAN "sanitize" FALSE) +option(BASISU_TOOL "Include basisu tool in build" TRUE) +option(BASISU_EXAMPLES "Include examples in build" TRUE) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) +option(BASISU_STATIC "static linking" FALSE) +option(BASISU_SAN "sanitize" FALSE) + +# Using a generator expression here prevents multi-config generators (VS, Xcode, Ninja Multi-Config) +# from appending a per-configuration subdirectory. NOTE: This means the output could be overwritten +# by a subsequent build for a different configuration. +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_SOURCE_DIR}/bin>) # For MSVC builds default to SSE enabled, and determine if it's a 64-bit (-A x64) vs. 32-bit (-A Win32) build. if (MSVC) - option(SSE "SSE 4.1 support" TRUE) - if ( CMAKE_GENERATOR_PLATFORM STREQUAL Win32 ) - set(BUILD_X64 0) + option(BASISU_SSE "SSE 4.1 support" TRUE) + if ( CMAKE_GENERATOR_PLATFORM STREQUAL Win32 ) + set(BASISU_BUILD_X64 0) else() - set(BUILD_X64 1) + set(BASISU_BUILD_X64 1) endif() add_compile_options(/W4) else() - option(SSE "SSE 4.1 support" FALSE) - option(BUILD_X64 "build 64-bit" TRUE) + option(BASISU_SSE "SSE 4.1 support" FALSE) + option(BASISU_BUILD_X64 "build 64-bit" TRUE) endif() -option(ZSTD "ZSTD support for KTX2 transcoding/encoding" TRUE) -option(OPENCL "OpenCL support in encoder" FALSE) +option(BASISU_ZSTD "ZSTD support for KTX2 transcoding/encoding" TRUE) +option(BASISU_OPENCL "OpenCL support in encoder" FALSE) -message("Initial BUILD_X64=${BUILD_X64}") +message("Initial BASISU_BUILD_X64=${BASISU_BUILD_X64}") message("Initial CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") -message("Initial SSE=${SSE}") -message("Initial ZSTD=${ZSTD}") -message("Initial OPENCL=${OPENCL}") -message("Initial SAN=${SAN}") +message("Initial BASISU_SSE=${BASISU_SSE}") +message("Initial BASISU_ZSTD=${BASISU_ZSTD}") +message("Initial BASISU_OPENCL=${BASISU_OPENCL}") +message("Initial BASISU_SAN=${BASISU_SAN}") +message("initial BASISU_TOOL=${BASISU_TOOL}") +message("initial BASISU_EXAMPLES=${BASISU_EXAMPLES}") -if ((NOT MSVC) AND OPENCL) +if ((NOT MSVC) AND BASISU_OPENCL) # With MSVC builds we use the Khronos lib/include files in the project's "OpenCL" directory, to completely avoid requiring fiddly to install vendor SDK's. # Otherwise we use the system's (if any). find_package(OpenCL) @@ -48,19 +56,19 @@ endif() message(${PROJECT_NAME} " build type: " ${CMAKE_BUILD_TYPE}) -if (BUILD_X64) +if (BASISU_BUILD_X64) message("Building 64-bit") else() message("Building 32-bit") endif() -if (SSE) +if (BASISU_SSE) message("SSE enabled") else() message("SSE disabled") endif() -if (ZSTD) +if (BASISU_ZSTD) message("Zstandard enabled") else() message("Zstandard disabled") @@ -73,7 +81,7 @@ if (NOT MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") - if (SAN) + if (BASISU_SAN) message("Enabling SAN") set(SANITIZE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize=alignment") @@ -88,7 +96,7 @@ if (NOT MSVC) set(CMAKE_CXX_FLAGS -std=c++17) set(GCC_COMPILE_FLAGS "-fvisibility=hidden -fPIC -fno-strict-aliasing -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 -Wall -Wextra -Wno-unused-local-typedefs -Wno-unused-value -Wno-unused-parameter -Wno-unused-variable -Wno-reorder -Wno-misleading-indentation -Wno-class-memaccess -Wno-deprecated-copy -Wno-maybe-uninitialized -Wno-unused-function -Wno-stringop-overflow -Wno-unknown-warning-option") - if (NOT BUILD_X64) + if (NOT BASISU_BUILD_X64) set(GCC_COMPILE_FLAGS "${GCC_COMPILE_FLAGS} -m32") endif() @@ -97,8 +105,8 @@ if (NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -DBASISU_SUPPORT_SSE=0") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_LINK_FLAGS}") - elseif (STATIC) - if (SSE) + elseif (BASISU_STATIC) + if (BASISU_SSE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBASISU_SUPPORT_SSE=1 -msse4.1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBASISU_SUPPORT_SSE=1 -msse4.1") else() @@ -108,7 +116,7 @@ if (NOT MSVC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_LINK_FLAGS} -static-libgcc -static-libstdc++ -static") else() - if (SSE) + if (BASISU_SSE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBASISU_SUPPORT_SSE=1 -msse4.1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBASISU_SUPPORT_SSE=1 -msse4.1") else() @@ -127,7 +135,7 @@ if (NOT MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") else() - if (SSE) + if (BASISU_SSE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBASISU_SUPPORT_SSE=1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBASISU_SUPPORT_SSE=1") else() @@ -163,66 +171,102 @@ set(ENCODER_LIB_SRC_LIST transcoder/basisu_transcoder.cpp ) -if (ZSTD) +set(ENCODER_LIB_HDR_LIST + encoder/basisu_astc_hdr_6x6_enc.h + encoder/basisu_astc_hdr_common.h + encoder/basisu_backend.h + encoder/basisu_basis_file.h + encoder/basisu_bc7enc.h + encoder/basisu_comp.h + encoder/basisu_enc.h + encoder/basisu_etc.h + encoder/basisu_frontend.h + encoder/basisu_gpu_texture.h + encoder/basisu_kernels_declares.h + encoder/basisu_kernels_imp.h + encoder/basisu_math.h + encoder/basisu_miniz.h + encoder/basisu_ocl_kernels.h + encoder/basisu_opencl.h + encoder/basisu_pvrtc1_4.h + encoder/basisu_resampler_filters.h + encoder/basisu_resampler.h + encoder/basisu_ssim.h + encoder/basisu_uastc_enc.h + encoder/basisu_uastc_hdr_4x4_enc.h + encoder/cppspmd_flow.h + encoder/cppspmd_math_declares.h + encoder/cppspmd_math.h + encoder/cppspmd_sse.h + encoder/cppspmd_type_aliases.h + encoder/jpgd.h + encoder/pvpngreader.h + encoder/3rdparty/android_astc_decomp.h + encoder/3rdparty/qoi.h + encoder/3rdparty/tinyexr.h + transcoder/basisu_astc_hdr_core.h + transcoder/basisu_astc_helpers.h + transcoder/basisu_containers_impl.h + transcoder/basisu_containers.h + transcoder/basisu_file_headers.h + transcoder/basisu_transcoder_internal.h + transcoder/basisu_transcoder_uastc.h + transcoder/basisu_transcoder.h + transcoder/basisu.h +) + +if (BASISU_ZSTD) set(ENCODER_LIB_SRC_LIST ${ENCODER_LIB_SRC_LIST} zstd/zstd.c) + set(ENCODER_LIB_HDR_LIST ${ENCODER_LIB_HDR_LIST} zstd/zstd.h) endif() # Create the static library -add_library(basisu_encoder STATIC ${ENCODER_LIB_SRC_LIST}) - -# Create the basisu executable and link against the static library -add_executable(basisu basisu_tool.cpp) -target_link_libraries(basisu PRIVATE basisu_encoder) - -# Create the new example executable and link against the static library -add_executable(examples example/example.cpp) -target_link_libraries(examples PRIVATE basisu_encoder) - -if (ZSTD) - target_compile_definitions(basisu PRIVATE BASISD_SUPPORT_KTX2_ZSTD=1) - target_compile_definitions(examples PRIVATE BASISD_SUPPORT_KTX2_ZSTD=1) -else() - target_compile_definitions(basisu PRIVATE BASISD_SUPPORT_KTX2_ZSTD=0) - target_compile_definitions(examples PRIVATE BASISD_SUPPORT_KTX2_ZSTD=0) -endif() +add_library(basisu_encoder STATIC ${ENCODER_LIB_SRC_LIST} ${ENCODER_LIB_HDR_LIST}) if (NOT MSVC) # For Non-Windows builds, let cmake try and find the system OpenCL headers/libs for us. - if (OPENCL AND OPENCL_FOUND) + if (BASISU_OPENCL AND OPENCL_FOUND) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBASISU_SUPPORT_OPENCL=1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBASISU_SUPPORT_OPENCL=1") - target_include_directories(basisu PRIVATE ${OpenCL_INCLUDE_DIRS}) - target_include_directories(examples PRIVATE ${OpenCL_INCLUDE_DIRS}) - target_include_directories(basisu_encoder PRIVATE ${OpenCL_INCLUDE_DIRS}) - set(BASISU_EXTRA_LIBS ${OpenCL_LIBRARIES}) + target_include_directories(basisu_encoder INTERFACE ${OpenCL_INCLUDE_DIRS}) + target_link_libraries(basisu_encoder INTERFACE ${OpenCL_LIBRARIES}) endif() + target_link_libraries(basisu_encoder INTERFACE m pthread) else() # For Windows builds, we use our local copies of the OpenCL import lib and Khronos headers. - if (OPENCL) + if (BASISU_OPENCL) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBASISU_SUPPORT_OPENCL=1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBASISU_SUPPORT_OPENCL=1") - target_include_directories(basisu PRIVATE "OpenCL") - target_include_directories(examples PRIVATE "OpenCL") - target_include_directories(basisu_encoder PRIVATE "OpenCL") + target_include_directories(basisu_encoder INTERFACE "OpenCL") - if (BUILD_X64) - target_link_libraries(basisu PRIVATE "${CMAKE_SOURCE_DIR}/OpenCL/lib/OpenCL64.lib") - target_link_libraries(examples PRIVATE "${CMAKE_SOURCE_DIR}/OpenCL/lib/OpenCL64.lib") + if (BASISU_BUILD_X64) + target_link_libraries(basisu_encoder INTERFACE "${CMAKE_SOURCE_DIR}/OpenCL/lib/OpenCL64.lib") else() - target_link_libraries(basisu PRIVATE "${CMAKE_SOURCE_DIR}/OpenCL/lib/OpenCL.lib") - target_link_libraries(examples PRIVATE "${CMAKE_SOURCE_DIR}/OpenCL/lib/OpenCL.lib") + target_link_libraries(basisu_encoder INTERFACE "${CMAKE_SOURCE_DIR}/OpenCL/lib/OpenCL.lib") endif() endif() endif() -if (NOT MSVC) - target_link_libraries(basisu PRIVATE m pthread ${BASISU_EXTRA_LIBS}) - target_link_libraries(examples PRIVATE m pthread ${BASISU_EXTRA_LIBS}) +macro(set_common_executable_properties target) + target_link_libraries(${target} PRIVATE basisu_encoder) + target_compile_definitions(${target} PRIVATE BASISD_SUPPORT_KTX2_ZSTD=$,1,0>) +endmacro() + +if (BASISU_TOOL) + # Create the basisu executable and link against the static library + add_executable(basisu basisu_tool.cpp) + set_common_executable_properties(basisu) +endif() + +if (BASISU_EXAMPLES) + # Create the new example executable and link against the static library + add_executable(examples example/example.cpp) + set_common_executable_properties(examples) endif() -if (NOT EMSCRIPTEN) +if (BASISU_TOOL AND NOT EMSCRIPTEN) if (UNIX) if (CMAKE_BUILD_TYPE STREQUAL Release) if (APPLE) @@ -236,20 +280,3 @@ if (NOT EMSCRIPTEN) endif() endif() -if (MSVC) - set_target_properties(basisu PROPERTIES - RUNTIME_OUTPUT_NAME "basisu" - RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - ) - - set_target_properties(examples PROPERTIES - RUNTIME_OUTPUT_NAME "examples" - RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - ) -endif()