# 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 "$<$:${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()