diff options
Diffstat (limited to 'rcc/cmake/modules/AddRCC.cmake')
| -rw-r--r-- | rcc/cmake/modules/AddRCC.cmake | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/rcc/cmake/modules/AddRCC.cmake b/rcc/cmake/modules/AddRCC.cmake new file mode 100644 index 0000000..11bd92e --- /dev/null +++ b/rcc/cmake/modules/AddRCC.cmake @@ -0,0 +1,184 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +include_guard(GLOBAL) +include(GNUInstallDirs) +include(HandleRCCOptions) + +macro(rcc_configure_output_directories) + set(RCC_RUNTIME_OUTPUT_INTDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin") + set(RCC_LIBRARY_OUTPUT_INTDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${RCC_RUNTIME_OUTPUT_INTDIR}") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${RCC_LIBRARY_OUTPUT_INTDIR}") + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${RCC_LIBRARY_OUTPUT_INTDIR}") +endmacro() + +function(rcc_set_output_directory target) + if(WIN32 OR CYGWIN) + set(moduleDir "${RCC_RUNTIME_OUTPUT_INTDIR}") + else() + set(moduleDir "${RCC_LIBRARY_OUTPUT_INTDIR}") + endif() + if(NOT CMAKE_CFG_INTDIR STREQUAL ".") + foreach(buildMode IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER "${buildMode}" configSuffix) + if(RCC_RUNTIME_OUTPUT_INTDIR) + string(REPLACE "${CMAKE_CFG_INTDIR}" "${buildMode}" binaryDir "${RCC_RUNTIME_OUTPUT_INTDIR}") + set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${configSuffix} "${binaryDir}") + endif() + if(RCC_LIBRARY_OUTPUT_INTDIR) + string(REPLACE "${CMAKE_CFG_INTDIR}" "${buildMode}" libraryDir "${RCC_LIBRARY_OUTPUT_INTDIR}") + set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_${configSuffix} "${libraryDir}") + endif() + if(moduleDir) + string(REPLACE "${CMAKE_CFG_INTDIR}" "${buildMode}" configModuleDir "${moduleDir}") + set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${configSuffix} "${configModuleDir}") + endif() + endforeach() + else() + if(RCC_RUNTIME_OUTPUT_INTDIR) + set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${RCC_RUNTIME_OUTPUT_INTDIR}") + endif() + if(RCC_LIBRARY_OUTPUT_INTDIR) + set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${RCC_LIBRARY_OUTPUT_INTDIR}") + endif() + if(moduleDir) + set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${moduleDir}") + endif() + endif() +endfunction() + +function(rcc_update_pch target) + if(RCC_REQUIRES_RTTI OR RCC_REQUIRES_EH) + set(arg_DISABLE_PCH_REUSE ON) + endif() + get_target_property(sources ${target} SOURCES) + foreach(source IN LISTS sources) + get_filename_component(extension "${source}" EXT) + if(extension STREQUAL ".c" AND NOT arg_PRECOMPILE_HEADERS) + set(arg_DISABLE_PCH_REUSE ON) + elseif(extension STREQUAL ".mm") + set(arg_DISABLE_PCH_REUSE ON) + endif() + endforeach() + get_target_property(targetType ${target} TYPE) + if(targetType STREQUAL "EXECUTABLE") + get_target_property(positionIndependent ${target} POSITION_INDEPENDENT_CODE) + if(positionIndependent) + set(arg_DISABLE_PCH_REUSE ON) + endif() + endif() + + set(pchPriority 0) + foreach(library IN LISTS arg_LINK_LIBS) + if(TARGET ${library}) + get_target_property(libraryPriority ${library} RCC_PCH_PRIORITY) + get_target_property(libraryPCHDisabled ${library} DISABLE_PRECOMPILE_HEADERS) + if(libraryPriority GREATER pchPriority AND NOT libraryPCHDisabled) + set(pchPriority "${libraryPriority}") + set(pchReuse "${library}") + endif() + endif() + endforeach() + if(arg_PRECOMPILE_HEADERS) + message(DEBUG "Adding PCH ${arg_PRECOMPILE_HEADERS} for ${target} (prio ${pchPriority})") + target_precompile_headers(${target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${arg_PRECOMPILE_HEADERS}>") + if(NOT arg_DISABLE_PCH_REUSE) + math(EXPR pchPriority "${pchPriority} + 1") + set_target_properties(${target} PROPERTIES RCC_PCH_PRIORITY "${pchPriority}") + endif() + elseif(pchReuse AND NOT arg_DISABLE_PCH_REUSE) + message(DEBUG "Using PCH ${pchReuse} for ${target} (prio ${pchPriority})") + target_precompile_headers(${target} REUSE_FROM ${pchReuse}) + else() + message(DEBUG "Using NO PCH for ${target}") + endif() +endfunction() + +function(rcc_setup_rpath target) + if(CMAKE_INSTALL_RPATH) + return() + endif() + set(extraLibraryDir "") + if(RCC_INSTALL_PREFIX AND NOT RCC_INSTALL_PREFIX STREQUAL CMAKE_INSTALL_PREFIX) + set(extraLibraryDir "${RCC_LIBRARY_DIR}") + elseif(RCC_BUILD_LIBRARY_DIR) + set(extraLibraryDir "${RCC_LIBRARY_DIR}") + endif() + get_target_property(targetType ${target} TYPE) + if(targetType STREQUAL "EXECUTABLE") + set(installDirectory "${CMAKE_INSTALL_FULL_BINDIR}") + else() + set(installDirectory "${CMAKE_INSTALL_FULL_LIBDIR}") + endif() + file(RELATIVE_PATH relativeLibraryDir "${installDirectory}" "${CMAKE_INSTALL_FULL_LIBDIR}") + + if(APPLE) + set(installName INSTALL_NAME_DIR "@rpath") + set(installRpath "@loader_path/${relativeLibraryDir}" ${extraLibraryDir}) + elseif(CMAKE_SYSTEM_NAME MATCHES "AIX" AND BUILD_SHARED_LIBS) + set(installRpath "${RCC_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_FULL_LIBDIR}" ${extraLibraryDir}) + elseif(UNIX) + set(buildRpath "\$ORIGIN/../lib" ${extraLibraryDir}) + set(installRpath "\$ORIGIN/${relativeLibraryDir}") + if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|DragonFly") + target_link_options(${target} PRIVATE "LINKER:-z,origin") + endif() + if(RCC_LINKER_IS_GNULD AND RCC_LIBRARY_OUTPUT_INTDIR) + target_link_options(${target} PRIVATE "LINKER:-rpath-link,${RCC_LIBRARY_OUTPUT_INTDIR}") + endif() + else() + return() + endif() + if("${CMAKE_BUILD_RPATH}" STREQUAL "") + if(CMAKE_SYSTEM_NAME MATCHES "Darwin|AIX") + set_target_properties(${target} PROPERTIES BUILD_WITH_INSTALL_RPATH ON) + else() + set_property(TARGET ${target} APPEND PROPERTY BUILD_RPATH "${buildRpath}") + endif() + endif() + set_target_properties(${target} PROPERTIES INSTALL_RPATH "${installRpath}" ${installName}) +endfunction() + +function(rcc_configure_target target) + rcc_apply_options(${target}) + rcc_set_output_directory(${target}) + rcc_update_pch(${target}) + get_target_property(targetType ${target} TYPE) + if(targetType MATCHES "^(EXECUTABLE|SHARED_LIBRARY|MODULE_LIBRARY)$" AND NOT arg_NO_INSTALL_RPATH) + rcc_setup_rpath(${target}) + endif() + if(targetType STREQUAL "SHARED_LIBRARY") + if(MSVC) + set_target_properties(${target} PROPERTIES PREFIX "") + endif() + if(UNIX) + set_target_properties(${target} PROPERTIES + VERSION "${RCC_VERSION_MAJOR}.${RCC_VERSION_MINOR}" + SOVERSION "${RCC_VERSION_MAJOR}.${RCC_VERSION_MINOR}") + endif() + endif() +endfunction() + +function(add_rcc_library name) + cmake_parse_arguments(PARSE_ARGV 1 arg "DISABLE_PCH_REUSE;NO_INSTALL_RPATH" "" "LINK_LIBS;PRECOMPILE_HEADERS") + add_library(${name} ${arg_UNPARSED_ARGUMENTS}) + target_link_libraries(${name} PUBLIC RCCHeaders ${arg_LINK_LIBS}) + rcc_configure_target(${name}) + install(TARGETS ${name} EXPORT RCCTargets + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") +endfunction() + +function(add_rcc_executable name) + cmake_parse_arguments(PARSE_ARGV 1 arg "DISABLE_PCH_REUSE;NO_INSTALL_RPATH" "" "LINK_LIBS;PRECOMPILE_HEADERS") + add_executable(${name} ${arg_UNPARSED_ARGUMENTS}) + target_link_libraries(${name} PRIVATE RCCHeaders ${arg_LINK_LIBS}) + rcc_configure_target(${name}) +endfunction() + +function(add_rcc_tool name) + add_rcc_executable(${name} ${ARGN}) + install(TARGETS ${name} EXPORT RCCTargets + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") +endfunction() |
