Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 74 additions & 20 deletions CMake/ystdlib-cpp-helpers.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# @param SOURCE_LIST The list of source files to check.
# @param IS_HEADER_ONLY Returns whether the list only contains header files.
# @param NON_HEADER_FILE Returns the name of the first, if any, non-header file.
function(check_if_header_only SOURCE_LIST IS_HEADER_ONLY NON_HEADER_FILE)
set(_LOCAL_SOURCE_LIST "${${SOURCE_LIST}}")
foreach(src_file IN LISTS _LOCAL_SOURCE_LIST)
if(NOT ${src_file} MATCHES ".*\\.(h|hpp)")
set(${IS_HEADER_ONLY} FALSE PARENT_SCOPE)
set(${NON_HEADER_FILE} ${src_file} PARENT_SCOPE)
return()
endif()
endforeach()
set(${IS_HEADER_ONLY} TRUE PARENT_SCOPE)
set(${NON_HEADER_FILE} "" PARENT_SCOPE)
endfunction()

# Adds a c++20 interface library in the subdirectory NAME with the target NAME and alias
# NAMESPACE::NAME. Libraries with multiple levels of namespace nesting are currently not supported.
#
Expand All @@ -6,40 +22,82 @@
#
# @param NAME
# @param NAMESPACE
# @param PUBLIC_HEADERS
# @param PRIVATE_SOURCES
# @param PUBLIC_LINK_LIBRARIES
# @param PRIVATE_LINK_LIBRARIES
# @parms TESTS_SOURCES
# @param [LIB_BUILD_INTERFACE="${PROJECT_SOURCE_DIR}/src"] The list of include paths for building
# the library and for external projects that link against it via the add_subdirectory() function.
# @param [BUILD_INCLUDE_DIR="${PROJECT_SOURCE_DIR}/src"] The list of include paths for building the
# library and for external projects that builds `ystdlib-cpp` as a CMAKE subproject via the
# add_subdirectory() function.
function(cpp_library)
set(options "")
set(oneValueArgs
NAME
NAMESPACE
)
set(multiValueArgs
PUBLIC_HEADERS
PRIVATE_SOURCES
PUBLIC_LINK_LIBRARIES
PRIVATE_LINK_LIBRARIES
TESTS_SOURCES
LIB_BUILD_INTERFACE
BUILD_INCLUDE_DIR
)
cmake_parse_arguments(arg_cpp_lib "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

set(_ALIAS_TARGET_NAME "${arg_cpp_lib_NAMESPACE}::${arg_cpp_lib_NAME}")

# TODO: Turn this into a function for handling other optional params that have default values.
if("LIB_BUILD_INTERFACE" IN_LIST arg_cpp_lib_KEYWORDS_MISSING_VALUES)
if("BUILD_INCLUDE_DIR" IN_LIST arg_cpp_lib_KEYWORDS_MISSING_VALUES)
message(FATAL_ERROR "Missing build interface list for ${_ALIAS_TARGET_NAME}.")
elseif(NOT DEFINED arg_cpp_lib_BUILD_INCLUDE_DIR)
set(arg_cpp_lib_BUILD_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/src")
endif()

check_if_header_only(arg_cpp_lib_PUBLIC_HEADERS _IS_VALID_INTERFACE _INVALID_HEADER_FILE)
if(NOT _IS_VALID_INTERFACE)
message(
FATAL_ERROR
"Missing build interface list for ${arg_cpp_lib_NAMESPACE}::${arg_cpp_lib_NAME}."
"Invalid interface header file ${_INVALID_HEADER_FILE} for ${_ALIAS_TARGET_NAME}."
)
endif()

check_if_header_only(arg_cpp_lib_PRIVATE_SOURCES _IS_INTERFACE_LIB _)
if(_IS_INTERFACE_LIB)
add_library(${arg_cpp_lib_NAME} INTERFACE)
target_include_directories(
${arg_cpp_lib_NAME}
INTERFACE
"$<BUILD_INTERFACE:${arg_cpp_lib_BUILD_INCLUDE_DIR}>"
)
target_compile_features(${arg_cpp_lib_NAME} INTERFACE cxx_std_20)
else()
# The library type is specified by `BUILD_SHARED_LIBS` if it is defined. Otherwise, the type
# defaults to static.
add_library(${arg_cpp_lib_NAME})
target_sources(
${arg_cpp_lib_NAME}
PRIVATE
${arg_cpp_lib_PUBLIC_HEADERS}
${arg_cpp_lib_PRIVATE_SOURCES}
)
target_include_directories(
${arg_cpp_lib_NAME}
PUBLIC
"$<BUILD_INTERFACE:${arg_cpp_lib_BUILD_INCLUDE_DIR}>"
)
elseif(NOT DEFINED arg_cpp_lib_LIB_BUILD_INTERFACE)
set(arg_cpp_lib_LIB_BUILD_INTERFACE "${PROJECT_SOURCE_DIR}/src")
target_compile_features(${arg_cpp_lib_NAME} PUBLIC cxx_std_20)
endif()

# Build interface library
add_library(${arg_cpp_lib_NAME} INTERFACE)
target_include_directories(
target_link_libraries(
${arg_cpp_lib_NAME}
INTERFACE
"$<BUILD_INTERFACE:${arg_cpp_lib_LIB_BUILD_INTERFACE}>"
PUBLIC
${arg_cpp_lib_PUBLIC_LINK_LIBRARIES}
PRIVATE
${arg_cpp_lib_PRIVATE_LINK_LIBRARIES}
)
target_compile_features(${arg_cpp_lib_NAME} INTERFACE cxx_std_20)
add_library(${arg_cpp_lib_NAMESPACE}::${arg_cpp_lib_NAME} ALIAS ${arg_cpp_lib_NAME})
add_library(${_ALIAS_TARGET_NAME} ALIAS ${arg_cpp_lib_NAME})

if(YSTDLIB_CPP_ENABLE_TESTS)
# Build library-specific unit test target
Expand All @@ -50,7 +108,7 @@ function(cpp_library)
${_UNIT_TEST_TARGET}
PRIVATE
Catch2::Catch2WithMain
${arg_cpp_lib_NAMESPACE}::${arg_cpp_lib_NAME}
${_ALIAS_TARGET_NAME}
)
target_compile_features(${_UNIT_TEST_TARGET} PRIVATE cxx_std_20)
set_property(
Expand All @@ -63,10 +121,6 @@ function(cpp_library)

# Link against unified unit test
target_sources(${UNIFIED_UNIT_TEST_TARGET} PRIVATE ${arg_cpp_lib_TESTS_SOURCES})
target_link_libraries(
${UNIFIED_UNIT_TEST_TARGET}
PRIVATE
${arg_cpp_lib_NAMESPACE}::${arg_cpp_lib_NAME}
)
target_link_libraries(${UNIFIED_UNIT_TEST_TARGET} PRIVATE ${_ALIAS_TARGET_NAME})
endif()
endfunction()
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ project(YSTDLIB_CPP LANGUAGES CXX)

set(YSTDLIB_CPP_VERSION "0.0.1" CACHE STRING "Project version.")

option(BUILD_SHARED_LIBS "Build using shared libraries." OFF)
option(YSTDLIB_CPP_BUILD_TESTING "Build the testing tree for ystdlib-cpp." ON)

# Require compiler versions that support the C++20 features necessary for compiling ystdlib-cpp
if("AppleClang" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
set(YSTDLIB_CPP_CMAKE_CXX_COMPILER_MIN_VERSION "16")
Expand Down Expand Up @@ -43,7 +46,6 @@ if(YSTDLIB_CPP_IS_TOP_LEVEL)
include(CTest)
endif()

option(YSTDLIB_CPP_BUILD_TESTING "Build the testing tree for ystdlib-cpp." ON)
if(BUILD_TESTING AND YSTDLIB_CPP_BUILD_TESTING)
set(YSTDLIB_CPP_ENABLE_TESTS ON)
endif()
Expand Down
9 changes: 8 additions & 1 deletion src/ystdlib/containers/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
cpp_library(NAME container NAMESPACE ystdlib TESTS_SOURCES test/test_Array.cpp)
cpp_library(
NAME containers
NAMESPACE ystdlib
PUBLIC_HEADERS
Array.hpp
TESTS_SOURCES
test/test_Array.cpp
)
2 changes: 2 additions & 0 deletions src/ystdlib/error_handling/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
cpp_library(
NAME error_handling
NAMESPACE ystdlib
PUBLIC_HEADERS
ErrorCode.hpp
TESTS_SOURCES
test/constants.hpp
test/test_ErrorCode.cpp
Expand Down