CMAKE_MINIMUM_REQUIRED(VERSION 3.16) PROJECT("Photo Compress Archiver") ################################################################################ # Check GCC version ################################################################################ IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # Require at least gcc 10.3 for C++20 support IF (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.3) MESSAGE(FATAL_ERROR "GCC version must be at least 10.3!") ENDIF() ENDIF() # This is a neat trick to prevent in source builds IF (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) MESSAGE(FATAL_ERROR "Prevented in-tree build. This is bad practice; you " "should be running cmake from inside a build directory.") ENDIF() ################################################################################ # Build configuration options ################################################################################ IF (NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE ReleaseWithDebug CACHE STRING "Choose the type of build, options are: None Debug ReceiverRelease ReleaseWithDebug." FORCE ) ENDIF() MESSAGE(STATUS "Build Type: " ${CMAKE_BUILD_TYPE}) ADD_CUSTOM_TARGET(Debug COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all COMMENT "Switch CMAKE_BUILD_TYPE to Debug" ) ADD_CUSTOM_TARGET(ReceiverRelease COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=PCARelease ${CMAKE_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all COMMENT "Switch CMAKE_BUILD_TYPE to ReceiverRelease" ) ADD_CUSTOM_TARGET(ReleaseWithDebug COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=ReleaseWithDebug ${CMAKE_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all COMMENT "Switch CMAKE_BUILD_TYPE to ReleaseWithDebug" ) # Use /etc/os-release to determine Linux flavor and version EXECUTE_PROCESS(COMMAND bash -c "grep \"^NAME=\" /etc/os-release | cut -c7- | rev | cut -c2- | rev" OUTPUT_VARIABLE DISTRIB_ID OUTPUT_STRIP_TRAILING_WHITESPACE ) EXECUTE_PROCESS(COMMAND bash -c "grep \"^VERSION_ID=\" /etc/os-release | cut -c13- | rev | cut -c2- | rev" OUTPUT_VARIABLE DISTRIB_RELEASE OUTPUT_STRIP_TRAILING_WHITESPACE ) # Output the parsed ID and release version MESSAGE(STATUS "DISTRIB_ID: " ${DISTRIB_ID}) MESSAGE(STATUS "DISTRIB_RELEASE: " ${DISTRIB_RELEASE}) # Do not let CMake add the build directory path to RPATH. This means that CL/SL # cannot be run from the build directory and must be properly installed. SET(CMAKE_SKIP_BUILD_RPATH TRUE) # Uncomment this line to enable AddressSanitizer # SET(CMAKE_CXX_FLAGS "-fsanitize=address -fno-omit-frame-pointer") # Detect presence of mold linker and use it if found IF (EXISTS "/usr/bin/mold") MESSAGE(STATUS "Using mold linker!") # Note this only works on gcc >= 12.1 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=mold") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=mold") ELSE() MESSAGE(WARNING "Mold linker not detected. Consider installing mold (add BL APT repo: " "https://athena.blacklynx.tech/apt/): sudo apt install mold") ENDIF() # # Set the compile flags # SET(CMAKE_CXX_STANDARD 20) SET(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_CXX_EXTENSIONS OFF) # SET(CMAKE_CXX_VISIBILITY_PRESET hidden) # This length is used along with the __FILE__ macro for logging STRING(LENGTH ${CMAKE_CURRENT_SOURCE_DIR} BPLEN) ADD_DEFINITIONS("-DBUILD_PATH_LEN=${BPLEN}") # Ensure symbols from statically linked libraries are hidden SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--exclude-libs=ALL") # Enable warnings SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter") IF (CMAKE_BUILD_TYPE STREQUAL "PCARelease") # Tune for Skylake minimum SET(COMPILE_FLAGS "-O3 -flto=auto -march=skylake") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS}") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS}") ELSEIF (CMAKE_BUILD_TYPE STREQUAL "ReleaseWithDebug") # Tune for Skylake minimum SET(COMPILE_FLAGS "-g -O3 -flto=auto -march=skylake ") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS}") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS}") ELSEIF (CMAKE_BUILD_TYPE STREQUAL "Debug") SET(COMPILE_FLAGS "-g -O0 -march=skylake -mtune=generic") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS}") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS}") ENDIF() # Set the library install path depending on the Linux flavor SET(LIBRARY_INSTALL_PATH "") IF ((DISTRIB_ID STREQUAL "Ubuntu") OR (DISTRIB_ID STREQUAL "Linux Mint")) SET(LIBRARY_INSTALL_PATH "usr/lib/x86_64-linux-gnu/") ELSE() # CentOS/RedHat/Scientific SET(LIBRARY_INSTALL_PATH "usr/lib64/") ENDIF() IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/" CACHE PATH "..." FORCE) ENDIF() ################################################################################ # Library Dependencies ################################################################################ SET(EXTERNAL_LIBS) FIND_PACKAGE(Threads) ################################################################################ # External projects ################################################################################ INCLUDE(ExternalProject) # # libpackjpg # SET(PACKJPG_PREFIX ${CMAKE_BINARY_DIR}/libpackjpg) # TODO: only build/install libpackjpg.a ExternalProject_Add(libpackjpg_local GIT_REPOSITORY "https://brutus.gleeze.com/git/libpackjpg" PREFIX ${PACKJPG_PREFIX} INSTALL_DIR ${PACKJPG_PREFIX}/install SOURCE_SUBDIR lib_src CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PACKJPG_PREFIX}/install -DCMAKE_BUILD_TYPE=Release) INCLUDE_DIRECTORIES(${PACKJPG_PREFIX}/install/usr/include) SET(libpackjpg_static_lib ${PACKJPG_PREFIX}/install/${LIBRARY_INSTALL_PATH}/libpackjpg.a) MESSAGE(STATUS "libpackjpg path: ${libpackjpg_static_lib}") SET_SOURCE_FILES_PROPERTIES( ${libpackjpg_static_lib} PROPERTIES EXTERNAL_OBJECT TRUE # Identifies this as an object file (static lib) GENERATED TRUE # Avoids need for file to exist at configure-time ) ################################################################################ # Source ################################################################################ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/external) SET(pca_sources ${CMAKE_CURRENT_SOURCE_DIR}/src/PhotoCompressArchiver.cc ) ################################################################################ # Target: pca executable ################################################################################ ADD_EXECUTABLE(pca ${pca_sources} ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc) ADD_DEPENDENCIES(pca libpackjpg_local) TARGET_LINK_LIBRARIES(pca ${EXTERNAL_LIBS} ${libpackjpg_static_lib})