diff --git a/.gersemirc b/.gersemirc index c6d6ef6c..b9cace7a 100644 --- a/.gersemirc +++ b/.gersemirc @@ -1,5 +1,6 @@ # yamllint disable-line rule:line-length # yaml-language-server: $schema=https://raw.githubusercontent.com/BlankSpruce/gersemi/master/gersemi/configuration.schema.json +definitions: ["CMake/ystdlib-cpp-helpers.cmake"] line_length: 100 list_expansion: "favour-expansion" diff --git a/CMake/ystdlib-cpp-helpers.cmake b/CMake/ystdlib-cpp-helpers.cmake new file mode 100644 index 00000000..997cd7dd --- /dev/null +++ b/CMake/ystdlib-cpp-helpers.cmake @@ -0,0 +1,35 @@ +# 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. +# +# @param NAME +# @param NAMESPACE +# @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. +function(cpp_library) + set(options "") + set(oneValueArgs + NAME + NAMESPACE + ) + set(multiValueArgs LIB_BUILD_INTERFACE) + cmake_parse_arguments(arg_cpp_lib "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # 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) + message( + FATAL_ERROR + "Missing build interface list for ${arg_cpp_lib_NAMESPACE}::${arg_cpp_lib_NAME}." + ) + elseif(NOT DEFINED arg_cpp_lib_LIB_BUILD_INTERFACE) + set(arg_cpp_lib_LIB_BUILD_INTERFACE "${PROJECT_SOURCE_DIR}/src") + endif() + + add_library(${arg_cpp_lib_NAME} INTERFACE) + target_include_directories( + ${arg_cpp_lib_NAME} + INTERFACE + "$" + ) + 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}) +endfunction() diff --git a/CMakeLists.txt b/CMakeLists.txt index 798b9658..fbffc4e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,14 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS FORCE ) +# Import CMake helper functions +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/CMake) +include(ystdlib-cpp-helpers) + +add_subdirectory(src/ystdlib) + +# Test dummy project add_executable(dummy) -target_sources(dummy PRIVATE src/ystdlib/hello.cpp) +target_sources(dummy PRIVATE src/main.cpp) +target_link_libraries(dummy PRIVATE ystdlib::testlib) target_compile_features(dummy PRIVATE cxx_std_20) diff --git a/README.md b/README.md index 63ccbaf8..7dc05193 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,18 @@ ystdlib-cpp =================================== An open-source C++ library developed and used at YScope. +# Usage +Clone `ystdlib-cpp` into your project. Then, in your project's `CMakeLists.txt`, add the following: +```cmake +add_subdirectory(/path/to/ystdlib-cpp EXCLUDE_FROM_ALL) +target_link_libraries( + ystdlib:: ystdlib:: ... ystdlib:: + # other libs... +) +``` +Ensure that `ystdlib-cpp` is either within a subdirectory of the folder containing `CMakeLists.txt` +or at the same level. + # Contributing Follow the steps below to develop and contribute to the project. @@ -15,7 +27,7 @@ Initialize and update submodules: git submodule update --init --recursive ``` -# Building +## Building To build all targets in `ystdlib-cpp`: ```shell task build:target diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 00000000..324fa36f --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,7 @@ +#include +#include + +[[nodiscard]] auto main() -> int { + std::cout << ystdlib::testlib::hello() << '\n'; + return 0; +} diff --git a/src/ystdlib/CMakeLists.txt b/src/ystdlib/CMakeLists.txt new file mode 100644 index 00000000..0d4ea731 --- /dev/null +++ b/src/ystdlib/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(testlib) diff --git a/src/ystdlib/hello.cpp b/src/ystdlib/hello.cpp deleted file mode 100644 index 5ed1c96a..00000000 --- a/src/ystdlib/hello.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -[[nodiscard]] auto main() -> int { - std::cout << "Hello, world!" << '\n'; - return 0; -} diff --git a/src/ystdlib/testlib/CMakeLists.txt b/src/ystdlib/testlib/CMakeLists.txt new file mode 100644 index 00000000..7c113fee --- /dev/null +++ b/src/ystdlib/testlib/CMakeLists.txt @@ -0,0 +1 @@ +cpp_library(NAME testlib NAMESPACE ystdlib) diff --git a/src/ystdlib/testlib/hello.hpp b/src/ystdlib/testlib/hello.hpp new file mode 100644 index 00000000..183acb60 --- /dev/null +++ b/src/ystdlib/testlib/hello.hpp @@ -0,0 +1,12 @@ +#ifndef YSTDLIB_TESTLIB_HELLO_HPP +#define YSTDLIB_TESTLIB_HELLO_HPP + +#include + +namespace ystdlib::testlib { +[[nodiscard]] inline auto hello() -> std::string { + return "Hello, world!"; +} +} // namespace ystdlib::testlib + +#endif // YSTDLIB_TESTLIB_HELLO_HPP diff --git a/taskfiles/lint-cmake.yaml b/taskfiles/lint-cmake.yaml index f3f2724a..cd232888 100644 --- a/taskfiles/lint-cmake.yaml +++ b/taskfiles/lint-cmake.yaml @@ -5,11 +5,15 @@ tasks: desc: "Runs the CMake linters." sources: &cmake_format_src_files - "{{.G_LINT_VENV_CHECKSUM_FILE}}" + - "{{.G_YSTDLIB_CPP_SRC_DIR}}/.gersemirc" - "{{.ROOT_DIR}}/**/*.cmake" - "{{.ROOT_DIR}}/**/*.cmake.in" - "{{.ROOT_DIR}}/**/CMakeLists.txt" + - "{{.ROOT_DIR}}/.gersemirc" - "{{.TASKFILE}}" - exclude: "{{.ROOT_DIR}}/**/build/*" + - exclude: "{{.ROOT_DIR}}/**/cmake_install.cmake" + - exclude: "{{.ROOT_DIR}}/**/CMakeFiles/*" - exclude: "{{.ROOT_DIR}}/**/submodules/*" - exclude: "{{.ROOT_DIR}}/**/tools/*" deps: @@ -44,7 +48,8 @@ tasks: - |- . "{{.G_LINT_VENV_DIR}}/bin/activate" find . \ - \( -path '**/build' -o -path '**/submodules' -o -path '**/tools' \) -prune -o \ + \( -path '**/build' -o -path '**/cmake_install.cmake' -o -path '**/CMakeFiles' \ + -o -path '**/submodules' -o -path '**/tools' \) -prune -o \ \( -iname "CMakeLists.txt" -o -iname "*.cmake" -o -iname "*.cmake.in" \) \ -print0 | \ xargs -0 gersemi {{.FLAGS}}