Skip to content

build(cmake): Allow ystdlib-cpp to be imported into other CMake projects as a library #65

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
dec0712
Make ystdlib a cmake library
PacificViking May 26, 2025
4aa941c
add missing ystdlib-config.cmake.in file
PacificViking May 26, 2025
662e768
add coderabbit suggestions
PacificViking May 26, 2025
3fbc72e
refactor: Update to the latest version of yscope-dev-utils:
anlowee May 27, 2025
93c4d50
Modify according to coderabbit suggestion
PacificViking May 27, 2025
98e1c54
fix(taskfiles): Enable `globstar` in main taskfile so that `**/*` wor…
LinZhihao-723 May 28, 2025
0a88c49
add changes according to coderabbit suggestions
PacificViking May 28, 2025
e4dc708
fix gersemi linting errors for cmakelists
PacificViking May 29, 2025
a3bc9d5
this cmake.in file is preprocessed and should not be linted
PacificViking May 30, 2025
d80cf86
feat: Replace `outcome` with Boost's version of `outcome` to remove d…
anlowee Jun 2, 2025
601c462
fix coderabbit suggestion
PacificViking Jun 5, 2025
2e54cdb
public target_compile_features
PacificViking Jun 5, 2025
f5e2b4b
Merge remote-tracking branch 'upstream/main' into dev
PacificViking Jun 6, 2025
89f53c1
cleanup unnecessary dependencies, merge new yscope-dev-utils
PacificViking Jun 6, 2025
1d313c3
use correct yscope-dev-utils version
PacificViking Jun 6, 2025
2f9f30b
Merge branch 'backup-main'
PacificViking Jun 6, 2025
a63a4f2
fix version ordering error
PacificViking Jun 6, 2025
847162f
add example, require boost
PacificViking Jun 6, 2025
5e55b58
rename project name and relevant variables to ystdlib (from YSTDLIB_CPP)
PacificViking Jun 6, 2025
77fc7ea
not working: splitting libraries
PacificViking Jun 6, 2025
521c1f9
working examples without filesets but with separate library targets
PacificViking Jun 6, 2025
1c44077
Merge branch 'dev'
PacificViking Jun 6, 2025
c8a3c93
modify according to coderabbit suggestions
PacificViking Jun 6, 2025
ef48733
fix examples/cmakelists according to coderabbit
PacificViking Jun 6, 2025
f62ee82
use filesets
PacificViking Jun 8, 2025
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
17 changes: 17 additions & 0 deletions CMake/ystdlib-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# gersemi: off
# this file is preprocessed and should not be linted like a CMake file
include(CMakeFindDependencyMacro)
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Include CMakePackageConfigHelpers for config helpers
To ensure the macros set_and_check and check_required_components are available, add

include(CMakePackageConfigHelpers)

immediately after include(CMakeFindDependencyMacro), or verify that @PACKAGE_INIT@ injects it.

🤖 Prompt for AI Agents
In CMake/ystdlib-config.cmake.in at lines 1 to 3, the file includes
CMakeFindDependencyMacro but does not include CMakePackageConfigHelpers, which
provides the macros set_and_check and check_required_components. To fix this,
add the line include(CMakePackageConfigHelpers) immediately after the
include(CMakeFindDependencyMacro) line, or verify that the @PACKAGE_INIT@
variable injects this include; if not, explicitly add the include to ensure
these macros are available.


@PACKAGE_INIT@

find_dependency(Boost REQUIRED)

set_and_check(ystdlib_INCLUDE_DIR "@PACKAGE_ystdlib_INSTALL_INCLUDE_DIR@")

check_required_components(ystdlib)

