🎉 init(cmake): init modern cmake template
This commit is contained in:
commit
120ef25b84
BIN
.cache/clangd/index/app.cpp.585A27E459A42788.idx
Normal file
BIN
.cache/clangd/index/app.cpp.585A27E459A42788.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/lib.cpp.3E5A22867B4F266E.idx
Normal file
BIN
.cache/clangd/index/lib.cpp.3E5A22867B4F266E.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/lib.hpp.C6091EB14F97B140.idx
Normal file
BIN
.cache/clangd/index/lib.hpp.C6091EB14F97B140.idx
Normal file
Binary file not shown.
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*build*
|
78
CMakeLists.txt
Normal file
78
CMakeLists.txt
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# Works with 3.14 and tested through 3.29
|
||||||
|
cmake_minimum_required(VERSION 3.14...3.29)
|
||||||
|
|
||||||
|
# Project name and a few useful settings. Other commands can pick up the results
|
||||||
|
project(
|
||||||
|
ModernCMakeExample
|
||||||
|
VERSION 0.1
|
||||||
|
DESCRIPTION "An example project with CMake"
|
||||||
|
LANGUAGES CXX)
|
||||||
|
|
||||||
|
# Only do these if this is the main project, and not if it is included through add_subdirectory
|
||||||
|
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||||
|
|
||||||
|
# Optionally set things like CMAKE_CXX_STANDARD, CMAKE_POSITION_INDEPENDENT_CODE here
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
# set(CMAKE_CXX_STANDARD_REQUIRED 17)
|
||||||
|
set(default_build_type "Release")
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
|
||||||
|
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
|
||||||
|
STRING "Choose the type of build." FORCE)
|
||||||
|
# Set the possible values of build type for cmake-gui
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||||
|
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
# Let's ensure -std=c++xx instead of -std=g++xx
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
# Let's nicely support folders in IDEs
|
||||||
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
|
# Testing only available if this is the main app
|
||||||
|
# Note this needs to be done in the main CMakeLists
|
||||||
|
# since it calls enable_testing, which must be in the
|
||||||
|
# main CMakeLists.
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
|
# Docs only available if this is the main app
|
||||||
|
find_package(Doxygen)
|
||||||
|
if(Doxygen_FOUND)
|
||||||
|
add_subdirectory(docs)
|
||||||
|
else()
|
||||||
|
message(STATUS "Doxygen not found, not building docs")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# FetchContent added in CMake 3.11, downloads during the configure step
|
||||||
|
# FetchContent_MakeAvailable was added in CMake 3.14; simpler usage
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
# Accumulator library
|
||||||
|
# This is header only, so could be replaced with git submodules or FetchContent
|
||||||
|
find_package(Boost REQUIRED)
|
||||||
|
# Adds Boost::boost
|
||||||
|
|
||||||
|
# Formatting library
|
||||||
|
FetchContent_Declare(
|
||||||
|
fmtlib
|
||||||
|
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
|
||||||
|
GIT_TAG 5.3.0)
|
||||||
|
FetchContent_MakeAvailable(fmtlib)
|
||||||
|
# Adds fmt::fmt
|
||||||
|
|
||||||
|
# The compiled library code is here
|
||||||
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
# The executable code is here
|
||||||
|
add_subdirectory(apps)
|
||||||
|
|
||||||
|
# Testing only available if this is the main app
|
||||||
|
# Emergency override MODERN_CMAKE_BUILD_TESTING provided as well
|
||||||
|
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR MODERN_CMAKE_BUILD_TESTING)
|
||||||
|
AND BUILD_TESTING)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif()
|
34
Makefile
Normal file
34
Makefile
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
## 定义基本编译命令到变量中
|
||||||
|
# CC=gcc
|
||||||
|
# CXX=g++
|
||||||
|
|
||||||
|
default:
|
||||||
|
cmake -S . -B build -GNinja
|
||||||
|
|
||||||
|
release:
|
||||||
|
cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
debug:
|
||||||
|
cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
docs:
|
||||||
|
cmake --build build --target docs
|
||||||
|
|
||||||
|
test:
|
||||||
|
cmake --build build --target test
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm build -rf
|
||||||
|
|
||||||
|
.PHONY: help clean
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Usage: make [target]"
|
||||||
|
@echo " default: build the project"
|
||||||
|
@echo " release: build the project with release mode"
|
||||||
|
@echo " debug: build the project with debug mode"
|
||||||
|
@echo " docs: build the project documentation"
|
||||||
|
@echo " clean: clean the project"
|
||||||
|
@echo " help: show this help message"
|
46
README.md
Normal file
46
README.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# CMake Template
|
||||||
|
|
||||||
|
This is an example project using CMake.
|
||||||
|
|
||||||
|
The requirements are:
|
||||||
|
|
||||||
|
- CMake 3.11 or better; 3.14+ highly recommended.
|
||||||
|
- A C++17 compatible compiler
|
||||||
|
- The Boost libararies (header only part is fine)
|
||||||
|
- Git
|
||||||
|
- Doxygen (optional)
|
||||||
|
|
||||||
|
To configure:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake -S . -B build
|
||||||
|
```
|
||||||
|
|
||||||
|
Add `-GNinja` if you have Ninja.
|
||||||
|
|
||||||
|
To build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
To test (`--target` can be written as `-t` in CMake 3.15+):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake --build build --target test
|
||||||
|
```
|
||||||
|
|
||||||
|
To build docs (requires Doxygen, output in `build/docs/html`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake --build build --target docs
|
||||||
|
```
|
||||||
|
|
||||||
|
To use an IDE, such as Xcode:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake -S . -B xbuild -GXcode
|
||||||
|
cmake --open xbuild
|
||||||
|
```
|
||||||
|
|
||||||
|
The CMakeLists show off several useful design patterns for CMake.
|
4
apps/CMakeLists.txt
Normal file
4
apps/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
add_executable(app app.cpp)
|
||||||
|
target_compile_features(app PRIVATE cxx_std_17)
|
||||||
|
|
||||||
|
target_link_libraries(app PRIVATE modern_library fmt::fmt)
|
17
apps/app.cpp
Normal file
17
apps/app.cpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include <modern/lib.hpp>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::vector<double> input = {1.2, 2.3, 3.4, 4.5};
|
||||||
|
|
||||||
|
auto [mean, moment] = accumulate_vector(input);
|
||||||
|
|
||||||
|
fmt::print("Mean: {}, Moment: {}\n", mean, moment);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
1
cmake/FindSomeLib.cmake
Normal file
1
cmake/FindSomeLib.cmake
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
5
docs/CMakeLists.txt
Normal file
5
docs/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
set(DOXYGEN_EXTRACT_ALL YES)
|
||||||
|
set(DOXYGEN_BUILTIN_STL_SUPPORT YES)
|
||||||
|
|
||||||
|
doxygen_add_docs(docs modern/lib.hpp "${CMAKE_CURRENT_SOURCE_DIR}/mainpage.md"
|
||||||
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/include")
|
11
docs/mainpage.md
Normal file
11
docs/mainpage.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Documentation for Modern Library {#mainpage}
|
||||||
|
|
||||||
|
This is the documentation for my simple example library.
|
||||||
|
|
||||||
|
It is good documentation because:
|
||||||
|
|
||||||
|
1. It exists.
|
||||||
|
2. I wrote it.
|
||||||
|
3. Everything is documented (pretty easy since there's only one function)
|
||||||
|
|
||||||
|
The single provided function is `::accumulate_vector`.
|
0
externals/.git-keep
vendored
Normal file
0
externals/.git-keep
vendored
Normal file
12
include/modern/lib.hpp
Normal file
12
include/modern/lib.hpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
/// \brief Accumulate a vector to produce the mean and the first moment of the distribution.
|
||||||
|
///
|
||||||
|
/// This computes the mean and the first moment of a vector of double values.
|
||||||
|
///
|
||||||
|
std::tuple<double, double> accumulate_vector(
|
||||||
|
const std::vector<double>& values ///< The vector of values
|
||||||
|
);
|
24
src/CMakeLists.txt
Normal file
24
src/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Note that headers are optional, and do not affect add_library, but they will not
|
||||||
|
# show up in IDEs unless they are listed in add_library.
|
||||||
|
|
||||||
|
# Optionally glob, but only for CMake 3.12 or later:
|
||||||
|
# file(GLOB HEADER_LIST CONFIGURE_DEPENDS "${ModernCMakeExample_SOURCE_DIR}/include/modern/*.hpp")
|
||||||
|
set(HEADER_LIST "${ModernCMakeExample_SOURCE_DIR}/include/modern/lib.hpp")
|
||||||
|
|
||||||
|
# Make an automatic library - will be static or dynamic based on user setting
|
||||||
|
add_library(modern_library lib.cpp ${HEADER_LIST})
|
||||||
|
|
||||||
|
# We need this directory, and users of our library will need it too
|
||||||
|
target_include_directories(modern_library PUBLIC ../include)
|
||||||
|
|
||||||
|
# This depends on (header only) boost
|
||||||
|
target_link_libraries(modern_library PRIVATE Boost::boost)
|
||||||
|
|
||||||
|
# All users of this library will need at least C++11
|
||||||
|
target_compile_features(modern_library PUBLIC cxx_std_11)
|
||||||
|
|
||||||
|
# IDEs should put the headers in a nice place
|
||||||
|
source_group(
|
||||||
|
TREE "${PROJECT_SOURCE_DIR}/include"
|
||||||
|
PREFIX "Header Files"
|
||||||
|
FILES ${HEADER_LIST})
|
21
src/lib.cpp
Normal file
21
src/lib.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include <modern/lib.hpp>
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boost/accumulators/accumulators.hpp>
|
||||||
|
#include <boost/accumulators/statistics/stats.hpp>
|
||||||
|
#include <boost/accumulators/statistics/mean.hpp>
|
||||||
|
#include <boost/accumulators/statistics/moment.hpp>
|
||||||
|
|
||||||
|
namespace ba = boost::accumulators;
|
||||||
|
|
||||||
|
std::tuple<double, double> accumulate_vector(const std::vector<double>& values) {
|
||||||
|
|
||||||
|
ba::accumulator_set<double, ba::stats<ba::tag::mean, ba::tag::moment<2>>> acc;
|
||||||
|
|
||||||
|
std::for_each(std::begin(values), std::end(values), std::ref(acc));
|
||||||
|
|
||||||
|
return {ba::mean(acc), ba::moment<2>(acc)};
|
||||||
|
}
|
20
tests/CMakeLists.txt
Normal file
20
tests/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Testing library
|
||||||
|
FetchContent_Declare(
|
||||||
|
catch
|
||||||
|
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
||||||
|
GIT_TAG v2.13.6)
|
||||||
|
FetchContent_MakeAvailable(catch)
|
||||||
|
# Adds Catch2::Catch2
|
||||||
|
|
||||||
|
# Tests need to be added as executables first
|
||||||
|
add_executable(testlib testlib.cpp)
|
||||||
|
|
||||||
|
# I'm using C++17 in the test
|
||||||
|
target_compile_features(testlib PRIVATE cxx_std_17)
|
||||||
|
|
||||||
|
# Should be linked to the main library, as well as the Catch2 testing library
|
||||||
|
target_link_libraries(testlib PRIVATE modern_library Catch2::Catch2)
|
||||||
|
|
||||||
|
# If you register a test, then ctest and make test will run it.
|
||||||
|
# You can also run examples and check the output, as well.
|
||||||
|
add_test(NAME testlibtest COMMAND testlib) # Command can be a target
|
11
tests/testlib.cpp
Normal file
11
tests/testlib.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include <modern/lib.hpp>
|
||||||
|
|
||||||
|
TEST_CASE( "Quick check", "[main]" ) {
|
||||||
|
std::vector<double> values {1, 2., 3.};
|
||||||
|
auto [mean, moment] = accumulate_vector(values);
|
||||||
|
|
||||||
|
REQUIRE( mean == 2.0 );
|
||||||
|
REQUIRE( moment == Approx(4.666666) );
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user