-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
148 lines (130 loc) · 5.32 KB
/
Makefile
File metadata and controls
148 lines (130 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# ===== Basic Configuration =====
PARALLEL_JOBS ?= $(shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)
CMAKE ?= cmake
BUILD_DIR ?= build
BUILD_DIR_ASAN ?= build-asan
BUILD_DIR_TSAN ?= build-tsan
BUILD_DIR_COV ?= build-coverage
COVERAGE_OUTPUT_DIR ?= coverage
# ===== User-Tunable Variables =====
CMAKE_C_COMPILER ?= clang
CMAKE_CXX_COMPILER ?= clang++
CLANG_FORMAT ?= clang-format
CLANG_TIDY ?= clang-tidy
CMAKE_CXX_STANDARD ?= 17 # Default to C++17, supports C++17, C++20, C++23, etc.
CMAKE_BUILD_TYPE ?= Debug
PLOTLY_CPP_BUILD_GALLERY ?= ON
PLOTLY_CPP_BUILD_TESTS ?= ON
# ===== CMake Options =====
CMAKE_COMMON_OPTIONS = \
-DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_CXX_STANDARD=$(CMAKE_CXX_STANDARD) \
-DCMAKE_C_COMPILER=$(CMAKE_C_COMPILER) \
-DCMAKE_CXX_COMPILER=$(CMAKE_CXX_COMPILER) \
-DPLOTLY_CPP_BUILD_GALLERY=$(PLOTLY_CPP_BUILD_GALLERY) \
-DPLOTLY_CPP_BUILD_TESTS=$(PLOTLY_CPP_BUILD_TESTS)
# ===== Helper Functions =====
define cmake_configure
@echo "Configuring: $(1)"
$(CMAKE) -S . -B $(1) $(CMAKE_COMMON_OPTIONS) $(2)
endef
define cmake_build
@echo "Building: $(1) $(if $(2),target=$(2),)"
$(CMAKE) --build $(1) --parallel $(PARALLEL_JOBS) $(if $(2),--target $(2),)
endef
define sanitizer_flags
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_FLAGS="-fsanitize=$(1) $(2) -g" \
-DCMAKE_CXX_FLAGS="-fsanitize=$(1) $(2) -g" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=$(1)" \
-DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=$(1)"
endef
# ===== Build Targets =====
.PHONY: release debug asan tsan coverage coverage-clang format tidy clean package doxygen
release:
$(call cmake_configure,$(BUILD_DIR), -DCMAKE_BUILD_TYPE=Release)
$(call cmake_build,$(BUILD_DIR))
debug:
$(call cmake_configure,$(BUILD_DIR))
$(call cmake_build,$(BUILD_DIR))
asan:
$(call cmake_configure,$(BUILD_DIR_ASAN), $(call sanitizer_flags,address,-fno-omit-frame-pointer))
$(call cmake_build,$(BUILD_DIR_ASAN))
tsan:
$(call cmake_configure,$(BUILD_DIR_TSAN), $(call sanitizer_flags,thread,))
$(call cmake_build,$(BUILD_DIR_TSAN))
coverage:
$(call cmake_configure,$(BUILD_DIR_COV), \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_COMPILER=g++ \
-DCMAKE_C_COMPILER=gcc \
-DCMAKE_C_FLAGS="--coverage -O0 -g" \
-DCMAKE_CXX_FLAGS="--coverage -O0 -g" \
-DCMAKE_EXE_LINKER_FLAGS="--coverage" \
-DCMAKE_SHARED_LINKER_FLAGS="--coverage")
$(call cmake_build,$(BUILD_DIR_COV))
@echo "Running tests for coverage..."
@cd $(BUILD_DIR_COV) && ctest --output-on-failure
@echo "Generating coverage report..."
@mkdir -p $(COVERAGE_OUTPUT_DIR)
@echo "Finding source files for coverage..."
@cd $(BUILD_DIR_COV) && find . -name "*.gcda" -exec gcov {} \; > /dev/null 2>&1 || true
@echo "Generating HTML coverage report with lcov..."
@if command -v lcov >/dev/null 2>&1 && command -v genhtml >/dev/null 2>&1; then \
cd $(BUILD_DIR_COV) && \
lcov --capture --directory . --output-file coverage.info && \
lcov --remove coverage.info '*/third_party/*' '*/test/*' '*/usr/*' --output-file coverage_filtered.info && \
genhtml coverage_filtered.info --output-directory ../$(COVERAGE_OUTPUT_DIR) && \
echo "Coverage report generated: $(COVERAGE_OUTPUT_DIR)/index.html"; \
else \
echo "lcov and genhtml are required for HTML coverage reports. Install with:"; \
echo " Ubuntu/Debian: sudo apt install lcov"; \
echo " RHEL/CentOS: sudo yum install lcov"; \
echo " macOS: brew install lcov"; \
echo ""; \
echo "Basic coverage data generated in $(BUILD_DIR_COV)/*.gcov files"; \
fi
format:
@echo "Formatting source files..."
@if ! command -v $(CLANG_FORMAT) >/dev/null 2>&1; then \
echo "Error: $(CLANG_FORMAT) not found. Please install clang-format."; \
exit 1; \
fi
@# Note: See .clang-format-ignore for excluded directories
@for d in src include gallery test; do \
[ -d $$d ] && find $$d -type f \( -name "*.cpp" -o -name "*.hpp" \) \
! -path "*/third_party/*" -exec $(CLANG_FORMAT) -i {} +; \
done
@echo "Formatting completed."
tidy:
$(call cmake_configure,$(BUILD_DIR))
@echo "Running clang-tidy..."
@if ! command -v run-$(CLANG_TIDY) >/dev/null 2>&1; then \
echo "Error: run-$(CLANG_TIDY) not found. Please install run-clang-tidy."; \
exit 1; \
fi
@run-$(CLANG_TIDY) -fix -format -p=$(BUILD_DIR) \
-source-filter="^(?!.*/build/|.*/third_party/).*" \
-j $(PARALLEL_JOBS) || echo "clang-tidy completed with warnings."
package:
@echo "Building Debian package..."
$(call cmake_configure,$(BUILD_DIR), -DCMAKE_BUILD_TYPE=Release)
$(call cmake_build,$(BUILD_DIR))
@echo "Creating Debian package with CPack..."
@cd $(BUILD_DIR) && cpack -G DEB
@echo "Package created successfully!"
@echo "Package files:"
@find $(BUILD_DIR) -name "*.deb" -type f -exec ls -la {} \;
doxygen:
@echo "Generating Doxygen documentation..."
@if ! command -v doxygen >/dev/null 2>&1; then \
echo "Error: doxygen not found. Please install doxygen."; \
echo " Ubuntu/Debian: sudo apt install doxygen graphviz"; \
exit 1; \
fi
@command doxygen Doxyfile
@echo "Documentation generated successfully in doxygen/html/"
@echo "Open doxygen/html/index.html in your browser to view the documentation"
clean:
@rm -rf $(BUILD_DIR) $(BUILD_DIR_ASAN) $(BUILD_DIR_TSAN) $(BUILD_DIR_COV) $(COVERAGE_OUTPUT_DIR) doxygen