aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorEgor Tensin <egor@tensin.name>2024-04-25 04:28:29 +0200
committerEgor Tensin <egor@tensin.name>2024-04-25 04:38:25 +0200
commit333ccc7385db0eb6151c1a163e5ea2ac2702012e (patch)
tree4b7a3fd16ee16eba9aa720bfbc10bbef09cff325
parentworkflows/ci: upgrade actions (diff)
downloadcimple-333ccc7385db0eb6151c1a163e5ea2ac2702012e.tar.gz
cimple-333ccc7385db0eb6151c1a163e5ea2ac2702012e.zip
Makefile: separate shortcuts for debug & release builds
-rw-r--r--.github/workflows/ci.yml28
-rw-r--r--DEVELOPMENT.md42
-rw-r--r--Dockerfile25
-rw-r--r--Makefile117
4 files changed, 103 insertions, 109 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 613124d..205a033 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -23,7 +23,7 @@ jobs:
strategy:
matrix:
compiler: [gcc, clang]
- configuration: [Debug, Release]
+ configuration: [debug, release]
runs-on: ubuntu-latest
name: 'Build: ${{ matrix.compiler }} / ${{ matrix.configuration }}'
env:
@@ -45,24 +45,24 @@ jobs:
sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends $DEPS valgrind
pip install -q -r ./test/requirements.txt
- name: Build
- run: make install
+ run: make '${{ matrix.configuration }}/install'
- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: 'cimple-${{ matrix.compiler }}-${{ matrix.configuration }}'
- path: './build/install/'
+ path: './build/${{ matrix.configuration }}/install/'
if-no-files-found: error
- name: Run tests
- run: make test/report
+ run: make '${{ matrix.configuration }}/report'
- name: Upload test report
uses: actions/upload-artifact@v4
with:
name: 'test-report-${{ matrix.compiler }}-${{ matrix.configuration }}'
- path: './build/test_report/'
+ path: './build/${{ matrix.configuration }}/test_report/'
if-no-files-found: error
if: always()
- name: Run Valgrind tests
- run: make test/valgrind
+ run: make '${{ matrix.configuration }}/valgrind'
coverage:
runs-on: ubuntu-latest
@@ -80,7 +80,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: coverage
- path: ./build/coverage/
+ path: ./build/coverage/html/
if-no-files-found: error
flame_graphs:
@@ -101,18 +101,18 @@ jobs:
run: |
echo -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
- name: Build
- run: make install
+ run: make debug/install
- name: Make flame graphs
run: |
# sudo is used to resolve kernel symbols. Plus, it would be required
# if we didn't fix perf_event_paranoid. PATH needs to be preserved
# for FlameGraph.
- sudo --preserve-env=PATH make flame_graphs
+ sudo --preserve-env=PATH make debug/flame_graphs
- name: Upload flame graphs
uses: actions/upload-artifact@v4
with:
name: flame_graphs
- path: ./build/flame_graphs/
+ path: ./build/debug/flame_graphs/
if-no-files-found: error
publish_reports:
@@ -122,15 +122,15 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- - name: Download test report - Clang/Debug
+ - name: Download test report - clang/debug
uses: actions/download-artifact@v4
with:
- name: test-report-clang-Debug
+ name: test-report-clang-debug
path: /tmp/reports/test_report_clang_debug/
- - name: Download test report - Clang/Release
+ - name: Download test report - clang/release
uses: actions/download-artifact@v4
with:
- name: test-report-clang-Release
+ name: test-report-clang-release
path: /tmp/reports/test_report_clang_release/
- name: Download coverage report
uses: actions/download-artifact@v4
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index f128c5b..59c5e9e 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -1,48 +1,54 @@
There's a Makefile with useful shortcuts to build the project in the "build/"
directory:
- make build
+ make debug # Debug build in build/debug/cmake
+ make release # Release build in build/release/cmake
-This command makes a CMake build directory in build/cmake/ and executes `make`
-there.
+This command makes a CMake build directory in build/{debug,release}/cmake/ and
+executes `make` there.
-The default is to build using clang in `Debug` configuration.
-You can choose a different compiler and configuration like so:
+The default is to build using Clang.
+You can choose a different compiler like so:
- make build COMPILER=gcc CONFIGURATION=Release
+ make {debug,release} COMPILER=gcc
### Testing
After building, you can run the "test suite" (depends on Pytest).
- make test
+ make debug/test
+ make release/test
To only run a subset of basic sanity tests:
- make test/sanity
+ make debug/sanity
+ make release/sanity
-To generate an HTML report in build/test_report/, run (requires pytest-html):
+To generate an HTML report in build/{debug,release}/test_report/, run (requires
+pytest-html):
- make test/report
+ make debug/report
+ make release/report
Reports for the latest successful Clang builds can be found below:
-* [Debug],
-* [Release].
+* [debug],
+* [release].
-[Debug]: https://egor-tensin.github.io/cimple/test_report_clang_debug/
-[Release]: https://egor-tensin.github.io/cimple/test_report_clang_release/
+[debug]: https://egor-tensin.github.io/cimple/test_report_clang_debug/
+[release]: https://egor-tensin.github.io/cimple/test_report_clang_release/
### Valgrind
You can run a suite of basic sanity tests under Valgrind:
- make test/valgrind
+ make debug/valgrind
+ make release/valgrind
### Code coverage
You can generate a code coverage report (depends on `gcovr`) in
-build/coverage/:
+build/coverage/html:
make coverage
@@ -54,11 +60,11 @@ https://egor-tensin.github.io/cimple/coverage/.
Some performance analysis can be done by looking at flame graphs.
Generate them after building the project (depends on `perf` & [FlameGraph]):
- make flame_graphs
+ make debug/flame_graphs
[FlameGraph]: https://github.com/brendangregg/FlameGraph
-This will generate two flame graphs in build/flame_graphs/; they stress
+This will generate two flame graphs in build/debug/flame_graphs/; they stress
slightly different parts of the system:
* [flame_graph_output_simple.svg] for a CI script with short output,
diff --git a/Dockerfile b/Dockerfile
index 60f1f31..1a472b5 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,31 +1,23 @@
FROM alpine:3.19 AS base
-ARG install_dir="/app/install"
-
FROM base AS builder
RUN build_deps='bash bsd-compat-headers build-base clang cmake coreutils git json-c-dev libgit2-dev libsodium-dev py3-pytest sqlite-dev valgrind' && \
apk add -q --no-cache $build_deps
ARG COMPILER=clang
-ARG CONFIGURATION=Release
ARG DEFAULT_HOST=127.0.0.1
ARG DEFAULT_PORT=5556
-ARG src_dir="/app/src"
-ARG install_dir
-
-COPY [".", "$src_dir"]
+COPY [".", "/app"]
-RUN cd -- "$src_dir" && \
- make install \
+RUN cd -- "/app" && \
+ make release/install \
"COMPILER=$COMPILER" \
- "CONFIGURATION=$CONFIGURATION" \
"DEFAULT_HOST=$DEFAULT_HOST" \
- "DEFAULT_PORT=$DEFAULT_PORT" \
- "INSTALL_PREFIX=$install_dir" && \
+ "DEFAULT_PORT=$DEFAULT_PORT" && \
ulimit -n 1024 && \
- make test/docker
+ make release/sanity
FROM base
@@ -34,11 +26,10 @@ LABEL maintainer="Egor Tensin <egor@tensin.name>"
RUN runtime_deps='json-c libgit2 libsodium sqlite tini' && \
apk add -q --no-cache $runtime_deps
-ARG install_dir
-COPY --from=builder ["$install_dir", "$install_dir"]
+COPY --from=builder ["/app/build/release/install", "/app"]
-ENV PATH="$install_dir/bin:${PATH}"
-WORKDIR "$install_dir/bin"
+ENV PATH="/app/bin:${PATH}"
+WORKDIR "/app/bin"
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["cimple-server"]
diff --git a/Makefile b/Makefile
index cb27efa..342b3ef 100644
--- a/Makefile
+++ b/Makefile
@@ -1,30 +1,25 @@
include prelude.mk
-src_dir := $(abspath .)
-build_dir := $(src_dir)/build
-cmake_dir := $(build_dir)/cmake
-install_dir := $(build_dir)/install
-
-test_report_dir := $(build_dir)/test_report
-coverage_dir := $(build_dir)/coverage
-flame_graphs_dir := $(build_dir)/flame_graphs
-
-COMPILER ?= clang
-CONFIGURATION ?= Debug
-DEFAULT_HOST ?= 127.0.0.1
-DEFAULT_PORT ?= 5556
-INSTALL_PREFIX ?= $(install_dir)
-COVERAGE ?=
+COMPILER ?= clang
+CONFIGURATION ?= debug
+DEFAULT_HOST ?= 127.0.0.1
+DEFAULT_PORT ?= 5556
+COVERAGE ?=
$(eval $(call noexpand,COMPILER))
$(eval $(call noexpand,CONFIGURATION))
$(eval $(call noexpand,DEFAULT_HOST))
$(eval $(call noexpand,DEFAULT_PORT))
-$(eval $(call noexpand,INSTALL_PREFIX))
$(eval $(call noexpand,COVERAGE))
+src_dir := $(abspath .)
+build_dir := $(src_dir)/build
+
.PHONY: all
-all: build
+all: debug
+
+.PHONY: DO
+DO:
.PHONY: clean
clean:
@@ -33,89 +28,91 @@ clean:
.PHONY: build
build:
@echo -----------------------------------------------------------------
- @echo Building
+ @echo 'Building: $(call escape,$(CONFIGURATION))'
@echo -----------------------------------------------------------------
- @mkdir -p -- '$(call escape,$(cmake_dir))'
+ @mkdir -p -- '$(call escape,$(build_dir)/cmake)'
cmake \
-G 'Unix Makefiles' \
-D 'CMAKE_C_COMPILER=$(call escape,$(COMPILER))' \
-D 'CMAKE_BUILD_TYPE=$(call escape,$(CONFIGURATION))' \
- -D 'CMAKE_INSTALL_PREFIX=$(call escape,$(INSTALL_PREFIX))' \
+ -D 'CMAKE_INSTALL_PREFIX=$(call escape,$(build_dir)/install)' \
-D 'DEFAULT_HOST=$(call escape,$(DEFAULT_HOST))' \
-D 'DEFAULT_PORT=$(call escape,$(DEFAULT_PORT))' \
- -D 'TEST_REPORT_DIR=$(call escape,$(test_report_dir))' \
+ -D 'TEST_REPORT_DIR=$(call escape,$(build_dir)/test_report)' \
-D 'COVERAGE=$(call escape,$(COVERAGE))' \
- -D 'FLAME_GRAPHS_DIR=$(call escape,$(flame_graphs_dir))' \
+ -D 'FLAME_GRAPHS_DIR=$(call escape,$(build_dir)/flame_graphs)' \
-S '$(call escape,$(src_dir))' \
- -B '$(call escape,$(cmake_dir))'
- cmake --build '$(call escape,$(cmake_dir))' -- -j
+ -B '$(call escape,$(build_dir)/cmake)'
+ cmake --build '$(call escape,$(build_dir)/cmake)' -- -j
+
+.PHONY: debug
+debug debug/%: CONFIGURATION := debug
+debug debug/%: build_dir := $(build_dir)/debug
+debug: build
.PHONY: release
-release: CONFIGURATION := Release
+release release/%: CONFIGURATION := release
+release release/%: build_dir := $(build_dir)/release
release: build
-.PHONY: install
-install: build
- cmake --install '$(call escape,$(cmake_dir))'
+# Coverage report depends on GCC debug data.
+.PHONY: coverage
+coverage coverage/%: CONFIGURATION := debug
+coverage coverage/%: COMPILER := gcc
+coverage coverage/%: COVERAGE := 1
+coverage coverage/%: build_dir := $(build_dir)/coverage
+coverage: build coverage/test
+ @echo -----------------------------------------------------------------
+ @echo Generating code coverage report
+ @echo -----------------------------------------------------------------
+ @mkdir -p -- '$(call escape,$(build_dir))/html'
+ gcovr --html-details '$(call escape,$(build_dir))/html/index.html' --print-summary
+ifndef CI
+ xdg-open '$(call escape,$(build_dir))/html/index.html' &> /dev/null
+endif
+
+%/install: % DO
+ cmake --install '$(call escape,$(build_dir))/cmake'
-.PHONY: test
-test:
+%/test: DO
@echo -----------------------------------------------------------------
@echo Running tests
@echo -----------------------------------------------------------------
- ctest --test-dir '$(call escape,$(cmake_dir))' \
+ ctest --test-dir '$(call escape,$(build_dir))/cmake' \
--verbose --tests-regex python_tests_default
-.PHONY: test/report
-test/report:
+%/report: DO
@echo -----------------------------------------------------------------
@echo Generating test report
@echo -----------------------------------------------------------------
- ctest --test-dir '$(call escape,$(cmake_dir))' \
+ ctest --test-dir '$(call escape,$(build_dir))/cmake' \
--verbose --tests-regex python_tests_report
+ifndef CI
+ xdg-open '$(call escape,$(build_dir))/test_report/index.html' &> /dev/null
+endif
# A subset of tests, excluding long-running stress tests.
-.PHONY: test/sanity
-test/sanity:
+%/sanity: DO
@echo -----------------------------------------------------------------
@echo Running sanity tests
@echo -----------------------------------------------------------------
- ctest --test-dir '$(call escape,$(cmake_dir))' \
+ ctest --test-dir '$(call escape,$(build_dir))/cmake' \
--verbose --tests-regex python_tests_sanity
# Same, but run under Valgrind.
-.PHONY: test/valgrind
-test/valgrind:
+%/valgrind: DO
@echo -----------------------------------------------------------------
@echo Running sanity tests w/ Valgrind
@echo -----------------------------------------------------------------
- ctest --test-dir '$(call escape,$(cmake_dir))' \
+ ctest --test-dir '$(call escape,$(build_dir))/cmake' \
--verbose --tests-regex python_tests_valgrind
# When building a Docker image for a different platform, exclude stress tests:
# they simply take way too long.
-.PHONY: test/docker
-test/docker: test/sanity
-
-# Force a rebuild for a coverage report, since it depends on GCC debug data.
-.PHONY: coverage
-coverage: COMPILER := gcc
-coverage: CONFIGURATION := Debug
-coverage: COVERAGE := 1
-coverage: clean build test
- @echo -----------------------------------------------------------------
- @echo Generating code coverage report
- @echo -----------------------------------------------------------------
- @mkdir -p -- '$(call escape,$(coverage_dir))'
- gcovr --html-details '$(call escape,$(coverage_dir))/index.html' --print-summary
-ifndef CI
- xdg-open '$(call escape,$(coverage_dir))/index.html' &> /dev/null
-endif
-.PHONY: flame_graphs
-flame_graphs:
+%/flame_graphs: DO
@echo -----------------------------------------------------------------
@echo Generating flame graphs
@echo -----------------------------------------------------------------
- ctest --test-dir '$(call escape,$(cmake_dir))' \
+ ctest --test-dir '$(call escape,$(build_dir))/cmake' \
--verbose --tests-regex python_tests_flame_graphs