include_guard(GLOBAL) function(myx_target_setup NAME) set(options) set(oneValueArgs PCH) set(multiValueArgs COMPILE_DEFINITIONS PACKAGES LINK_LIBRARIES CPP INTERFACE_HEADERS PUBLIC_HEADERS PRIVATE_HEADERS) cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT TARGET ${NAME}) myx_message_fatal_error("Target ${NAME} does not exists.") endif() get_target_property(target_type ${NAME} TYPE) foreach(iter ${ARG_PACKAGES}) target_include_directories(${NAME} PRIVATE ${${iter}_INCLUDE_DIRS}) target_compile_definitions(${NAME} PRIVATE ${${iter}_COMPILE_DEFINITIONS}) endforeach() target_compile_definitions(${NAME} PRIVATE ${ARG_COMPILE_DEFINITIONS}) if(ARG_CPP) set_property(TARGET ${NAME} APPEND PROPERTY CPP_FILES ${ARG_CPP}) set_property(TARGET ${NAME} APPEND PROPERTY TR_FILES ${ARG_CPP}) endif() if(ARG_PUBLIC_HEADERS) set_property(TARGET ${NAME} APPEND PROPERTY PUBLIC_HEADER_FILES "${ARG_PUBLIC_HEADERS}") set_property(TARGET ${NAME} APPEND PROPERTY TR_FILES ${ARG_PUBLIC_HEADERS}) endif() if(ARG_PRIVATE_HEADERS) set_property(TARGET ${NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PRIVATE_HEADERS}") set_property(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(${NAME} PRIVATE ${ARG_PCH}) else() target_compile_options(${NAME} PRIVATE -include ${ARG_PCH}) endif() set_property(TARGET ${NAME} APPEND PROPERTY PRIVATE_HEADER_FILES "${ARG_PCH}") endif() if(NOT target_type STREQUAL "INTERFACE_LIBRARY") target_include_directories(${PROJECT_NAME} PRIVATE $) if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/src") target_include_directories(${PROJECT_NAME} PRIVATE $) endif() endif() if(target_type STREQUAL "EXECUTABLE") if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/include") target_include_directories(${PROJECT_NAME} PRIVATE $) endif() if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}") target_include_directories(${PROJECT_NAME} PRIVATE $) endif() set_target_properties(${NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} ) if(CMAKE_CXX_COMPILE_OPTIONS_PIE) target_compile_options(${NAME} PUBLIC ${CMAKE_CXX_COMPILE_OPTIONS_PIE}) endif() install(TARGETS ${NAME} COMPONENT main RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() if(${target_type} STREQUAL "INTERFACE_LIBRARY") target_sources(${NAME} INTERFACE $) else() target_sources(${NAME} PUBLIC $) target_sources(${NAME} PUBLIC ${ARG_PUBLIC_HEADERS}) target_sources(${NAME} PRIVATE ${ARG_CPP} ${ARG_PCH} ${ARG_PRIVATE_HEADERS}) target_compile_definitions(${NAME} PRIVATE ${ARG_COMPILE_DEFINITIONS}) endif() # CMake до версии 3.12 не умеет извлекать из целей типа `OBJECT_LIBRARY` # информацию о заголовочных файлах. Это обход. if(${CMAKE_VERSION} VERSION_GREATER "3.11.99") target_link_libraries(${NAME} PRIVATE ${ARG_LINK_LIBRARIES}) else() if((NOT ${target_type} STREQUAL "OBJECT_LIBRARY") AND (NOT ${target_type} STREQUAL "EXECUTABLE")) target_link_libraries(${NAME} PRIVATE ${ARG_LINK_LIBRARIES}) elseif(${target_type} STREQUAL "INTERFACE") target_link_libraries(${NAME} INTERFACE ${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_dir ${link_library} INTERFACE_INCLUDE_DIRECTORIES) if(include_dir) target_include_directories(${NAME} PUBLIC ${include_dir}) endif() if(${target_type} STREQUAL "EXECUTABLE") if(${lib_type} STREQUAL "OBJECT_LIBRARY") if(TARGET ${link_library}_static) target_link_libraries(${NAME} PRIVATE ${link_library}_static) else() target_link_libraries(${NAME} PRIVATE ${link_library}_shared) endif() else() target_link_libraries(${NAME} PRIVATE ${link_library}) endif() endif() endif() endif() endforeach() endif() endif() # Установка публичных заголовочных файлов if(PROJECT_IS_TOP_LEVEL) myx_install_relative(${PROJECT_SOURCE_DIR} FILES ${ARG_PUBLIC_HEADERS} ${ARG_INTERFACE_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT dev ) endif() endfunction()