# Avoid repeatedly including the targets
if(NOT TARGET ystdlib::ystdlib)
include("${CMAKE_CURRENT_LIST_DIR}/ystdlib-targets.cmake")
endif()
# gersemi: on
47 changes: 33 additions & 14 deletions CMake/ystdlib-cpp-helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ 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.
#
# If `YSTDLIB_CPP_ENABLE_TESTS` is ON, builds the unit tests specific to the current library, and
# links this library against the unified unit test target for the entire `ystdlib-cpp` project.
# If `ystdlib_ENABLE_TESTS` is ON, builds the unit tests specific to the current library, and
# links this library against the unified unit test target for the entire `ystdlib` project.
#
# @param {string} NAME
# @param {string} NAMESPACE
Expand All @@ -40,7 +40,7 @@ endfunction()
# @param {string[]} [PRIVATE_LINK_LIBRARIES]
# @param {string[]} [TESTS_LINK_LIBRARIES]
# @param {string[]} [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
# building the library and for external projects that builds `ystdlib` as a CMAKE subproject via
# the add_subdirectory() function.
function(cpp_library)
set(options "")
Expand Down Expand Up @@ -96,12 +96,9 @@ function(cpp_library)
endif()
add_library(${arg_cpp_lib_NAME} INTERFACE)
target_link_libraries(${arg_cpp_lib_NAME} INTERFACE ${arg_cpp_lib_PUBLIC_LINK_LIBRARIES})
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.
Expand All @@ -119,17 +116,32 @@ function(cpp_library)
PRIVATE
${arg_cpp_lib_PRIVATE_LINK_LIBRARIES}
)
target_include_directories(
${arg_cpp_lib_NAME}
PUBLIC
"$<BUILD_INTERFACE:${arg_cpp_lib_BUILD_INCLUDE_DIR}>"
)
target_compile_features(${arg_cpp_lib_NAME} PUBLIC cxx_std_20)
endif()

add_library(${_ALIAS_TARGET_NAME} ALIAS ${arg_cpp_lib_NAME})

if(YSTDLIB_CPP_ENABLE_TESTS)
# replaces header_include_directories
# replaces header installation
target_sources(
${arg_cpp_lib_NAME}
PUBLIC
FILE_SET HEADERS
BASE_DIRS
"$<BUILD_INTERFACE:${arg_cpp_lib_BUILD_INCLUDE_DIR}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
FILES
${arg_cpp_lib_PUBLIC_HEADERS}
)

set_target_properties(
${arg_cpp_lib_NAME}
PROPERTIES
LINKER_LANGUAGE
CXX
)

if(ystdlib_ENABLE_TESTS)
# Build library-specific unit test target
set(_UNIT_TEST_TARGET "unit-test-${arg_cpp_lib_NAME}")
add_executable(${_UNIT_TEST_TARGET})
Expand All @@ -150,6 +162,13 @@ function(cpp_library)
${CMAKE_BINARY_DIR}/testbin
)

set_target_properties(
${_UNIT_TEST_TARGET}
PROPERTIES
LINKER_LANGUAGE
CXX
)

