Skip to content

Commit 4c964c2

Browse files
authored
Add CMake build support (#73)
Support building with CMake, both with and without tests. Add new build type to CI. Update the README with instructions on how to build with cmake and depend on the project.
1 parent 2dfe1b8 commit 4c964c2

File tree

6 files changed

+141
-13
lines changed

6 files changed

+141
-13
lines changed

.github/workflows/main.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ jobs:
4040
sudo apt-get install -y clang-16 libc++-16-dev libc++abi-16-dev
4141
echo "/usr/lib/llvm-16/bin" >> $GITHUB_PATH
4242
43+
- name: Install cmake
44+
run: |
45+
sudo apt-get install -y cmake ninja-build
46+
echo "/usr/bin/cmake" >> $GITHUB_PATH
47+
4348
# Enable tmate debugging of manually-triggered workflows if the input option was provided
4449
- name: Setup tmate session
4550
uses: mxschmitt/action-tmate@v3
@@ -62,3 +67,16 @@ jobs:
6267
- name: Test (C++20)
6368
run: |
6469
"${GITHUB_WORKSPACE}/bin/bazel" test --config=clang --config=cpp20 //...
70+
71+
- name: Build (CMake)
72+
run: |
73+
cmake -S . -B build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
74+
cmake --build build
75+
ctest --test-dir build --output-on-failure
76+
77+
- name: Build w/ Tests (CMake)
78+
run: |
79+
rm -rf build
80+
cmake -S . -B build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DPIXELMATCH_BUILD_TESTS=ON
81+
cmake --build build
82+
ctest --test-dir build --output-on-failure

.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,29 @@ coverage-report
1717
# The Bzlmod lockfile is platform-dependent with Python and thus hard
1818
# to keep up-to-date in CI. It still speeds up local development.
1919
MODULE.bazel.lock
20+
21+
# CMake
22+
# Created by https://www.toptal.com/developers/gitignore/api/cmake
23+
# Edit at https://www.toptal.com/developers/gitignore?templates=cmake
24+
25+
### CMake ###
26+
/build/
27+
CMakeLists.txt.user
28+
CMakeCache.txt
29+
CMakeFiles
30+
CMakeScripts
31+
Testing
32+
Makefile
33+
cmake_install.cmake
34+
install_manifest.txt
35+
compile_commands.json
36+
CTestTestfile.cmake
37+
_deps
38+
39+
### CMake Patch ###
40+
CMakeUserPresets.json
41+
42+
# External projects
43+
*-prefix/
44+
45+
# End of https://www.toptal.com/developers/gitignore/api/cmake

CMakeLists.txt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
project(pixelmatch-cpp17 LANGUAGES CXX)
3+
4+
set(CMAKE_CXX_STANDARD 20)
5+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6+
7+
option(PIXELMATCH_BUILD_TESTS "Enable building tests" OFF)
8+
9+
# stb libraries for tests and image_utils. Not used in pixelmatch-cpp17 itself.
10+
add_library(pixelmatch_third_party_stb_image STATIC third_party/stb/stb_image.cpp)
11+
target_include_directories(pixelmatch_third_party_stb_image PUBLIC third_party)
12+
target_compile_options(pixelmatch_third_party_stb_image PRIVATE -Wno-unused-function -Wno-self-assign)
13+
14+
add_library(pixelmatch_third_party_stb_image_write STATIC third_party/stb/stb_image_write.cpp)
15+
target_include_directories(pixelmatch_third_party_stb_image_write PUBLIC third_party)
16+
target_compile_options(pixelmatch_third_party_stb_image_write PRIVATE -Wno-unused-function -Wno-self-assign)
17+
18+
# Main library
19+
add_library(pixelmatch-cpp17 src/pixelmatch/pixelmatch.cc)
20+
target_include_directories(pixelmatch-cpp17 PUBLIC src)
21+
22+
# image_utils helper library (uses stb to load and save images)
23+
add_library(image_utils src/pixelmatch/image_utils.cc)
24+
target_include_directories(image_utils PUBLIC src)
25+
target_link_libraries(image_utils PUBLIC pixelmatch-cpp17 pixelmatch_third_party_stb_image pixelmatch_third_party_stb_image_write)
26+
27+
if(PIXELMATCH_BUILD_TESTS)
28+
include(FetchContent)
29+
FetchContent_Declare(
30+
googletest
31+
URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
32+
)
33+
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
34+
FetchContent_MakeAvailable(googletest)
35+
36+
enable_testing()
37+
add_library(test_base INTERFACE)
38+
target_link_libraries(test_base INTERFACE GTest::gtest_main GTest::gmock_main m)
39+
40+
add_executable(pixelmatch_tests tests/pixelmatch_tests.cc)
41+
target_link_libraries(pixelmatch_tests PRIVATE test_base pixelmatch-cpp17 image_utils)
42+
add_test(NAME pixelmatch_tests COMMAND pixelmatch_tests)
43+
set_tests_properties(pixelmatch_tests PROPERTIES WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
44+
45+
add_executable(image_utils_tests tests/image_utils_tests.cc)
46+
target_link_libraries(image_utils_tests PRIVATE test_base image_utils)
47+
add_test(NAME image_utils_tests COMMAND image_utils_tests)
48+
set_tests_properties(image_utils_tests PROPERTIES WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
49+
50+
endif() # PIXELMATCH_BUILD_TESTS

README.md

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,58 @@ git_override(
7373
)
7474
```
7575

76-
#### Adding the dependency
76+
### CMake
7777

78-
Then add a dependency on `@pixelmatch-cpp17`:
79-
```py
80-
cc_test(
81-
name = "my_test",
82-
# ...
83-
data = glob([
84-
"testdata/*.png",
85-
]),
86-
deps = [
87-
"@pixelmatch-cpp17",
88-
# ...
89-
],
78+
To take a dependency on `pixelmatch-cpp17` with `FetchContent`, add the following
79+
to your project's `CMakeLists.txt`:
80+
81+
```cmake
82+
include(FetchContent)
83+
FetchContent_Declare(
84+
pixelmatch-cpp17
85+
GIT_REPOSITORY https://github.com/jwmcglynn/pixelmatch-cpp17.git
86+
GIT_TAG <commit or tag>
9087
)
88+
FetchContent_MakeAvailable(pixelmatch-cpp17)
89+
90+
target_link_libraries(your_target PRIVATE pixelmatch-cpp17)
9191
```
9292

93+
#### Running the tests
94+
95+
96+
This repository also provides CMake build files. A typical workflow is:
97+
98+
```sh
99+
cmake -S . -B build -DPIXELMATCH_BUILD_TESTS=ON
100+
cmake --build build
101+
ctest --test-dir build
102+
```
103+
104+
### Calling from C++
105+
93106
In your test file, include pixelmatch with:
94107
```cpp
95108
#include <pixelmatch/pixelmatch.h>
96109
```
97110

111+
Then, you can use the `pixelmatch::pixelmatch` function.
112+
113+
```cpp
114+
// Pass an options struct to configure the comparison. If not specified, defaults will be used.
115+
pixelmatch::Options options;
116+
options.threshold = 0.1f;
117+
118+
// Load two images as RGBA-encoded byte arrays. The images must have the same dimensions and stride.
119+
const std::vector<uint8_t> img1 = ...;
120+
const std::vector<uint8_t> img2 = ...;
121+
// Output image will be saved in this buffer.
122+
std::vector<uint8_t> diffImage(img1.size());
123+
124+
// Pass the image buffers and call with the width, height, and stride of the images.
125+
const int numDiffPixels = pixelmatch::pixelmatch(img1, img2, diffImage, width, height, stride, options);
126+
```
127+
98128
## Projects using pixelmatch-cpp17
99129
100130
- Python bindings: https://github.com/cubao/pybind11_pixelmatch

third_party/stb/stb_image.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define STB_IMAGE_IMPLEMENTATION
2+
#include "stb_image.h"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define STB_IMAGE_WRITE_IMPLEMENTATION
2+
#include "stb_image_write.h"

0 commit comments

Comments
 (0)