Skip to content

Commit 1018429

Browse files
authored
👋🏽 Add example on how to import and use cib in a project. (#39)
* clarifications to the build in the README * create hello_world example by extracting it from the README
1 parent ea1d603 commit 1018429

File tree

15 files changed

+385
-121
lines changed

15 files changed

+385
-121
lines changed

.github/workflows/unit_tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,4 @@ jobs:
155155
with:
156156
name: cib.hpp
157157
path: ${{github.workspace}}/build/include/cib/cib.hpp
158+

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/Testing/
44
/cmake-build*
55
/venv/
6+
/examples/hello_world/build/

CMakeLists.txt

Lines changed: 70 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,79 @@
11
cmake_minimum_required(VERSION 3.16)
2-
project(compile_time_init_build)
32

4-
5-
if (DEFINED ENV{CXX_STANDARD} AND NOT $ENV{CXX_STANDARD} EQUAL "")
6-
set(CMAKE_CXX_STANDARD $ENV{CXX_STANDARD})
3+
if(NOT DEFINED PROJECT_NAME)
4+
set(NOT_SUBPROJECT ON)
75
else()
8-
set(CMAKE_CXX_STANDARD 17)
6+
set(NOT_SUBPROJECT OFF)
97
endif()
10-
message("CMAKE_CXX_STANDARD = ${CMAKE_CXX_STANDARD}")
11-
12-
enable_testing()
13-
14-
add_subdirectory(lib/Catch2)
15-
add_subdirectory(test)
16-
add_subdirectory(benchmark)
17-
18-
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/include/cib/)
19-
20-
add_custom_command(
21-
DEPENDS
22-
${CMAKE_SOURCE_DIR}/tools/gen_release_header.py
23-
${CMAKE_SOURCE_DIR}/include/cib/*
24-
${CMAKE_SOURCE_DIR}/include/cib/detail/*
25-
COMMAND
26-
python3 ${CMAKE_SOURCE_DIR}/tools/gen_release_header.py ${CMAKE_SOURCE_DIR}/include/cib/cib.hpp > ${CMAKE_BINARY_DIR}/include/cib/cib.hpp
27-
OUTPUT
28-
${CMAKE_BINARY_DIR}/include/cib/cib.hpp
29-
)
30-
31-
add_custom_target(release_header
32-
DEPENDS
33-
${CMAKE_BINARY_DIR}/include/cib/cib.hpp)
34-
358

36-
37-
add_library(Cib INTERFACE)
9+
project(
10+
cib
11+
VERSION 0.1.0
12+
LANGUAGES CXX
13+
DESCRIPTION "A header-only C++ library for composing modular firmware at compile-time."
14+
HOMEPAGE_URL "https://github.com/intel/compile-time-init-build")
15+
16+
add_library(cib INTERFACE)
17+
target_compile_features(cib INTERFACE cxx_std_17)
18+
19+
20+
21+
if(NOT_SUBPROJECT)
22+
if (DEFINED ENV{CXX_STANDARD} AND NOT $ENV{CXX_STANDARD} EQUAL "")
23+
set(CMAKE_CXX_STANDARD $ENV{CXX_STANDARD})
24+
else()
25+
set(CMAKE_CXX_STANDARD 17)
26+
endif()
27+
28+
find_package(Git QUIET)
29+
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
30+
message("Updating git submodules...")
31+
execute_process(
32+
COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
33+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
34+
RESULT_VARIABLE GIT_RETVAL)
35+
if(NOT GIT_RETVAL EQUAL "0")
36+
message(FATAL_ERROR "git submodule update failed!")
37+
endif()
38+
endif()
39+
40+
# Enable functional and performance test suites.
41+
enable_testing()
42+
add_subdirectory(lib/Catch2)
43+
add_subdirectory(test)
44+
add_subdirectory(benchmark)
45+
46+
# Build single-header release.
47+
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/cib/)
48+
49+
find_package(PythonInterp 3 REQUIRED)
50+
51+
add_custom_command(
52+
DEPENDS
53+
${CMAKE_CURRENT_SOURCE_DIR}/tools/gen_release_header.py
54+
${CMAKE_CURRENT_SOURCE_DIR}/include/cib/*
55+
${CMAKE_CURRENT_SOURCE_DIR}/include/cib/detail/*
56+
COMMAND
57+
python3 ${CMAKE_CURRENT_SOURCE_DIR}/tools/gen_release_header.py ${CMAKE_CURRENT_SOURCE_DIR}/include/cib/cib.hpp > ${CMAKE_CURRENT_BINARY_DIR}/include/cib/cib.hpp
58+
OUTPUT
59+
${CMAKE_CURRENT_BINARY_DIR}/include/cib/cib.hpp
60+
)
61+
62+
add_custom_target(release_header
63+
DEPENDS
64+
${CMAKE_CURRENT_BINARY_DIR}/include/cib/cib.hpp)
65+
endif()
3866

3967
if ($ENV{SINGLE_HEADER})
40-
message("Using single-header version of cib.hpp.")
41-
42-
add_dependencies(Cib release_header)
43-
44-
target_include_directories(Cib
45-
INTERFACE
46-
${CMAKE_BINARY_DIR}/include/)
68+
add_dependencies(cib release_header)
4769

70+
target_include_directories(cib INTERFACE
71+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/>
72+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/>
73+
)
4874
else()
49-
message("Using multi-header version of cib.hpp.")
50-
51-
target_include_directories(Cib
52-
INTERFACE
53-
${CMAKE_CURRENT_SOURCE_DIR}/include)
54-
55-
target_sources(Cib
56-
INTERFACE
57-
${CMAKE_CURRENT_SOURCE_DIR}/include/cib/cib.hpp)
58-
endif()
75+
target_include_directories(cib INTERFACE
76+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
77+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/>
78+
)
79+
endif()

README.md

Lines changed: 24 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ in your repo and add the cib directory in your CMakeLists.txt file:
3030

3131
```cmake
3232
add_subdirectory(lib/compile-time-init-build)
33-
target_link_libraries(your_target PRIVATE Cib)
33+
target_link_libraries(your_target PRIVATE cib)
3434
```
3535

3636
With either of these methods, include the cib.hpp header in your code to use it.
@@ -40,101 +40,51 @@ With either of these methods, include the cib.hpp header in your code to use it.
4040
Since *cib* is a library for efficiently building firmware through composition
4141
a simple example takes a few more lines than a typical "Hello, world!"
4242

43-
#### core.hpp
44-
The `core` component of this example **exports** the `say_message` **service**. Pay close
45-
attention to the `#include` directives in each file.
4643
```c++
4744
#include <cib/cib.hpp>
45+
#include <iostream>
4846

4947
struct say_message : public cib::callback_meta<>{};
5048

49+
// the 'core' component exposes the 'say_message' service for others to extend
5150
struct core {
52-
constexpr static auto config =
53-
cib::config(cib::exports<say_message>);
51+
constexpr static auto config = cib::exports<say_message>;
5452
};
55-
```
56-
#### hello_world.hpp
57-
The `hello_world` component **extends** the `say_message` **service** with new
58-
contained in a lambda.
59-
```c++
60-
#include <iostream>
61-
#include <cib/cib.hpp>
6253

63-
struct hello_world {
54+
// the 'say_hello_world' component extends 'say_message' with its own functionality
55+
struct say_hello_world {
6456
constexpr static auto config =
65-
cib::config(
66-
cib::extend<say_message>([](){
67-
std::cout << "Hello, world!" << std::endl;
68-
})
69-
);
57+
cib::extend<say_message>([](){
58+
std::cout << "Hello, world!" << std::endl;
59+
});
7060
};
71-
```
72-
#### lazy_dog.hpp
73-
Another component, `lazy_dog` is also extending the `say_message` **service**.
74-
This time it is using a function pointer instead of a lambda. The function
75-
definition of `talk_about_the_dog` could also be placed in a `lazy_dog.cpp`
76-
file if desired.
77-
```c++
78-
#include <iostream>
79-
#include <cib/cib.hpp>
8061

81-
struct lazy_dog {
82-
static void talk_about_the_dog() {
83-
std::cout << "The quick brown fox jumps over the lazy dog." << std::endl;
84-
}
85-
86-
constexpr static auto config =
87-
cib::config(
88-
cib::extend<say_message>(talk_about_the_dog)
89-
);
90-
};
91-
```
92-
#### my_project.hpp
93-
All the components are brought together in the project configuration, `my_project`.
94-
```c++
95-
#include "core.hpp"
96-
#include "hello_world.hpp"
97-
#include "lazy_dog.hpp"
98-
99-
struct my_project {
62+
// the 'hello_world' project composes 'core' and 'say_hello_world'
63+
struct hello_world {
10064
constexpr static auto config =
101-
cib::components<core, hello_world, lazy_dog>;
65+
cib::components<core, say_hello_world>;
10266
};
103-
```
104-
#### main.cpp
105-
The `cib::nexus` brings all the **services** and **features** together. This is
106-
where the compile-time initialization and build process actually occurs.
107-
```c++
108-
#include "my_project.hpp"
10967

110-
cib::nexus<my_project> nexus{};
68+
// the nexus instantiates the project
69+
cib::nexus<hello_world> nexus{};
11170

11271
int main() {
113-
// services can be accessed directly from the nexus...
72+
// the fully extended and built services are ready to be used
11473
nexus.service<say_message>();
115-
116-
// ...or they can be accessed anywhere through cib::service
117-
nexus.init();
118-
cib::service<say_message>();
74+
return 0;
11975
}
12076
```
121-
#### Execution
122-
All of the initialization and registration occurs at compile-time, but the
123-
new functionality is still executed at run-time:
124-
```
125-
shell> ./my_project
126-
Hello, world!
127-
The quick brown fox jumps over the lazy dog.
128-
Hello, world!
129-
The quick brown fox jumps over the lazy dog.
130-
```
77+
78+
A larger and more illustrative example can be found in this repo at
79+
[examples/hello_world](examples/hello_world).
13180
13281
### Building
13382
13483
*cib* is built with CMake. The single header is built with the
13584
`release_header` target:
13685
13786
```shell
87+
git clone https://github.com/intel/compile-time-init-build.git
13888
cmake -B build
13989
cmake --build build -t release_header
14090
ls build/include/cib/ | grep cib.hpp
@@ -143,6 +93,10 @@ ls build/include/cib/ | grep cib.hpp
14393
This combines all the *cib* header files in the `include` tree by recursively
14494
including the `#include` directives and ignoring all other macros.
14595

96+
**NOTE:** *cib* uses git submodules to include its testing dependencies. The
97+
CMake configuration *should* fetch the submodules for you, but only if the
98+
repository was cloned as a git repo and not downloaded as an archive.
99+
146100
Unit tests are registered with CTest:
147101

148102
```shell

benchmark/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ target_compile_options(compilation_benchmark
2828
-ftemplate-backtrace-limit=0
2929
)
3030

31-
target_link_libraries(compilation_benchmark PRIVATE Cib)
31+
target_link_libraries(compilation_benchmark PRIVATE cib)

examples/hello_world/CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
project(hello_world LANGUAGES CXX)
4+
5+
set(CMAKE_CXX_STANDARD 17)
6+
7+
add_executable(hello_world main.cpp dont_panic.cpp)
8+
9+
include(FetchContent)
10+
FetchContent_Declare(
11+
cib
12+
GIT_REPOSITORY https://github.com/intel/compile-time-init-build.git
13+
14+
# update this to a more recent commit ID for your project
15+
GIT_TAG 8b35ed8f6fb358234a916768c81a924a373c80ff
16+
)
17+
FetchContent_MakeAvailable(cib)
18+
19+
target_link_libraries(hello_world cib)

0 commit comments

Comments
 (0)