# Link against unified unit test
target_sources(${UNIFIED_UNIT_TEST_TARGET} PRIVATE ${arg_cpp_lib_TESTS_SOURCES})
target_link_libraries(
Expand Down
86 changes: 66 additions & 20 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
cmake_minimum_required(VERSION 3.22.1)
cmake_minimum_required(VERSION 3.23)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
include(ystdlib-cpp-helpers)
set(ystdlib_VERSION "0.0.1" CACHE STRING "Project version.")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Ensure consistent variable naming prefix.
The project cache variable ystdlib_VERSION should follow your established convention (e.g., YSTDLIB_CPP_VERSION), using uppercase and the YSTDLIB_CPP_ prefix for clarity and to avoid conflicts.

🤖 Prompt for AI Agents
In CMakeLists.txt at line 3, the cache variable ystdlib_VERSION uses
inconsistent naming. Rename it to follow the established uppercase prefix
convention as YSTDLIB_CPP_VERSION to ensure clarity and avoid conflicts. Update
the set command accordingly to use YSTDLIB_CPP_VERSION instead of
ystdlib_VERSION.


project(YSTDLIB_CPP LANGUAGES CXX)
project(ystdlib VERSION "${ystdlib_VERSION}" LANGUAGES CXX)

set(YSTDLIB_CPP_VERSION "0.0.1" CACHE STRING "Project version.")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
include(ystdlib-cpp-helpers)
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

option(BUILD_SHARED_LIBS "Build using shared libraries." OFF)
option(YSTDLIB_CPP_BUILD_TESTING "Build the testing tree for ystdlib-cpp." ON)
option(ystdlib_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")
set(ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION "16")
elseif("Clang" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
set(YSTDLIB_CPP_CMAKE_CXX_COMPILER_MIN_VERSION "16")
set(ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION "16")
elseif("GNU" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
set(YSTDLIB_CPP_CMAKE_CXX_COMPILER_MIN_VERSION "11")
set(ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION "11")
Comment on lines +17 to +21
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

DRY up compiler version logic.
The three set(ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION ...) calls for AppleClang, Clang, and GNU are largely identical. Consider collapsing the AppleClang and Clang cases into one branch or using a lookup map to reduce duplication.

🤖 Prompt for AI Agents
In CMakeLists.txt around lines 17 to 21, the compiler minimum version setting is
duplicated for AppleClang and Clang. Refactor by combining the AppleClang and
Clang conditions into a single branch that sets the minimum version to 16,
reducing redundancy. Alternatively, use a lookup map or variable to assign the
minimum version based on the compiler ID in a more concise way.

else()
message(
FATAL_ERROR
"Unsupported compiler: ${CMAKE_CXX_COMPILER_ID}. Please use AppleClang, Clang, or GNU."
)
endif()
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "${YSTDLIB_CPP_CMAKE_CXX_COMPILER_MIN_VERSION}")
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "${ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION}")
message(
FATAL_ERROR
"${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION} is too low. Must be at \
least ${YSTDLIB_CPP_CMAKE_CXX_COMPILER_MIN_VERSION}."
least ${ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION}."
Comment on lines +28 to +32
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Refine multiline error message.
The use of a backslash and split string in your message(FATAL_ERROR ...) makes the text harder to read. Collapse into a single line or use CMake’s automatic wrapping:

message(FATAL_ERROR
  "${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION} is too low; at least ${ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION} is required."
)
🤖 Prompt for AI Agents
In CMakeLists.txt around lines 28 to 32, the multiline error message uses a
backslash and split string which reduces readability. Replace the multiline
string with a single line message using CMake's automatic wrapping by combining
the text into one continuous string inside the message(FATAL_ERROR ...) call.

)
endif()

Expand All @@ -39,7 +41,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS
FORCE
)

if(YSTDLIB_CPP_IS_TOP_LEVEL)
if(ystdlib_IS_TOP_LEVEL)
# Include dependency settings if the project isn't being included as a subproject.
# NOTE: We mark the file optional because if the user happens to have the dependencies
# installed, this file is not necessary.
Expand All @@ -49,18 +51,16 @@ if(YSTDLIB_CPP_IS_TOP_LEVEL)
include(CTest)
endif()

if(BUILD_TESTING AND YSTDLIB_CPP_BUILD_TESTING)
set(YSTDLIB_CPP_ENABLE_TESTS ON)
if(BUILD_TESTING AND ystdlib_BUILD_TESTING)
set(ystdlib_ENABLE_TESTS ON)
endif()

find_package(outcome REQUIRED)
if(outcome_FOUND)
message(STATUS "Found outcome.")
else()
message(FATAL_ERROR "Could not find libraries for outcome.")
find_package(Boost REQUIRED)
if(Boost_FOUND)
message(STATUS "Found Boost ${Boost_VERSION}.")
Comment on lines +58 to +60
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Specify Boost components explicitly.
A bare find_package(Boost REQUIRED) only locates the root and include dirs. If you rely on header-only modules, use:

find_package(Boost REQUIRED COMPONENTS headers)

or list specific components to ensure consistency.

🤖 Prompt for AI Agents
In CMakeLists.txt around lines 58 to 60, the find_package call for Boost does
not specify any components, which only locates the root and include directories.
To fix this, explicitly list the required Boost components in the find_package
call, for example by adding COMPONENTS headers or other specific modules your
project depends on, ensuring consistent and complete Boost detection.

endif()
Comment on lines +58 to 61
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify Boost dependency scope and completeness.

The switch from outcome to Boost appears incomplete. Based on past review comments, there should be proper linkage to Boost targets for downstream consumers.

Let me verify the current dependency setup and ensure proper target linkage:


🏁 Script executed:

#!/bin/bash
# Check for Boost target linkage in library targets
echo "=== Checking for Boost target linkage in ystdlib libraries ==="
find src -name "CMakeLists.txt" -exec grep -l "Boost::" {} \;

echo -e "\n=== Checking specific Boost targets used ==="
rg "Boost::" src/ -A 2 -B 2

echo -e "\n=== Checking if main ystdlib target links to Boost ==="
rg "target_link_libraries.*ystdlib" CMakeLists.txt -A 5 -B 2

Length of output: 882


Ensure main ystdlib target properly links Boost

We found that only src/ystdlib/error_handling/CMakeLists.txt PUBLIC-links Boost::headers, but the root CMakeLists.txt does not propagate any Boost targets. Downstream consumers of ystdlib will not inherit this dependency.

• In CMakeLists.txt (lines 58–61), after find_package(Boost REQUIRED), add:

target_link_libraries(ystdlib PUBLIC Boost::headers)

(or include any other Boost components in use)

• Confirm your install(EXPORT …) exports also list Boost so that consuming projects pick up the dependency.

Suggested diff:

 find_package(Boost REQUIRED)
 if(Boost_FOUND)
     message(STATUS "Found Boost ${Boost_VERSION}.")
 endif()
+target_link_libraries(ystdlib PUBLIC Boost::headers)
🤖 Prompt for AI Agents
In CMakeLists.txt around lines 58 to 61, after the find_package(Boost REQUIRED)
call, the main ystdlib target does not link to Boost targets, so downstream
consumers won't inherit the Boost dependency. Fix this by adding
target_link_libraries(ystdlib PUBLIC Boost::headers) or other relevant Boost
components used by ystdlib. Also, verify that the install(EXPORT ...) commands
include Boost to properly export the dependency for consuming projects.


if(YSTDLIB_CPP_ENABLE_TESTS)
if(ystdlib_ENABLE_TESTS)
find_package(Catch2 3.8.0 REQUIRED)
if(Catch2_FOUND)
message(STATUS "Found Catch2 ${Catch2_VERSION}.")
Expand All @@ -84,4 +84,50 @@ if(YSTDLIB_CPP_ENABLE_TESTS)
catch_discover_tests(${UNIFIED_UNIT_TEST_TARGET} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/testbin)
endif()

set(ystdlib_INSTALL_CONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/ystdlib)
set(ystdlib_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR})
Comment on lines +87 to +88
Copy link

