toxcore/cmake/ModulePackage.cmake

174 lines
5.9 KiB
CMake
Raw Normal View History

2016-09-12 01:49:44 +08:00
option(ENABLE_SHARED "Build shared (dynamic) libraries for all modules" ON)
option(ENABLE_STATIC "Build static libraries for all modules" ON)
option(COMPILE_AS_CXX "Compile all C code as C++ code" OFF)
2016-09-12 01:49:44 +08:00
if(NOT ENABLE_SHARED AND NOT ENABLE_STATIC)
message(WARNING
"Both static and shared libraries are disabled; "
"enabling only shared libraries. Use -DENABLE_SHARED or -DENABLE_STATIC to "
"select one manually.")
set(ENABLE_SHARED ON)
endif()
find_package(PkgConfig)
2016-09-12 01:49:44 +08:00
if(COMPILE_AS_CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_FORMAT_MACROS=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_LIMIT_MACROS=1")
endif()
macro(set_source_language)
if(COMPILE_AS_CXX)
foreach(srcfile ${ARGN})
get_filename_component(srcext ${srcfile} EXT)
if(${srcext} STREQUAL ".c")
set_source_files_properties(${srcfile} PROPERTIES LANGUAGE CXX)
endif()
endforeach()
endif()
endmacro()
function(add_c_executable exec)
set_source_language(${ARGN})
add_executable(${exec} ${ARGN})
endfunction()
function(pkg_use_module mod pkg)
if(PKG_CONFIG_FOUND)
pkg_search_module(${mod} ${pkg})
endif()
2016-09-12 01:49:44 +08:00
if(${mod}_FOUND)
link_directories(${${mod}_LIBRARY_DIRS})
include_directories(${${mod}_INCLUDE_DIRS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${${mod}_CFLAGS_OTHER}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${mod}_CFLAGS_OTHER}" PARENT_SCOPE)
foreach(dir ${${mod}_INCLUDE_DIRS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isystem ${dir}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${dir}" PARENT_SCOPE)
endforeach()
2016-09-12 01:49:44 +08:00
endif()
endfunction()
macro(add_submodule super lib)
add_module(${lib} ${ARGN})
set(${super}_SUBLIBS ${${super}_SUBLIBS} ${lib})
set(${super}_SOURCES ${${super}_SOURCES} ${${lib}_SOURCES})
endmacro()
2016-09-12 01:49:44 +08:00
function(add_module lib)
set_source_language(${ARGN})
set(${lib}_SOURCES ${ARGN} PARENT_SCOPE)
2016-09-12 01:49:44 +08:00
if(ENABLE_SHARED)
add_library(${lib}_shared SHARED ${ARGN})
set_target_properties(${lib}_shared PROPERTIES OUTPUT_NAME ${lib})
endif()
if(ENABLE_STATIC)
add_library(${lib}_static STATIC ${ARGN})
set_target_properties(${lib}_static PROPERTIES OUTPUT_NAME ${lib})
endif()
# ${lib}_PKGCONFIG_LIBS is what's added to the Libs: line in ${lib}.pc. It
# needs to contain all the libraries a program using ${lib} should link against
# if it's statically linked. If it's dynamically linked, there is no need to
# explicitly link against all the dependencies, but it doesn't harm much(*)
# either.
#
# (*) It allows client code to use symbols from our dependencies without
# explicitly linking against them.
set(${lib}_PKGCONFIG_LIBS PARENT_SCOPE)
# Requires: in pkg-config file.
set(${lib}_PKGCONFIG_REQUIRES PARENT_SCOPE)
endfunction()
function(install_module lib)
if(ENABLE_SHARED)
set_target_properties(${lib}_shared PROPERTIES
VERSION ${SOVERSION}
SOVERSION ${SOVERSION_MAJOR}
)
2016-09-12 01:49:44 +08:00
install(TARGETS ${lib}_shared DESTINATION "lib")
endif()
if(ENABLE_STATIC)
install(TARGETS ${lib}_static DESTINATION "lib")
endif()
string(REPLACE ";" " " ${lib}_PKGCONFIG_LIBS "${${lib}_PKGCONFIG_LIBS}")
string(REPLACE ";" " " ${lib}_PKGCONFIG_REQUIRES "${${lib}_PKGCONFIG_REQUIRES}")
configure_file(
"${${lib}_SOURCE_DIR}/other/pkgconfig/${lib}.pc.in"
"${CMAKE_BINARY_DIR}/${lib}.pc"
@ONLY
)
install(FILES
${CMAKE_BINARY_DIR}/${lib}.pc
DESTINATION "lib/pkgconfig")
foreach(sublib ${${lib}_API_HEADERS})
string(REPLACE "^" ";" sublib ${sublib})
list(GET sublib 0 header)
install(FILES ${header} ${ARGN})
endforeach()
2016-09-12 01:49:44 +08:00
endfunction()
function(target_link_modules target)
# If the target we're adding dependencies to is a shared library, add it to
# the set of targets.
2016-09-12 01:49:44 +08:00
if(TARGET ${target}_shared)
set(_targets ${_targets} ${target}_shared)
# Shared libraries should first try to link against other shared libraries.
set(${target}_shared_primary shared)
# If that fails (because the shared target doesn't exist), try linking
# against the static library. This requires the static library's objects to
# be PIC.
set(${target}_shared_secondary static)
2016-09-12 01:49:44 +08:00
endif()
# It can also be a static library at the same time.
2016-09-12 01:49:44 +08:00
if(TARGET ${target}_static)
set(_targets ${_targets} ${target}_static)
# Static libraries aren't actually linked, but their dependencies are
# recorded by "linking" them. If we link an executable to a static library,
# we want to also link statically against its transitive dependencies.
set(${target}_static_primary static)
# If a dependency doesn't exist as static library, we link against the
# shared one.
set(${target}_static_secondary shared)
2016-09-12 01:49:44 +08:00
endif()
# If it's neither, then it's an executable.
2016-09-12 01:49:44 +08:00
if(NOT _targets)
set(_targets ${_targets} ${target})
# Executables preferably link against static libraries, so they are
# standalone and can be shipped without any external dependencies. As a
# frame of reference: nTox becomes an 1.3M binary instead of 139K on x86_64
# Linux.
set(${target}_primary static)
set(${target}_secondary shared)
2016-09-12 01:49:44 +08:00
endif()
foreach(dep ${ARGN})
foreach(_target ${_targets})
if(TARGET ${dep}_${${_target}_primary})
target_link_libraries(${_target} ${dep}_${${_target}_primary})
elseif(TARGET ${dep}_${${_target}_secondary})
target_link_libraries(${_target} ${dep}_${${_target}_secondary})
2016-09-12 01:49:44 +08:00
else()
# We record the modules linked to this target, so that we can collect
# them later when linking a composed module.
list(FIND LINK_MODULES ${dep} _index)
if(_index EQUAL -1)
set(LINK_MODULES ${LINK_MODULES} ${dep})
endif()
target_link_libraries(${_target} ${dep})
2016-09-12 01:49:44 +08:00
endif()
endforeach()
endforeach()
set(${target}_LINK_MODULES ${${target}_LINK_MODULES} ${LINK_MODULES} PARENT_SCOPE)
2016-09-12 01:49:44 +08:00
endfunction()