Skip to content

Commit

Permalink
feat(add): support FetchContent for cmake (#22)
Browse files Browse the repository at this point in the history
* add package target

* add release workflows

* refactor CMakeLists; enhance usability

* add alias for library name
  • Loading branch information
guuzaa authored Mar 17, 2024
1 parent b8124e9 commit f6bb7b3
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 59 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Release

on:
release:
types: [published]

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Create build environment
run: cmake -B build-release
- name: Package source code
working-directory: build-release/
run: cmake --build . --target package
- name: Add packaged source code to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: build-release/numbers-src.zip
tag: ${{ github.ref }}
61 changes: 41 additions & 20 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
cmake_minimum_required(VERSION 3.10)

set(BUILD_SHARED_LIBS OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(version 0.0.3)

string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL)
project(numbers VERSION ${version} LANGUAGES CXX)

if (PROJECT_IS_TOP_LEVEL)
message(STATUS "Project is top level")
endif()
set(BUILD_SHARED_LIBS OFF)

option(NUMBERS_TEST "Build and perform numbers tests" ${PROJECT_IS_TOP_LEVEL})
string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_IN_ROOT)

set(version 0.0.2)
set(CMAKE_EXPORT_COMPILE_COMMANDS ${PROJECT_IS_IN_ROOT})

project(numbers VERSION ${version} LANGUAGES CXX)
if(PROJECT_IS_IN_ROOT)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
message(STATUS "Project ${PROJECT_NAME} is in root")
endif()

# Check if the compiler supports C++17
if(NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 17)
message(FATAL_ERROR "Error: ${PROJECT_NAME} is a library for C++17 and later versions.")
endif()

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(NUMBERS_TEST "Build and perform ${PROJECT_NAME} tests" ${PROJECT_IS_IN_ROOT})
option(NUMBERS_EXAMPLE "Build and perform ${PROJECT_NAME} examples" ${PROJECT_IS_IN_ROOT})

# Includes.
set(SRC_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/src/include)
Expand All @@ -25,14 +31,29 @@ include_directories(${SRC_INCLUDE_DIR})

add_subdirectory(src)

if (NUMBERS_TEST)
message(STATUS "Building and running tests")
set(THIRD_PARTY_INCLUDE_DIR
${PROJECT_SOURCE_DIR}/third_party
)
include_directories(${THIRD_PARTY_INCLUDE_DIR})
if(NUMBERS_EXAMPLE)
add_subdirectory(examples)
endif()

add_subdirectory(examples)
add_subdirectory(third_party)
add_subdirectory(tests)
if(NUMBERS_TEST)
message(STATUS "Building and running tests")
set(THIRD_PARTY_INCLUDE_DIR
${PROJECT_SOURCE_DIR}/third_party
)
include_directories(${THIRD_PARTY_INCLUDE_DIR})

add_subdirectory(third_party)
add_subdirectory(tests)

# Provide only the minimum source files needed by downstream users
set(package_files src/ CMakeLists.txt LICENSE.txt)
set(packaged_zip ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-src.zip)
add_custom_command(
OUTPUT ${packaged_zip}
COMMAND ${CMAKE_COMMAND} -E tar c ${packaged_zip} --format=zip -- ${package_files}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "The source files have been packaged into ${packaged_zip}"
DEPENDS ${package_files}
)
add_custom_target(package DEPENDS ${packaged_zip})
endif()
28 changes: 28 additions & 0 deletions examples/overflowing-sub.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <iostream>
#include <tuple>

#include "numbers.h"

void for_error() {
size_t i;

// error - infinite loop
for (i = 10; i >= 0; i--) {
printf("[ID %u] Hello, World\n", i);
}
}

void for_correct() {
using namespace numbers;

u8 i;
bool flag = false;
for (i = 10; !flag && i >= 0; std::tie(i, flag) = i.overflowing_sub(1)) {
printf("[ID %u] Hello, World\n", i);
}
}

int main(int argc, char const *argv[]) {
for_correct();
return 0;
}
7 changes: 4 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
add_subdirectory(numbers)