@coderabbitai coderabbitai bot Jun 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Install directory variables need prefix.
The variables ystdlib_INSTALL_CONFIG_DIR and ystdlib_INSTALL_INCLUDE_DIR should use your project prefix and uppercase style (e.g., YSTDLIB_CPP_INSTALL_CONFIG_DIR) to align with other cache variables.

🤖 Prompt for AI Agents
In CMakeLists.txt around lines 87 to 88, rename the variables
ystdlib_INSTALL_CONFIG_DIR and ystdlib_INSTALL_INCLUDE_DIR to use the project
prefix in uppercase style, such as YSTDLIB_CPP_INSTALL_CONFIG_DIR and
YSTDLIB_CPP_INSTALL_INCLUDE_DIR, to maintain consistency with other cache
variables. Update all references accordingly to reflect this naming convention.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we are no longer using project prefix uppercase style.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for current naming patterns in CMake files to verify the naming convention
echo "=== Searching for ystdlib_ prefixed variables (lowercase) ==="
rg "ystdlib_[A-Z_]+" --type cmake -A 1 -B 1

echo -e "\n=== Searching for YSTDLIB_CPP_ prefixed variables (uppercase) ==="
rg "YSTDLIB_CPP_[A-Z_]+" --type cmake -A 1 -B 1

