include_guard(DIRECTORY) include(${CMAKE_SOURCE_DIR}/cmake/ExportToParent.cmake) include(${CMAKE_SOURCE_DIR}/cmake/InstallBasic.cmake) include(${CMAKE_SOURCE_DIR}/cmake/ProtobufGenerateCpp.cmake) include(${CMAKE_SOURCE_DIR}/cmake/SetFirstDefined.cmake) include(${CMAKE_SOURCE_DIR}/cmake/safe_dep_glob.cmake) function(init_library) set(_options SHARED STATIC) set(_one_value_args NAME SOURCE_DIR INCLUDE_DIR ) set(_multi_value_args) cmake_parse_arguments(_ARGS "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN}) if (_ARGS_SHARED AND _ARGS_STATIC) message(FATAL_ERROR "Invalid args passed to init_library: cannot specify STATIC and SHARED") endif() set_first_defined(_name _ARGS_NAME PROJECT_NAME) set_first_defined(_source_dir _ARGS_SOURCE_DIR _name) set_first_defined(_include_dir _ARGS_INCLUDE_DIR _source_dir) # Cpp sources file( GLOB_RECURSE ${_name}_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${_source_dir}/*.cpp ) # Note: cpp files inside 'tests' dir(s) are considered tests. # Remove tests from main sources, and add them to test sources foreach(item ${${_name}_SOURCES}) if(${item} MATCHES "tests/.*\.cpp$") list(APPEND ${_name}_TEST_SOURCES ${item}) endif() endforeach() foreach(item ${${_name}_TEST_SOURCES}) list(REMOVE_ITEM ${_name}_SOURCES ${item}) endforeach() # Proto sources file( GLOB_RECURSE ${_name}_PROTO_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${_source_dir}/protobufs/*.proto ) update_deps_file("${${_name}_PROTO_SOURCES};") protobuf_generate_cpp( CXX_SOURCES ${_name}_CXX_PROTO_SOURCES CXX_HEADERS ${_name}_CXX_PROTO_HEADERS CXX_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR} PROTO_INCLUDE_DIRS ${EXTERNALS_INCLUDE} ${CMAKE_CURRENT_SOURCE_DIR} PROTO_SOURCES ${${_name}_PROTO_SOURCES} ) export_to_parent( ${_name}_SOURCES ${_name}_TEST_SOURCES ${_name}_PROTO_SOURCES ${_name}_CXX_PROTO_SOURCES ${_name}_CXX_PROTO_HEADERS ) # Add main lib if (_ARGS_STATIC) add_library(${_name} STATIC ${${_name}_SOURCES} ${${_name}_CXX_PROTO_SOURCES}) elseif(_ARGS_SHARED) add_library(${_name} SHARED ${${_name}_SOURCES} ${${_name}_CXX_PROTO_SOURCES}) else() add_library(${_name} ${${_name}_SOURCES} ${${_name}_CXX_PROTO_SOURCES}) endif() target_include_directories( ${_name} SYSTEM BEFORE PUBLIC $ $ ) target_include_directories( ${_name} PUBLIC $ $ ) # Include protos (if any) if (${_name}_PROTO_SOURCES) target_include_directories( ${_name} PUBLIC $ ) endif() target_link_directories( ${_name} PUBLIC $ $> $ ) # Install main lib foreach(_hdr ${${_name}_CXX_PROTO_HEADERS}) file(RELATIVE_PATH _relative_path ${CMAKE_CURRENT_BINARY_DIR} ${_hdr}) install(FILES ${_hdr} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${_relative_path}) endforeach() install_basic( NAME ${_name} INCLUDE_DIR ${_include_dir} ) # Add tests executable (if there are any) if (${_name}_TEST_SOURCES AND NOT WIN32) add_executable(${_name}-tests ${${_name}_TEST_SOURCES}) get_target_property(_lib_type ${_name} TYPE) if (_lib_type STREQUAL "SHARED_LIBRARY") # Set RPATH so the tests exe knows where to find the shared lib. set_target_properties( ${_name}-tests PROPERTIES BUILD_RPATH "$ORIGIN" INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}" ) endif() # Link main lib target_link_directories( ${_name}-tests PRIVATE $ $ ) target_link_libraries(${_name}-tests PRIVATE ${_name}) # Catch2 find_package(Catch2 CONFIG REQUIRED COMPONENTS Catch2WithMain) target_link_libraries(${_name}-tests PRIVATE Catch2::Catch2WithMain) endif() endfunction()