-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
174 lines (150 loc) · 8.38 KB
/
Makefile
File metadata and controls
174 lines (150 loc) · 8.38 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
CXX ?= g++
CC = gcc
CXXFLAGS ?= -Wall
CFLAGS ?= -Wall -Wextra -pedantic
# Always add optimization - O3 for maximum performance
CXXFLAGS += -O3 -std=c++17 -pthread -Iinclude
CFLAGS += -O3 -Iinclude
LDFLAGS += -pthread -lz
CPPFLAGS ?=
PREFIX = /usr
BINDIR = $(PREFIX)/bin
# Detect OS for ncurses/pdcurses
# Check for MSYSTEM (set in MSYS2 environment) or Windows_NT
UNAME_S := $(shell uname -s 2>/dev/null || echo Windows)
MSYSTEM_VAL := $(shell echo $$MSYSTEM)
ifneq (,$(findstring MINGW,$(MSYSTEM_VAL)))
# MSYS2 MinGW environment - PDCurses headers are in pdcurses subdirectory
# PDC_WIDE and PDC_FORCE_UTF8 must match how the library was built
CFLAGS += -I/mingw64/include/pdcurses -DPDC_WIDE -DPDC_FORCE_UTF8
LDFLAGS_NCURSES = -L/mingw64/lib -lpdcurses
TARGET_MON_EXT = .exe
TARGET_EXT = .exe
else ifneq (,$(findstring MINGW,$(UNAME_S)))
# MSYS2 MinGW detected via uname
CFLAGS += -I/mingw64/include/pdcurses -DPDC_WIDE -DPDC_FORCE_UTF8
LDFLAGS_NCURSES = -L/mingw64/lib -lpdcurses
TARGET_MON_EXT = .exe
TARGET_EXT = .exe
else ifeq ($(OS),Windows_NT)
# Windows native
CFLAGS += -I/mingw64/include/pdcurses -DPDC_WIDE -DPDC_FORCE_UTF8
LDFLAGS_NCURSES = -L/mingw64/lib -lpdcurses
TARGET_MON_EXT = .exe
TARGET_EXT = .exe
else ifeq ($(UNAME_S),Darwin)
# macOS
LDFLAGS_NCURSES = -lncurses
TARGET_MON_EXT =
TARGET_EXT =
else
# Linux and other POSIX
LDFLAGS_NCURSES = -lncurses
TARGET_MON_EXT =
TARGET_EXT =
endif
# Extract version: try dpkg-parsechangelog, then git tag, else "unknown"
# Note: debian/changelog parsing removed due to shell escaping issues in Make
VERSION := $(shell dpkg-parsechangelog -S Version 2>/dev/null || git describe --tags --abbrev=0 2>/dev/null || echo unknown)
CPPFLAGS += -DVERSION='"$(VERSION)"'
# Coverage flags (set COVERAGE=1 to enable)
ifdef COVERAGE
CXXFLAGS += --coverage
CFLAGS += --coverage
LDFLAGS += --coverage
endif
# Source files for sensor-data (C++)
SOURCES = src/sensor-data.cpp
LIB_SOURCES = src/csv_parser.cpp src/json_parser.cpp src/error_detector.cpp src/file_utils.cpp src/sensor_data_transformer.cpp src/data_counter.cpp src/error_lister.cpp src/error_summarizer.cpp src/stats_analyser.cpp src/latest_finder.cpp src/sensor_data_api.cpp src/rdata_writer.cpp src/distinct_lister.cpp
TEST_SOURCES = tests/test_csv_parser.cpp tests/test_json_parser.cpp tests/test_error_detector.cpp tests/test_file_utils.cpp tests/test_date_utils.cpp tests/test_common_arg_parser.cpp tests/test_data_reader.cpp tests/test_file_collector.cpp tests/test_command_base.cpp tests/test_stats_analyser.cpp tests/test_rdata_writer.cpp
# Source files for sensor-mon (C)
MON_SOURCES = src/sensor-mon.c src/graph.c
# Source files for sensor-plot (C)
PLOT_SOURCES = src/sensor-plot.c src/graph.c
# Object files
LIB_OBJECTS = $(LIB_SOURCES:.cpp=.o)
MON_OBJECTS = $(MON_SOURCES:.c=.o)
PLOT_OBJECTS = src/sensor-plot.o src/graph.o src/sensor_plot_args.o
TEST_EXECUTABLES = test_csv_parser test_json_parser test_error_detector test_file_utils test_date_utils test_common_arg_parser test_data_reader test_file_collector test_command_base test_stats_analyser test_graph test_sensor_plot_args test_rdata_writer
TARGET = sensor-data
TARGET_MON = sensor-mon
TARGET_PLOT = sensor-plot
all: $(TARGET) $(TARGET_MON) $(TARGET_PLOT)
# Build library objects
%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
# Build C objects for sensor-mon
src/%.o: src/%.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
# Build main application (sensor-data)
$(TARGET): $(LIB_OBJECTS) $(SOURCES)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $(TARGET) $(SOURCES) $(LIB_OBJECTS) $(LDFLAGS)
# Build sensor-mon (links with C++ API objects, so uses C++ linker)
API_OBJECTS = src/sensor_data_api.o src/csv_parser.o src/json_parser.o src/file_utils.o src/error_detector.o
$(TARGET_MON): $(MON_OBJECTS) $(API_OBJECTS)
$(CXX) $(CFLAGS) -o $(TARGET_MON) $(MON_OBJECTS) $(API_OBJECTS) $(LDFLAGS) $(LDFLAGS_NCURSES)
# Build sensor-plot (links with C++ API objects, so uses C++ linker)
$(TARGET_PLOT): $(PLOT_OBJECTS) $(API_OBJECTS)
$(CXX) $(CFLAGS) -o $(TARGET_PLOT) $(PLOT_OBJECTS) $(API_OBJECTS) $(LDFLAGS) $(LDFLAGS_NCURSES)
# Build and run tests
test: $(LIB_OBJECTS)
@echo "Building and running unit tests..."
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_csv_parser.cpp src/csv_parser.o -o test_csv_parser $(LDFLAGS) && ./test_csv_parser
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_json_parser.cpp src/json_parser.o -o test_json_parser $(LDFLAGS) && ./test_json_parser
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_error_detector.cpp src/error_detector.o -o test_error_detector $(LDFLAGS) && ./test_error_detector
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_file_utils.cpp src/file_utils.o -o test_file_utils $(LDFLAGS) && ./test_file_utils
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_date_utils.cpp -o test_date_utils $(LDFLAGS) && ./test_date_utils
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_common_arg_parser.cpp src/file_utils.o -o test_common_arg_parser $(LDFLAGS) && ./test_common_arg_parser
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_data_reader.cpp src/csv_parser.o src/json_parser.o src/file_utils.o src/error_detector.o -o test_data_reader $(LDFLAGS) && ./test_data_reader
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_file_collector.cpp src/file_utils.o -o test_file_collector $(LDFLAGS) && ./test_file_collector
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_command_base.cpp src/csv_parser.o src/json_parser.o src/file_utils.o src/error_detector.o -o test_command_base $(LDFLAGS) && ./test_command_base
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_stats_analyser.cpp -o test_stats_analyser $(LDFLAGS) && ./test_stats_analyser
@$(CC) $(CPPFLAGS) $(CFLAGS) -c src/graph.c -o src/graph.o
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_graph.cpp src/graph.o -o test_graph $(LDFLAGS) $(LDFLAGS_NCURSES) && ./test_graph
@$(CC) $(CPPFLAGS) $(CFLAGS) -c src/sensor_plot_args.c -o src/sensor_plot_args.o
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_sensor_plot_args.cpp src/sensor_plot_args.o -o test_sensor_plot_args $(LDFLAGS) && ./test_sensor_plot_args
@$(CXX) $(CPPFLAGS) $(CXXFLAGS) tests/test_rdata_writer.cpp src/rdata_writer.o -o test_rdata_writer $(LDFLAGS) && ./test_rdata_writer
@echo "All unit tests passed!"
# Run integration tests (requires bash)
test-integration: $(TARGET)
@echo "Running integration tests..."
@bash tests/test_transform.sh
@bash tests/test_count.sh
@bash tests/test_stdin_stdout.sh
@bash tests/test_list_errors_stdin.sh
@bash tests/test_summarise_errors.sh
@bash tests/test_stats.sh
@bash tests/test_csv_input.sh
@bash tests/test_error_handling.sh
@bash tests/test_latest.sh
@echo "All integration tests passed!"
# Run all tests
test-all: test test-integration
install: $(TARGET) $(TARGET_MON) $(TARGET_PLOT)
install -d $(DESTDIR)$(BINDIR)
install -m 755 $(TARGET) $(DESTDIR)$(BINDIR)/
install -m 755 $(TARGET_MON) $(DESTDIR)$(BINDIR)/
install -m 755 $(TARGET_PLOT) $(DESTDIR)$(BINDIR)/
install -d $(DESTDIR)/etc/ws/sensor-errors
install -m 644 etc/ws/sensor-errors/*.errors $(DESTDIR)/etc/ws/sensor-errors/
install -d $(DESTDIR)/usr/share/bash-completion/completions
install -m 644 completions/sensor-data.bash $(DESTDIR)/usr/share/bash-completion/completions/sensor-data
clean:
rm -f $(TARGET) $(TARGET_MON) $(TARGET_PLOT) $(LIB_OBJECTS) $(MON_OBJECTS) $(PLOT_OBJECTS) $(TEST_EXECUTABLES) src/*.o *.gcda *.gcno src/*.gcda src/*.gcno
# Force a clean rebuild
rebuild: clean all
# Release build with maximum optimizations
release: clean
$(CXX) $(CPPFLAGS) -std=c++17 -pthread -Iinclude -O3 -march=native -flto -DNDEBUG -o $(TARGET) $(SOURCES) $(LIB_SOURCES) -pthread
$(CXX) $(CPPFLAGS) -std=c++17 -Iinclude -O3 -march=native -flto -DNDEBUG -o $(TARGET_MON) $(MON_SOURCES) src/sensor_data_api.cpp src/csv_parser.cpp src/json_parser.cpp src/file_utils.cpp src/error_detector.cpp $(LDFLAGS_NCURSES)
$(CXX) $(CPPFLAGS) -std=c++17 -Iinclude -O3 -march=native -flto -DNDEBUG -o $(TARGET_PLOT) $(PLOT_SOURCES) src/sensor_data_api.cpp src/csv_parser.cpp src/json_parser.cpp src/file_utils.cpp src/error_detector.cpp $(LDFLAGS_NCURSES)
# Generate coverage report (requires gcov)
coverage:
@echo "=== Coverage files ==="
@ls -la *.gcno *.gcda 2>/dev/null || true
@ls -la src/*.gcno src/*.gcda 2>/dev/null || true
@echo "=== Running gcov ==="
gcov src/*.cpp tests/*.cpp 2>/dev/null || true
@echo "=== Generated .gcov files ==="
@ls -la *.gcov 2>/dev/null || true
.PHONY: all install clean rebuild test test-integration test-all coverage release