echo -e "\n=== Searching for all project-specific variables in CMakeLists.txt ==="
rg "(ystdlib_|YSTDLIB_)" CMakeLists.txt -A 1 -B 1

Length of output: 5224


@PacificViking You're absolutely correct! The codebase search confirms that the project has indeed standardized on lowercase ystdlib_ prefixed variables. I can see consistent usage throughout:

  • ystdlib_VERSION
  • ystdlib_BUILD_TESTING
  • ystdlib_ENABLE_TESTS
  • ystdlib_IS_TOP_LEVEL
  • And many others

The variables ystdlib_INSTALL_CONFIG_DIR and ystdlib_INSTALL_INCLUDE_DIR are correctly named according to your current naming convention. My suggestion was based on outdated information. Thank you for the correction!


✏️ Learnings added
Learnt from: PacificViking
PR: y-scope/ystdlib-cpp#65
File: CMakeLists.txt:87-88
Timestamp: 2025-06-06T15:01:53.952Z
Learning: The y-scope/ystdlib-cpp project uses lowercase `ystdlib_` prefix for project-specific CMake variables (e.g., `ystdlib_VERSION`, `ystdlib_BUILD_TESTING`, `ystdlib_INSTALL_CONFIG_DIR`) following the current naming convention standards.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


⛔ Learnings removed
Learnt from: Bill-hbrhbr
PR: y-scope/ystdlib-cpp#32
File: CMakeLists.txt:0-0
Timestamp: 2025-02-28T05:04:33.616Z
Learning: The y-scope/ystdlib-cpp project uses the "YSTDLIB_CPP_" prefix for project-specific CMake variables, following good naming convention practices.

🧠 Learnings used
Learnt from: Bill-hbrhbr
PR: y-scope/ystdlib-cpp#32
File: CMakeLists.txt:0-0
Timestamp: 2025-02-28T05:04:33.616Z
Learning: The y-scope/ystdlib-cpp project uses the "YSTDLIB_CPP_" prefix for project-specific CMake variables, following good naming convention practices.


add_subdirectory(src/ystdlib)

set(ystdlib_targets
containers
error_handling
io_interface
wrapped_facade_headers)

foreach(install_target_name IN LISTS ystdlib_targets)

install(TARGETS
${install_target_name}
EXPORT ystdlib-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FILE_SET HEADERS
)

endforeach()


install(EXPORT ystdlib-targets NAMESPACE ystdlib:: DESTINATION ${ystdlib_INSTALL_CONFIG_DIR})

configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/CMake/ystdlib-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/ystdlib-config.cmake
INSTALL_DESTINATION ${ystdlib_INSTALL_CONFIG_DIR}
PATH_VARS
ystdlib_INSTALL_INCLUDE_DIR
)
Comment on lines +114 to +120
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Include all relevant path variables.
When calling configure_package_config_file, consider adding ystdlib_INSTALL_CONFIG_DIR to PATH_VARS so the generated config file reflects the correct install location for your package directory itself.

🤖 Prompt for AI Agents
In CMakeLists.txt around lines 106 to 112, the call to
configure_package_config_file includes only ystdlib_INSTALL_INCLUDE_DIR in
PATH_VARS. To ensure the generated config file correctly reflects the install
location of the package directory, add ystdlib_INSTALL_CONFIG_DIR to the
PATH_VARS list. This will make the config file aware of the package install
directory path.


