cpp-utilities/cmake/modules/3rdParty.cmake

175 lines
6.1 KiB
CMake

cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
# prevent multiple inclusion
if (DEFINED THIRD_PARTY_MODULE_LOADED)
return()
endif ()
set(THIRD_PARTY_MODULE_LOADED YES)
macro (save_default_library_suffixes)
set(DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
endmacro ()
macro (restore_default_library_suffixes)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES})
unset(DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES)
endmacro ()
macro (configure_static_library_suffixes)
# allows to look for static libraries in particular
if (WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)
else ()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif ()
endmacro ()
macro (configure_dynamic_library_suffixes)
# allows to look for dynamic libraries in particular
if (WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .dll .dll.a)
elseif (APPLE)
set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib .so)
else ()
set(CMAKE_FIND_LIBRARY_SUFFIXES .so)
endif ()
endmacro ()
function(validate_visibility VISIBILITY)
if (NOT (VISIBILITY STREQUAL PUBLIC OR VISIBILITY STREQUAL PRIVATE))
message(FATAL_ERROR "Specified visibility ${VISIBILITY} is invalid (must be either PUBLIC or PRIVATE).")
endif()
endfunction()
function(parse_arguments_for_use_functions)
# parse arguments
set(OPTIONAL_ARGS OPTIONAL)
set(ONE_VALUE_ARGS VISIBILITY LIBRARIES_VARIABLE TARGET_NAME)
set(MULTI_VALUE_ARGS)
cmake_parse_arguments(ARGS "${OPTIONAL_ARGS}" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN})
# validate values
if (ARGS_VISIBILITY)
validate_visibility(${ARGS_VISIBILITY})
else()
set (ARGS_VISIBILITY PRIVATE)
endif()
if (NOT ARGS_LIBRARIES_VARIABLE)
set (ARGS_LIBRARIES_VARIABLE "${ARGS_VISIBILITY}_LIBRARIES")
endif()
# export parsed values to parent scope
set(ARGS_VISIBILITY "${ARGS_VISIBILITY}" PARENT_SCOPE)
set(ARGS_LIBRARIES_VARIABLE "${ARGS_LIBRARIES_VARIABLE}" PARENT_SCOPE)
set(ARGS_TARGET_NAME "${ARGS_TARGET_NAME}" PARENT_SCOPE)
set(ARGS_OPTIONAL "${ARGS_OPTIONAL}" PARENT_SCOPE)
if (NOT ARGS_OPTIONAL)
set(ARGS_FIND_PACKAGE "REQUIRED" PARENT_SCOPE)
endif()
endfunction()
function (use_iconv)
parse_arguments_for_use_functions(${ARGN})
# check whether iconv from the standard library can be used
set(FORCE_EXTERNAL_ICONV OFF
CACHE PATH "whether to force usage of external iconv (rather than the using the one bundled with glibc)")
if (NOT FORCE_EXTERNAL_ICONV)
# check whether iconv exists in standard lib
include(CheckFunctionExists)
check_function_exists(iconv HAS_ICONV)
endif ()
if (NOT FORCE_EXTERNAL_ICONV AND HAS_ICONV)
message(STATUS "Using iconv from the standard library for target ${META_PROJECT_NAME}.")
return()
endif()
# find external iconv library
if (NOT TARGET ICONV::LIBICONV)
find_library(ICONV_LIBRARY_PATH iconv)
if (NOT EXISTS "${ICONV_LIBRARY_PATH}")
if (ARGS_OPTIONAL)
return()
endif()
message(FATAL_ERROR "Unable to find iconv library for project ${META_PROJECT_NAME}.")
endif()
add_library(ICONV::LIBICONV STATIC IMPORTED)
set_property(TARGET ICONV::LIBICONV PROPERTY IMPORTED_LOCATION "${ICONV_LIBRARY_PATH}")
endif()
set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};ICONV::LIBICONV" PARENT_SCOPE)
endfunction()
function (use_openssl)
parse_arguments_for_use_functions(${ARGN})
find_package(OpenSSL ${ARGS_FIND_PACKAGE})
set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};OpenSSL::SSL;OpenSSL::Crypto" PARENT_SCOPE)
set("PKG_CONFIG_OpenSSL_SSL" "libssl" PARENT_SCOPE)
set("PKG_CONFIG_OpenSSL_Crypto" "libcrypto" PARENT_SCOPE)
endfunction()
function (use_crypto)
parse_arguments_for_use_functions(${ARGN})
find_package(OpenSSL ${ARGS_FIND_PACKAGE})
set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};OpenSSL::Crypto" PARENT_SCOPE)
set("PKG_CONFIG_OpenSSL_Crypto" "libcrypto" PARENT_SCOPE)
endfunction()
function (use_zlib)
parse_arguments_for_use_functions(${ARGN})
find_package(ZLIB ${ARGS_FIND_PACKAGE})
set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};ZLIB::ZLIB" PARENT_SCOPE)
set("PKG_CONFIG_ZLIB_ZLIB" "zlib" PARENT_SCOPE)
endfunction()
function (use_target)
parse_arguments_for_use_functions(${ARGN})
if(NOT TARGET "${ARGS_TARGET_NAME}")
if (ARGS_OPTIONAL)
return()
endif()
message(FATAL_ERROR "Target \"${ARGS_TARGET_NAME}\" does not exist.")
endif()
set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};${ARGS_TARGET_NAME}" PARENT_SCOPE)
endfunction()
# skip subsequent configuration if only the function includes are wanted
if (META_NO_3RDPARTY_CONFIG)
return()
endif()
# add options for deciding whether to build/use static or shared libraries
if (("${META_PROJECT_TYPE}" STREQUAL "library")
OR ("${META_PROJECT_TYPE}" STREQUAL "plugin")
OR ("${META_PROJECT_TYPE}" STREQUAL "qtplugin")
OR ("${META_PROJECT_TYPE}" STREQUAL ""))
set(META_PROJECT_IS_LIBRARY YES)
elseif ("${META_PROJECT_TYPE}" STREQUAL "application")
set(META_PROJECT_IS_APPLICATION YES)
endif ()
if (META_PROJECT_IS_LIBRARY)
option(BUILD_SHARED_LIBS ON "whether to build shared or static libraries")
option(STATIC_LIBRARY_LINKAGE "adds flags for static linkage when building dynamic libraries" OFF)
elseif (META_PROJECT_IS_APPLICATION)
option(STATIC_LINKAGE "adds flags for static linkage when building applications" OFF)
endif()
# configure "static linkage"
if ((STATIC_LINKAGE AND META_PROJECT_IS_APPLICATION) OR (STATIC_LIBRARY_LINKAGE AND META_PROJECT_IS_LIBRARY))
# add additional linker flags to achieve a fully statically linked build
if (META_PROJECT_IS_APPLICATION)
if (NOT APPLE)
list(APPEND META_ADDITIONAL_LINK_FLAGS -static)
endif ()
list(APPEND META_ADDITIONAL_LINK_FLAGS -static-libstdc++ -static-libgcc)
endif()
# prefer static libraries
configure_static_library_suffixes()
endif()