myx/MyxCMake/lib/TargetSetup.cmake
2022-10-19 14:39:26 +03:00

140 lines
5.5 KiB
CMake
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

include_guard(GLOBAL)
function(myx_target_setup TARGET_NAME)
set(options)
set(oneValueArgs PCH)
set(multiValueArgs COMPILE_DEFINITIONS PACKAGES LINK_LIBRARIES
CPP PUBLIC_HEADERS PRIVATE_HEADERS)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT TARGET ${TARGET_NAME})
myx_message_fatal_error("Target ${TARGET_NAME} does not exists.")
endif()
get_target_property(__target_type ${TARGET_NAME} TYPE)
foreach(iter ${ARG_PACKAGES})
target_include_directories(${TARGET_NAME} PRIVATE ${${iter}_INCLUDE_DIRS})
target_compile_definitions(${TARGET_NAME} PRIVATE ${${iter}_COMPILE_DEFINITIONS})
endforeach()
target_compile_definitions(${TARGET_NAME} PRIVATE ${ARG_COMPILE_DEFINITIONS})
if(ARG_CPP)
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY CPP_FILES ${ARG_CPP})
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY TR_FILES ${ARG_CPP})
endif()
if(ARG_PUBLIC_HEADERS)
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY PUBLIC_HEADER_FILES "${ARG_PUBLIC_HEADERS}")
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY TR_FILES ${ARG_PUBLIC_HEADERS})
endif()
if(ARG_PRIVATE_HEADERS)
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PRIVATE_HEADERS}")
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY TR_FILES ${ARG_PRIVATE_HEADERS})
endif()
if(ARG_PCH)
if((${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.16) AND (PROJECT_IS_TOP_LEVEL OR MYX_USE_LOCAL_DIRECTORIES))
target_precompile_headers(${TARGET_NAME} PRIVATE ${ARG_PCH})
else()
target_compile_options(${TARGET_NAME} PRIVATE -include ${ARG_PCH})
endif()
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PCH}")
endif()
if(NOT __target_type STREQUAL "INTERFACE_LIBRARY")
target_include_directories(${PROJECT_NAME} PRIVATE
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>)
if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/src")
target_include_directories(${PROJECT_NAME} PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
endif()
endif()
if(__target_type STREQUAL "EXECUTABLE")
if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/include")
target_include_directories(${PROJECT_NAME} PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
endif()
if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}")
target_include_directories(${PROJECT_NAME} PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}>)
endif()
set_target_properties(${TARGET_NAME} PROPERTIES
POSITION_INDEPENDENT_CODE ON
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
)
if(CMAKE_CXX_COMPILE_OPTIONS_PIE)
target_compile_options(${TARGET_NAME} PUBLIC ${CMAKE_CXX_COMPILE_OPTIONS_PIE})
endif()
install(TARGETS ${TARGET_NAME} COMPONENT MAIN RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(NOT ${__target_type} STREQUAL "INTERFACE_LIBRARY")
target_sources(${TARGET_NAME} PUBLIC $<BUILD_INTERFACE:${ARG_INTERFACE_HEADERS}>)
target_sources(${TARGET_NAME} PUBLIC ${ARG_PUBLIC_HEADERS})
target_sources(${TARGET_NAME} PRIVATE ${ARG_CPP} ${ARG_PCH} ${ARG_PRIVATE_HEADERS})
target_compile_definitions(${TARGET_NAME} PRIVATE ${ARG_COMPILE_DEFINITIONS})
endif()
if(${__target_type} STREQUAL "INTERFACE_LIBRARY")
foreach(__lib ${ARG_LINK_LIBRARIES})
if(TARGET ${__lib})
install(
TARGETS ${__lib}
EXPORT ${TARGET_NAME}Targets
COMPONENT LIB
)
endif()
endforeach()
target_link_libraries(${TARGET_NAME} INTERFACE ${ARG_LINK_LIBRARIES})
else()
# CMake до версии 3.12 не умеет извлекать из целей типа `OBJECT_LIBRARY`
# информацию о заголовочных файлах. Это обход.
if(${CMAKE_VERSION} VERSION_GREATER "3.11.99")
target_link_libraries(${TARGET_NAME} PRIVATE ${ARG_LINK_LIBRARIES})
else()
if((NOT ${__target_type} STREQUAL "OBJECT_LIBRARY") AND
(NOT ${__target_type} STREQUAL "EXECUTABLE"))
target_link_libraries(${TARGET_NAME} PRIVATE ${ARG_LINK_LIBRARIES})
else()
foreach(__link_library ${ARG_LINK_LIBRARIES})
if(TARGET ${__link_library})
get_target_property(__lib_type ${__link_library} TYPE)
if(__lib_type)
get_target_property(__include_dirs ${__link_library} INTERFACE_INCLUDE_DIRECTORIES)
if(__include_dirs)
target_include_directories(${TARGET_NAME} PUBLIC ${__include_dirs})
endif()
if(${__target_type} STREQUAL "EXECUTABLE")
if(${__lib_type} STREQUAL "OBJECT_LIBRARY")
if(TARGET ${__link_library}_static)
target_link_libraries(${TARGET_NAME} PRIVATE ${__link_library}_static)
else()
target_link_libraries(${TARGET_NAME} PRIVATE ${__link_library}_shared)
endif()
else()
target_link_libraries(${TARGET_NAME} PRIVATE ${__link_library})
endif()
endif()
endif()
endif()
endforeach()
endif()
endif()
endif()
# Установка публичных заголовочных файлов
if(PROJECT_IS_TOP_LEVEL)
myx_install_relative(${PROJECT_SOURCE_DIR}
FILES ${ARG_PUBLIC_HEADERS}
DESTINATION ${CMAKE_INSTALL_PREFIX}
COMPONENT DEV
)
endif()
endfunction()