Comment on lines +114 to +121
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Include config dir in PATH_VARS
Add ystdlib_INSTALL_CONFIG_DIR to the PATH_VARS of configure_package_config_file so the generated config file points to the correct install directory.

🤖 Prompt for AI Agents
In CMakeLists.txt around lines 106 to 113, the configure_package_config_file
call is missing ystdlib_INSTALL_CONFIG_DIR in the PATH_VARS list. Add
ystdlib_INSTALL_CONFIG_DIR to the PATH_VARS argument so the generated config
file correctly references the install directory path.

write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/ystdlib-config-version.cmake
COMPATIBILITY SameMajorVersion
)

install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/ystdlib-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/ystdlib-config-version.cmake
DESTINATION ${ystdlib_INSTALL_CONFIG_DIR}
)

9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ An open-source C++ library developed and used at YScope.
# Usage

## Via CMake's add_subdirectory()
> Note: this is not accurate in this branch, which is a work in progress to use ystdlib-cpp as a
CMake library
Comment on lines +7 to +8
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Clarify library import note
The added blockquote clearly indicates that add_subdirectory usage is WIP. Consider ensuring this note is revisited or removed once the feature is stabilised.

🤖 Prompt for AI Agents
In README.md around lines 7 to 8, the note about using ystdlib-cpp as a CMake
library is marked as a work in progress. Add a reminder comment or TODO to
revisit and remove or update this note once the add_subdirectory feature is
stable to keep documentation accurate and up to date.


Clone `ystdlib-cpp` into your project. Then, in your project's `CMakeLists.txt`, add the following:
```cmake
Comment on lines 10 to 11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Surround fenced code blocks with blank lines
Markdown lint recommends blank lines before and after fenced code blocks to avoid MD031 violations.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

11-11: Fenced code blocks should be surrounded by blank lines
null

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
In README.md around lines 10 to 11, the fenced code block is not surrounded by
blank lines, which violates Markdown lint rule MD031. Add a blank line before
and after the fenced code block to ensure proper formatting and compliance with
the lint rule.

# Set `YSTDLIB_CPP_BUILD_TESTING` to an accepted `FALSE` class value to skip building unit tests.
# option(YSTDLIB_CPP_BUILD_TESTING "" OFF)
# Set `ystdlib_BUILD_TESTING` to an accepted `FALSE` class value to skip building unit tests.
# option(ystdlib_BUILD_TESTING "" OFF)
add_subdirectory(/path/to/ystdlib-cpp EXCLUDE_FROM_ALL)
target_link_libraries(<target_name> <link_options>
ystdlib::<lib_1> ystdlib::<lib_2> ... ystdlib::<lib_N>
Expand Down Expand Up @@ -64,7 +67,7 @@ task test-<lib_name>
```

When generating a testing target, the CMake variable `BUILD_TESTING` is followed (unless overruled
by setting `YSTDLIB_CPP_BUILD_TESTING` to false). By default, if built as a top-level project,
by setting `ystdlib_BUILD_TESTING` to false). By default, if built as a top-level project,
`BUILD_TESTING` is set to true and unit tests are built.

## Linting
Expand Down
30 changes: 30 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.22.1)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Consider updating CMake version requirement for consistency.

The examples project requires CMake 3.22.1, but the main project now requires 3.23. For consistency and to ensure all features work properly, consider updating to match the main project requirement.

-cmake_minimum_required(VERSION 3.22.1)
+cmake_minimum_required(VERSION 3.23)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cmake_minimum_required(VERSION 3.22.1)
cmake_minimum_required(VERSION 3.23)
🤖 Prompt for AI Agents
In examples/CMakeLists.txt at line 1, update the cmake_minimum_required version
from 3.22.1 to 3.23 to match the main project's CMake version requirement for
consistency and compatibility.


project(ystdlib-examples)

include("${CMAKE_SOURCE_DIR}/../build/deps/cmake-settings/settings.cmake" REQUIRED)