add_library(numbers STATIC ${ALL_OBJECT_FILES})
add_library(${PROJECT_NAME} STATIC ${ALL_OBJECT_FILES})
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

target_include_directories(numbers PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEIR}>
target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEIR}>
)
28 changes: 25 additions & 3 deletions src/include/integer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,11 @@ class Integer {
return Integer(-num_);
}

constexpr bool operator==(const Integer<T> &other) const noexcept { return num_ == other.num_; }
constexpr bool operator<(const Integer<T> &other) const noexcept { return num_ < other.num_; }
constexpr bool operator>(const Integer<T> &other) const noexcept { return num_ > other.num_; }
constexpr bool operator==(Integer<T> other) const noexcept { return num_ == other.num_; }
constexpr bool operator<(Integer<T> other) const noexcept { return num_ < other.num_; }
constexpr bool operator>(Integer<T> other) const noexcept { return num_ > other.num_; }
constexpr bool operator<=(Integer<T> other) const noexcept { return num_ <= other.num_; }
constexpr bool operator>=(Integer<T> other) const noexcept { return num_ >= other.num_; }

Integer &operator+=(Integer other) {
*this = *this + other;
Expand Down Expand Up @@ -401,6 +403,26 @@ constexpr bool operator==(U lhs, Integer<T> rhs) noexcept {
return Integer<T>(lhs) == rhs;
}

template <typename U, typename T, typename = std::enable_if_t<std::is_signed_v<U> && std::is_convertible_v<U, T>>>
constexpr bool operator>(U lhs, Integer<T> rhs) noexcept {
return Integer<T>(lhs) > rhs;
}

template <typename U, typename T, typename = std::enable_if_t<std::is_signed_v<U> && std::is_convertible_v<U, T>>>
constexpr bool operator>=(U lhs, Integer<T> rhs) noexcept {
return Integer<T>(lhs) >= rhs;
}

template <typename U, typename T, typename = std::enable_if_t<std::is_signed_v<U> && std::is_convertible_v<U, T>>>
constexpr bool operator<(U lhs, Integer<T> rhs) noexcept {
return Integer<T>(lhs) < rhs;
}

template <typename U, typename T, typename = std::enable_if_t<std::is_signed_v<U> && std::is_convertible_v<U, T>>>
constexpr bool operator<=(U lhs, Integer<T> rhs) noexcept {
return Integer<T>(lhs) <= rhs;
}

using i8 = Integer<int8_t>;
using i16 = Integer<int16_t>;
using i32 = Integer<int32_t>;
Expand Down
22 changes: 22 additions & 0 deletions src/include/uinteger.hh
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ class Uinteger {
constexpr bool operator==(Uinteger<T> other) const noexcept { return num_ == other.num_; }
constexpr bool operator<(Uinteger<T> other) const noexcept { return num_ < other.num_; }
constexpr bool operator>(Uinteger<T> other) const noexcept { return num_ > other.num_; }
constexpr bool operator<=(Uinteger<T> other) const noexcept { return num_ <= other.num_; }
constexpr bool operator>=(Uinteger<T> other) const noexcept { return num_ >= other.num_; }

Uinteger &operator+=(Uinteger other) {
*this = *this + other;
Expand Down Expand Up @@ -340,6 +342,26 @@ constexpr bool operator==(U lhs, Uinteger<T> rhs) noexcept {
return Uinteger<T>(lhs) == rhs;
}

template <typename U, typename T, typename = std::enable_if_t< std::is_convertible_v<U, T>>>
constexpr bool operator>(U lhs, Uinteger<T> rhs) noexcept {
return Uinteger<T>(lhs) > rhs;
}

template <typename U, typename T, typename = std::enable_if_t<std::is_convertible_v<U, T>>>
constexpr bool operator>=(U lhs, Uinteger<T> rhs) noexcept {
return Uinteger<T>(lhs) >= rhs;
}

template <typename U, typename T, typename = std::enable_if_t<std::is_convertible_v<U, T>>>
constexpr bool operator<(U lhs, Uinteger<T> rhs) noexcept {
return Uinteger<T>(lhs) < rhs;
}

template <typename U, typename T, typename = std::enable_if_t<std::is_convertible_v<U, T>>>
constexpr bool operator<=(U lhs, Uinteger<T> rhs) noexcept {
return Uinteger<T>(lhs) <= rhs;
}

using u8 = Uinteger<uint8_t>;
using u16 = Uinteger<uint16_t>;
using u32 = Uinteger<uint32_t>;
Expand Down
10 changes: 5 additions & 5 deletions src/numbers/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
file(GLOB obj_files "${CMAKE_CURRENT_SOURCE_DIR}/*.cc")

add_library(
numbers_obj
OBJECT
${obj_files}
numbers_obj
OBJECT
${obj_files}
)

set(ALL_OBJECT_FILES
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:numbers_obj>
PARENT_SCOPE)
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:numbers_obj>
PARENT_SCOPE)
22 changes: 11 additions & 11 deletions tests/integer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ file(GLOB_RECURSE test_files "${CMAKE_CURRENT_SOURCE_DIR}/*.test.cc")
set(PROJECT_NAME integer_test)

add_executable(
${PROJECT_NAME}
EXCLUDE_FROM_ALL
${test_files}
${PROJECT_NAME}
EXCLUDE_FROM_ALL
${test_files}
)

target_link_libraries(${PROJECT_NAME} PRIVATE numbers_obj test_utils gtest gmock_main)

gtest_discover_tests(${PROJECT_NAME}
EXTRA_ARGS
--gtest_output=xml:${CMAKE_BINARY_DIR}/test/${PROJECT_NAME}.xml
--gtest_catch_exceptions=0
DISCOVERY_TIMEOUT 120
PROPERTIES
TIMEOUT 120
EXTRA_ARGS
--gtest_output=xml:${CMAKE_BINARY_DIR}/test/${PROJECT_NAME}.xml
--gtest_catch_exceptions=0
DISCOVERY_TIMEOUT 120
PROPERTIES
TIMEOUT 120
)

set_target_properties(${PROJECT_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test"
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test"
)

list(APPEND TEST_TARGETS ${PROJECT_NAME} PARENT_SCOPE)
Expand Down
22 changes: 11 additions & 11 deletions tests/uinteger/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ file(GLOB_RECURSE test_files "${CMAKE_CURRENT_SOURCE_DIR}/*.test.cc")
set(PROJECT_NAME uinteger_test)

add_executable(
${PROJECT_NAME}
EXCLUDE_FROM_ALL
${test_files}
${PROJECT_NAME}
EXCLUDE_FROM_ALL
${test_files}
)

target_link_libraries(${PROJECT_NAME} PRIVATE numbers_obj test_utils gtest gmock_main)

gtest_discover_tests(${PROJECT_NAME}
EXTRA_ARGS
--gtest_output=xml:${CMAKE_BINARY_DIR}/test/${PROJECT_NAME}.xml
--gtest_catch_exceptions=0
DISCOVERY_TIMEOUT 120
PROPERTIES
TIMEOUT 120
EXTRA_ARGS
--gtest_output=xml:${CMAKE_BINARY_DIR}/test/${PROJECT_NAME}.xml
--gtest_catch_exceptions=0
DISCOVERY_TIMEOUT 120
PROPERTIES
TIMEOUT 120
)

set_target_properties(${PROJECT_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test"
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/test"
)

list(APPEND TEST_TARGETS ${PROJECT_NAME} PARENT_SCOPE)
Expand Down
12 changes: 6 additions & 6 deletions tests/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
add_library(
test_utils
EXCLUDE_FROM_ALL
OBJECT
utils.cc
test_utils
EXCLUDE_FROM_ALL
OBJECT
utils.cc
)

set(ALL_OBJECT_FILES
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:test_utils>
PARENT_SCOPE)
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:test_utils>
PARENT_SCOPE)

0 comments on commit f6bb7b3

Please sign in to comment.