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() # Создание в каталоге ${CMAKE_BINARY_DIR} стандартных каталогов bin,include,lib, # а также символических ссылок на каталоги в ${CMAKE_SOURCE_DIR}/files if(NOT TARGET ${NAME}-populate-cmake-binary-dir) add_custom_target( ${NAME}-populate-cmake-binary-dir WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/bin COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/lib # Ссылка на каталог с журналами COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/files/log ${CMAKE_BINARY_DIR}/log # Ссылка на каталог с обрабатываемыми данными COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/files/var ${CMAKE_BINARY_DIR}/var # Ссылка на каталог с постоянными данными COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/files/share ${CMAKE_BINARY_DIR}/share # Ссылка на каталог настроек COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/files/etc ${CMAKE_BINARY_DIR}/etc ) add_dependencies(${NAME} ${NAME}-populate-cmake-binary-dir) 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 IS_DIRECTORY "${PROJECT_BINARY_DIR}/include") file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/include") 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() 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() target_sources(${NAME} PUBLIC $) target_sources(${NAME} PUBLIC ${ARG_PUBLIC_HEADERS}) target_sources(${NAME} PRIVATE ${ARG_CPP} ${ARG_PCH} ${ARG_PRIVATE_HEADERS}) target_link_libraries(${NAME} PRIVATE ${ARG_LINK_LIBRARIES}) target_compile_definitions(${NAME} PRIVATE ${ARG_COMPILE_DEFINITIONS}) # Установка публичных заголовочных файлов if(PROJECT_IS_TOP_LEVEL) install_relative(${PROJECT_SOURCE_DIR} FILES ${ARG_PUBLIC_HEADERS} ${ARG_INTERFACE_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT dev ) endif() endfunction()