if(NOT DEFINED ystdlib_ROOT)
set(ystdlib_ROOT "${CMAKE_SOURCE_DIR}/../build/build_install")
endif()
find_package(ystdlib REQUIRED)

add_library(
common
OBJECT
types.cpp
types.hpp
constants.hpp
)
target_link_libraries(common PRIVATE ystdlib::error_handling)
add_executable(main main.cpp)

target_compile_features(main PRIVATE cxx_std_20)
target_compile_features(common PRIVATE cxx_std_20)

target_link_libraries(
main
PRIVATE
ystdlib::error_handling
common
)
9 changes: 9 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cmake ..

Run above command from examples/build

Dependencies:

After building main project, cd to build and run

cmake --install . --prefix=build_install to have an install location
18 changes: 18 additions & 0 deletions examples/constants.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef EXAMPLE_CONSTANTS_HPP
#define EXAMPLE_CONSTANTS_HPP

#include <array>
#include <string_view>
#include <system_error>

namespace ystdlib::error_handling::test {
constexpr std::string_view cAlwaysSuccessErrorCategoryName{"Always Success Error Code"};
constexpr std::string_view cBinaryTestErrorCategoryName{"Binary Error Code"};
constexpr std::string_view cSuccessErrorMsg{"Success"};
constexpr std::string_view cFailureErrorMsg{"Failure"};
constexpr std::string_view cUnrecognizedErrorCode{"Unrecognized Error Code"};
constexpr std::array cFailureConditions{std::errc::not_connected, std::errc::timed_out};
constexpr std::array cNoneFailureConditions{std::errc::broken_pipe, std::errc::address_in_use};
} // namespace ystdlib::error_handling::test

#endif // EXAMPLE_CONSTANTS_HPP
53 changes: 53 additions & 0 deletions examples/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <algorithm>
#include <string_view>
#include <system_error>

#include <ystdlib/error_handling/ErrorCode.hpp>

#include "constants.hpp"
#include "types.hpp"

#include <cassert>
#include <iostream>

using namespace ystdlib::error_handling::test;

int main() {
// Test error codes within the same error category
BinaryErrorCode const success{BinaryErrorCodeEnum::Success};
std::error_code const success_error_code{success};
assert((success == success_error_code));
assert((cSuccessErrorMsg == success_error_code.message()));
assert((BinaryErrorCode::get_category() == success_error_code.category()));
assert((cBinaryTestErrorCategoryName == success_error_code.category().name()));

BinaryErrorCode const failure{BinaryErrorCodeEnum::Failure};
std::error_code const failure_error_code{failure};
assert((failure == failure_error_code));
assert((cFailureErrorMsg == failure_error_code.message()));
assert((BinaryErrorCode::get_category() == failure_error_code.category()));
assert((cBinaryTestErrorCategoryName == failure_error_code.category().name()));

assert((success_error_code != failure_error_code));
assert((success_error_code.category() == failure_error_code.category()));

AlwaysSuccessErrorCode const always_success{AlwaysSuccessErrorCodeEnum::Success};
std::error_code const always_success_error_code{always_success};
assert((always_success_error_code == always_success));
assert((cSuccessErrorMsg == always_success_error_code.message()));
assert((AlwaysSuccessErrorCode::get_category() == always_success_error_code.category()));
assert((cAlwaysSuccessErrorCategoryName == always_success_error_code.category().name()));

// Compare error codes from different error category
// Error codes that have the same value or message won't be the same with each other if they are
// from different error categories.
assert((success_error_code.value() == always_success_error_code.value()));
assert((success_error_code.message() == always_success_error_code.message()));
assert((success_error_code.category() != always_success_error_code.category()));
assert((success_error_code != always_success_error_code));
assert((AlwaysSuccessErrorCode{AlwaysSuccessErrorCodeEnum::Success} != success_error_code));
assert((BinaryErrorCode{BinaryErrorCodeEnum::Success} != always_success_error_code));

std::cout << "test is good!" << std::endl;
return 0;
}
Loading