Advertisement
Guest User

Untitled

a guest
Jan 10th, 2024
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
CMake 6.66 KB | None | 0 0
  1. # add cpp library
  2. # named parameters:
  3. #  NAME: name of the library
  4. #  HDRS: header files
  5. #  SRCS: source files
  6. #  MODS: module files
  7. #  DEPS: dependencies
  8. #  MACROS: macros
  9. #  CONFIGS: CMake configurable header files
  10. #  COMPILE_OPTIONS: compile options
  11. #  COMPILE_FEATURES: compile features
  12. function(robocin_cpp_library)
  13.   cmake_parse_arguments(
  14.           ARG                                                                     # prefix of output variables
  15.           ""                                                                      # list of names of the boolean arguments
  16.           "NAME"                                                                  # list of names of mono-valued arguments
  17.           "HDRS;SRCS;MODS;DEPS;MACROS;CONFIGS;COMPILE_OPTIONS;COMPILE_FEATURES"   # list of names of multi-valued arguments
  18.           ${ARGN}                                                                 # arguments of the function to parse (ARGN contains all the arguments after the function name)
  19.   )
  20.  
  21.   # if there isn't at least one module file, then should be at least one header file and one source file
  22.   if (NOT ARG_MODS)
  23.     # if there isn't at least one header file, then the library is not created
  24.     if (NOT ARG_HDRS)
  25.       message(FATAL_ERROR "robocin_cpp_library: no header files given.")
  26.     endif ()
  27.  
  28.     # if there isn't at least one source file, then the library is not created
  29.     if (NOT ARG_SRCS)
  30.       message(FATAL_ERROR "robocin_cpp_library: no source files given.")
  31.     endif ()
  32.   endif ()
  33.  
  34.   # if there are CMake configurable files, then they are configured and added to the library
  35.   if (ARG_CONFIGS)
  36.     foreach (CONFIG_FILE ${ARG_CONFIGS})
  37.       get_filename_component(config_last_extension ${CONFIG_FILE} LAST_EXT)
  38.  
  39.       if (NOT ${config_last_extension} STREQUAL ".in")
  40.         message(FATAL_ERROR "robocin_cpp_library: invalid extension '${config_last_extension}' for configurable file '${CONFIG_FILE}'.")
  41.       endif ()
  42.  
  43.       get_filename_component(config_absolute_file ${CONFIG_FILE} ABSOLUTE)
  44.       get_filename_component(config_absolute_path ${config_absolute_file} DIRECTORY)
  45.       file(RELATIVE_PATH config_relative_subdirectory ${CMAKE_CURRENT_SOURCE_DIR} ${config_absolute_path})
  46.  
  47.       get_filename_component(config_filename ${CONFIG_FILE} NAME_WLE)
  48.       robocin_concatenate_paths("${config_relative_subdirectory}" "${config_filename}" config_filename)
  49.  
  50.       configure_file(${CONFIG_FILE} ${config_filename})
  51.       robocin_concatenate_paths("${CMAKE_CURRENT_BINARY_DIR}" "${config_filename}" config_filename_real_path)
  52.       list(APPEND CONFIG_HDRS "${config_filename_real_path}")
  53.     endforeach ()
  54.   endif ()
  55.  
  56.   add_library(${ARG_NAME} ${ARG_HDRS} ${ARG_SRCS} ${ARG_MODS} ${CONFIG_HDRS}) # add library with given name, headers, sources and modules
  57.   target_link_libraries(${ARG_NAME} PUBLIC ${ARG_DEPS}) # link library with given dependencies
  58.  
  59.   if (ARG_MODS)
  60.     if (CMAKE_CXX_STANDARD)
  61.       if (CMAKE_CXX_STANDARD GREATER_EQUAL 20)
  62.         target_compile_features(${ARG_NAME} PUBLIC cxx_std_${CMAKE_CXX_STANDARD})
  63.       else ()
  64.         message(FATAL_ERROR "robocin_cpp_library: modules are only supported with C++20 or newer.")
  65.       endif ()
  66.     else ()
  67.       message(WARNING "robocin_cpp_library: CMAKE_CXX_STANDARD is not defined when adding modules to library '${ARG_NAME}'. Using C++20 as default.")
  68.       target_compile_features(${ARG_NAME} PUBLIC cxx_std_20)
  69.     endif ()
  70.   endif ()
  71.  
  72.   target_include_directories(${ARG_NAME} PRIVATE ${ROBOCIN_PROJECT_PATH})
  73.   target_include_directories(${ARG_NAME} PRIVATE ${CMAKE_BINARY_DIR})
  74.  
  75.   target_compile_definitions(${ARG_NAME} PRIVATE ROBOCIN_PROJECT_NAME="${ROBOCIN_PROJECT_NAME}")
  76.   target_compile_definitions(${ARG_NAME} PRIVATE ROBOCIN_PROJECT_PATH="${ROBOCIN_PROJECT_PATH}")
  77.  
  78.   target_sources(${ARG_NAME} PUBLIC FILE_SET CXX_MODULES FILES ${ARG_MODS})
  79.  
  80.   if (ARG_MACROS)
  81.     target_compile_definitions(${ARG_NAME} ${ARG_MACROS})
  82.   endif ()
  83.  
  84.   if (ARG_COMPILE_OPTIONS)
  85.     target_compile_options(${ARG_NAME} ${ARG_COMPILE_OPTIONS})
  86.   endif ()
  87.  
  88.   if (ARG_COMPILE_FEATURES)
  89.     target_compile_features(${ARG_NAME} ${ARG_COMPILE_FEATURES})
  90.   endif ()
  91.  
  92.   # installing steps:
  93.   #  - include directories to be used by other projects
  94.   target_include_directories(${ARG_NAME} INTERFACE
  95.           $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
  96.           $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
  97.   )
  98.   #  - install header files preserving the directory structure
  99.   foreach (HDR_FILE ${ARG_HDRS})
  100.     get_filename_component(header_absolute_file ${HDR_FILE} ABSOLUTE)
  101.     get_filename_component(header_absolute_path ${header_absolute_file} DIRECTORY)
  102.     file(RELATIVE_PATH header_relative_path ${ROBOCIN_PROJECT_PATH} ${header_absolute_path})
  103.  
  104.     robocin_concatenate_paths("${CMAKE_INSTALL_INCLUDEDIR}" "${header_relative_path}" header_install_path)
  105.     install(FILES ${HDR_FILE} DESTINATION "${header_install_path}")
  106.   endforeach ()
  107.   #  - install module files preserving the directory structure
  108.   foreach (MOD_FILE ${ARG_MODS})
  109.     get_filename_component(module_absolute_file ${MOD_FILE} ABSOLUTE)
  110.     get_filename_component(module_absolute_path ${module_absolute_file} DIRECTORY)
  111.     file(RELATIVE_PATH module_relative_path ${ROBOCIN_PROJECT_PATH} ${module_absolute_path})
  112.  
  113.     robocin_concatenate_paths("${CMAKE_INSTALL_INCLUDEDIR}" "${module_relative_path}" module_install_path)
  114.     install(FILES ${MOD_FILE} DESTINATION "${module_install_path}")
  115.   endforeach ()
  116.   #  - install config files preserving the directory structure
  117.   foreach (CONFIG_HDR ${CONFIG_HDRS})
  118.     file(RELATIVE_PATH config_relative_path ${ROBOCIN_PROJECT_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
  119.  
  120.     get_filename_component(config_relative_subdirectory ${CONFIG_HDR} DIRECTORY)
  121.     file(RELATIVE_PATH config_relative_subdirectory ${CMAKE_CURRENT_BINARY_DIR} ${config_relative_subdirectory})
  122.  
  123.     robocin_concatenate_paths("${config_relative_path}" "${config_relative_subdirectory}" config_relative_path)
  124.     robocin_concatenate_paths("${CMAKE_INSTALL_INCLUDEDIR}" "${config_relative_path}" config_install_path)
  125.  
  126.     install(FILES ${CONFIG_HDR} DESTINATION "${config_install_path}")
  127.   endforeach ()
  128.   #  - install library
  129.   install(TARGETS ${ARG_NAME} EXPORT "${PROJECT_NAME}Targets" FILE_SET HEADERS DESTINATION include
  130.                                                               FILE_SET CXX_MODULES DESTINATION modules)
  131.   #  - install CMake configuration files
  132.   install(
  133.           EXPORT "${PROJECT_NAME}Targets"
  134.           NAMESPACE "${PROJECT_NAME}::"
  135.           FILE "${PROJECT_NAME}Config.cmake"
  136.           DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
  137.   )
  138.  
  139. endfunction(robocin_cpp_library)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement