Skip to content

Commit f566729

Browse files
authored
Merge pull request #24 from Vladush/feature/opencv-upgrade-static
feat: upgrade OpenCV to 4.12.0 static and cache builds
2 parents 43c97a5 + 14d0db0 commit f566729

38 files changed

+1930
-424
lines changed

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ build_*
66
.cache
77
compile_commands.json
88
.clang-format
9+
opencv_static
10+
cmake-build-*
11+
.idea
12+
.vscode

.github/workflows/ci.yml

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,27 @@ jobs:
6161
libjsoncpp-dev nlohmann-json3-dev v4l-utils \
6262
libgtest-dev devscripts debhelper dh-cmake
6363
64+
- name: Cache OpenCV Static
65+
id: cache-opencv
66+
uses: actions/cache@v4
67+
with:
68+
path: opencv_static
69+
key: ${{ runner.os }}-${{ runner.arch }}-opencv-4.12.0-static-rev1
70+
71+
- name: Build OpenCV Static
72+
if: steps.cache-opencv.outputs.cache-hit != 'true'
73+
run: |
74+
chmod +x scripts/build_opencv.sh
75+
./scripts/build_opencv.sh
76+
6477
- name: Download models
6578
run: ./scripts/download_models.sh
6679

80+
- name: Install models to system
81+
run: |
82+
sudo mkdir -p /usr/share/linuxcampam/models
83+
sudo cp models/*.onnx /usr/share/linuxcampam/models/
84+
6785
- name: Configure
6886
run: cmake -B build -DCMAKE_BUILD_TYPE=Release
6987

@@ -95,13 +113,44 @@ jobs:
95113
run: |
96114
sudo apt-get update
97115
sudo apt-get install -y \
98-
build-essential cmake clang libopencv-dev libpam0g-dev \
99-
libjsoncpp-dev nlohmann-json3-dev v4l-utils
116+
build-essential cmake libopencv-dev libpam0g-dev \
117+
libjsoncpp-dev nlohmann-json3-dev v4l-utils \
118+
libgtest-dev devscripts debhelper dh-cmake
119+
120+
- name: Cache OpenCV Static
121+
id: cache-opencv
122+
uses: actions/cache@v4
123+
with:
124+
path: opencv_static
125+
key: ${{ runner.os }}-${{ runner.arch }}-opencv-4.12.0-static-clang-rev1
126+
127+
- name: Build OpenCV Static
128+
if: steps.cache-opencv.outputs.cache-hit != 'true'
129+
env:
130+
CC: clang
131+
CXX: clang++
132+
run: |
133+
chmod +x scripts/build_opencv.sh
134+
./scripts/build_opencv.sh
135+
136+
- name: Download models
137+
run: ./scripts/download_models.sh
138+
139+
- name: Install models to system
140+
run: |
141+
sudo mkdir -p /usr/share/linuxcampam/models
142+
sudo cp models/*.onnx /usr/share/linuxcampam/models/
100143
101144
- name: Configure
102-
run: cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
145+
env:
146+
CC: clang
147+
CXX: clang++
148+
run: cmake -B build -DCMAKE_BUILD_TYPE=Release
103149

104150
- name: Build
151+
env:
152+
CC: clang
153+
CXX: clang++
105154
run: cmake --build build -j$(nproc)
106155

107156
- name: Test
@@ -121,9 +170,27 @@ jobs:
121170
libjsoncpp-dev nlohmann-json3-dev v4l-utils \
122171
libgtest-dev devscripts debhelper dh-cmake
123172
173+
- name: Cache OpenCV Static
174+
id: cache-opencv
175+
uses: actions/cache@v4
176+
with:
177+
path: opencv_static
178+
key: ${{ runner.os }}-${{ runner.arch }}-opencv-4.12.0-static-rev1
179+
180+
- name: Build OpenCV Static
181+
if: steps.cache-opencv.outputs.cache-hit != 'true'
182+
run: |
183+
chmod +x scripts/build_opencv.sh
184+
./scripts/build_opencv.sh
185+
124186
- name: Download models
125187
run: ./scripts/download_models.sh
126188

189+
- name: Install models to system
190+
run: |
191+
sudo mkdir -p /usr/share/linuxcampam/models
192+
sudo cp models/*.onnx /usr/share/linuxcampam/models/
193+
127194
- name: Configure
128195
run: cmake -B build -DCMAKE_BUILD_TYPE=Release
129196

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,12 @@ models/
6262
# Python
6363
__pycache__/
6464
*.pyc
65+
66+
# Logs
67+
*.log
68+
69+
# OpenCV (Local build artifacts)
70+
opencv_static/
71+
opencv_build/
72+
opencv-*/
73+
downloads/

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- **Faster First Login**: AI models are now pre-loaded when the service starts, rather than waiting for the first user to walk by.
1414
- **Hardened Validation**: Switched input validation from regex to a strict character-allowlist loop. This isn't visible to users, but it removes a potential ReDoS attack vector and makes path traversal protection bulletproof.
1515

16+
## [0.9.7] - 2026-01-25
17+
18+
### Improved in 0.9.7
19+
20+
- **Upgraded AI Model**: Switched to `YuNet 2023mar` for better face detection accuracy, especially with smaller faces and difficult angles.
21+
- **Dynamic Resolution**: Removed fixed resizing (320x320) for face detection. The engine now uses the camera's native resolution, which significantly improves detection performance on IR cameras with non-square aspect ratios.
22+
- **Static Linking**: Upgraded to **OpenCV 4.12.0** (statically linked), removing runtime dependencies and potential conflicts.
23+
- **Hardware Strategy**: Prioritized **OpenCL 1.2+** as the universal accelerator (AMD/Intel/NVIDIA) to keep the package lightweight (~15MB). Native CUDA/OpenVINO backends are disabled to avoid massive binary bloat (~200MB+), with OpenCL providing near-native performance.
24+
1625
## [0.9.6] - 2026-01-07
1726

1827
### Added in 0.9.6

CMakeLists.txt

Lines changed: 79 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
11
cmake_minimum_required(VERSION 3.14)
2-
project(LinuxCamPAM VERSION 0.9.6 LANGUAGES C CXX)
2+
project(LinuxCamPAM VERSION 0.9.7 LANGUAGES C CXX)
3+
4+
# --- Versioning with Git Hash ---
5+
find_package(Git)
6+
if(GIT_FOUND)
7+
execute_process(
8+
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
9+
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
10+
OUTPUT_VARIABLE GIT_HASH
11+
OUTPUT_STRIP_TRAILING_WHITESPACE
12+
)
13+
endif()
14+
15+
if(GIT_HASH)
16+
set(FULL_VERSION "${PROJECT_VERSION}+g${GIT_HASH}")
17+
else()
18+
string(TIMESTAMP BUILD_DATE "%Y%m%d")
19+
set(FULL_VERSION "${PROJECT_VERSION}+dev${BUILD_DATE}")
20+
endif()
321

4-
add_compile_definitions(LINUXCAMPAM_VERSION="${PROJECT_VERSION}")
22+
add_compile_definitions(LINUXCAMPAM_VERSION="${FULL_VERSION}")
523

624
set(CMAKE_CXX_STANDARD 17)
725
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -25,6 +43,9 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
2543
endif()
2644

2745
# --- Dependencies ---
46+
if(EXISTS "${CMAKE_SOURCE_DIR}/opencv_static/lib/cmake/opencv4")
47+
set(OpenCV_DIR "${CMAKE_SOURCE_DIR}/opencv_static/lib/cmake/opencv4")
48+
endif()
2849
find_package(OpenCV REQUIRED COMPONENTS core videoio imgproc dnn objdetect photo)
2950
find_package(Threads REQUIRED)
3051

@@ -48,34 +69,31 @@ configure_file(${CMAKE_SOURCE_DIR}/config/config.ini ${CMAKE_BINARY_DIR}/config.
4869

4970
# PAM Module
5071
add_library(pam_linuxcampam SHARED src/pam/pam_linuxcampam.cpp)
51-
target_include_directories(pam_linuxcampam PRIVATE include ${PAM_INCLUDE_DIR})
72+
target_include_directories(pam_linuxcampam PRIVATE include src/common ${PAM_INCLUDE_DIR})
5273
target_link_libraries(pam_linuxcampam PRIVATE ${PAM_LIBRARY})
5374
set_target_properties(pam_linuxcampam PROPERTIES PREFIX "") # pam_ modules often don't want strict lib prefix, though standard is usually ok. PAM expects filename to match config.
5475

55-
# Auth Service
56-
add_executable(linuxcampamd
57-
src/service/main.cpp
76+
# Service Core Library (Shared between Service and Tests)
77+
add_library(service_core STATIC
5878
src/service/auth_engine.cpp
59-
src/service/auth_engine.hpp
6079
src/service/camera.cpp
61-
src/service/camera.hpp
6280
src/service/config.cpp
63-
src/service/config.hpp
6481
src/service/utils.cpp
6582
)
66-
target_include_directories(linuxcampamd PRIVATE include ${OpenCV_INCLUDE_DIRS})
67-
target_link_libraries(linuxcampamd PRIVATE
83+
target_include_directories(service_core PUBLIC include src src/common ${OpenCV_INCLUDE_DIRS})
84+
target_link_libraries(service_core PUBLIC
6885
${OpenCV_LIBS}
6986
Threads::Threads
7087
stdc++fs
7188
)
7289

7390
if(nlohmann_json_FOUND)
74-
target_link_libraries(linuxcampamd PRIVATE nlohmann_json::nlohmann_json)
91+
target_link_libraries(service_core PUBLIC nlohmann_json::nlohmann_json)
7592
endif()
76-
# Always include local include dir for vendored headers
77-
target_include_directories(linuxcampamd PRIVATE include)
7893

94+
# Auth Service
95+
add_executable(linuxcampamd src/service/main.cpp)
96+
target_link_libraries(linuxcampamd PRIVATE service_core)
7997

8098
# CLI Tool
8199
add_executable(linuxcampam src/cli/main.cpp)
@@ -86,36 +104,57 @@ target_link_libraries(linuxcampam PRIVATE stdc++fs)
86104
add_executable(check_opencl src/tools/check_opencl.cpp)
87105
target_link_libraries(check_opencl PRIVATE ${OpenCV_LIBS})
88106

107+
# --- Testing ---
89108
# --- Testing ---
90109
enable_testing()
91-
find_package(GTest)
92110

93-
if(GTest_FOUND)
111+
include(FetchContent)
112+
# Handle DOWNLOAD_EXTRACT_TIMESTAMP for CMake 3.24+
113+
set(GTEST_DOWNLOAD_ARGS "")
114+
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
115+
set(GTEST_DOWNLOAD_ARGS DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
116+
endif()
117+
118+
FetchContent_Declare(
119+
googletest
120+
URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
121+
${GTEST_DOWNLOAD_ARGS}
122+
)
123+
124+
# Fix for CMP0135 warning in CMake 3.24+
125+
if(POLICY CMP0135)
126+
cmake_policy(SET CMP0135 NEW)
127+
# CMake 3.24+ requires explicit timestamp handling for consistency
128+
set(FETCHCONTENT_UPDATES_DISCONNECTED_GOOGLETEST ON)
129+
endif()
130+
# Prevent overriding the parent project's compiler/linker settings
131+
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
132+
# Disable installation of GoogleTest to prevent conflicts with system packages
133+
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE)
134+
set(INSTALL_GMOCK OFF CACHE BOOL "" FORCE)
135+
136+
FetchContent_MakeAvailable(googletest)
137+
138+
if(TARGET gtest)
94139
add_executable(linuxcampam_tests
95140
tests/main.cpp
96141
tests/test_auth_config.cpp
97142
tests/test_model_version.cpp
98143
tests/test_embeddings.cpp
99144
tests/test_security.cpp
100145
tests/test_stability.cpp
101-
tests/test_stability.cpp
102-
src/service/auth_engine.cpp
103-
src/service/camera.cpp
104-
src/service/config.cpp
105-
src/service/utils.cpp
146+
tests/test_camera_detection.cpp
147+
tests/test_config_detection.cpp
148+
tests/test_auth_logic.cpp
149+
tests/test_protocol.cpp
106150
)
107-
# We need to compile auth_engine.cpp without main(), which is fine since main is in main.cpp.
108-
# However, auth_engine might have dependencies.
109-
target_include_directories(linuxcampam_tests PRIVATE include)
151+
152+
# We link against the service_core library to test internal logic without
153+
# duplicating compilation units or pulling in the main service entry point.
110154
target_link_libraries(linuxcampam_tests PRIVATE
111-
GTest::GTest GTest::Main
112-
${OpenCV_LIBS}
113-
Threads::Threads
114-
stdc++fs
155+
gtest gtest_main gmock
156+
service_core
115157
)
116-
if(nlohmann_json_FOUND)
117-
target_link_libraries(linuxcampam_tests PRIVATE nlohmann_json::nlohmann_json)
118-
endif()
119158

120159
add_test(NAME UnitTests COMMAND linuxcampam_tests)
121160
endif()
@@ -136,14 +175,17 @@ install(FILES ${CMAKE_SOURCE_DIR}/config/config.ini
136175
DESTINATION /etc/linuxcampam
137176
)
138177

178+
install(DIRECTORY ${CMAKE_SOURCE_DIR}/models/
179+
DESTINATION /usr/share/linuxcampam/models
180+
FILES_MATCHING PATTERN "*.onnx"
181+
)
182+
139183
install(FILES ${CMAKE_SOURCE_DIR}/config/linuxcampam_pam_profile
140184
DESTINATION /usr/share/pam-configs
141185
RENAME linuxcampam
142186
)
143187

144-
install(DIRECTORY ${CMAKE_SOURCE_DIR}/models
145-
DESTINATION /etc/linuxcampam
146-
)
188+
147189

148190
install(FILES ${CMAKE_SOURCE_DIR}/scripts/linuxcampam.service
149191
DESTINATION /lib/systemd/system
@@ -168,8 +210,9 @@ set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Vladimir Orlinski")
168210

169211
set(CPACK_GENERATOR "DEB")
170212
# Runtime dependencies (not -dev packages) for Ubuntu 24.04
171-
# OpenCV 4.6 runtime libs, PAM, and utilities
172-
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libopencv-core406t64, libopencv-imgproc406t64, libopencv-objdetect406t64, libopencv-dnn406t64, libopencv-videoio406t64, libopencv-photo406t64, libpam0g, libpam-runtime, v4l-utils, systemd")
213+
# Runtime dependencies (not -dev packages) for Ubuntu 24.04
214+
# OpenCV is statically linked, so we don't need libopencv-* packages
215+
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpam0g, libpam-runtime, v4l-utils, systemd, libgfortran5, libatlas3-base")
173216

174217
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/debian/postinst")
175218

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ See the [README.md](README.md) for full installation instructions.
3030
### Quick Build for Devs
3131

3232
```bash
33+
# 1. Build Static Dependencies (Required once)
34+
./scripts/build_opencv.sh
35+
36+
# 2. Build Project
3337
mkdir build && cd build
3438
cmake .. -DENABLE_TESTING=ON
3539
make

0 commit comments

Comments
 (0)