Skip to content

Commit e215b8d

Browse files
nicknick
authored andcommitted
updated CMakeLists for tests and test files to fix tests with manual zlib header file
1 parent bec25f7 commit e215b8d

5 files changed

Lines changed: 80 additions & 39 deletions

File tree

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
BUILDING.md
88
/.vscode
99
/build
10-
/dist
1110
.pypirc
12-
/build_mingw64
11+
/build_mingw64
12+
/build_msvc
161 KB
Binary file not shown.
47.1 KB
Binary file not shown.

tests/CMakeLists.txt

Lines changed: 56 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
# =============================================================================
22
# tests/CMakeLists.txt
3-
#
4-
# Builds and registers the self-contained docx_comment_parser test suite.
5-
# Invoked automatically by the parent CMakeLists when BUILD_TESTS=ON (default).
6-
#
7-
# Usage:
8-
# cmake -B build -DBUILD_TESTS=ON
9-
# cmake --build build
10-
# ctest --test-dir build --output-on-failure
113
# =============================================================================
124

135
cmake_minimum_required(VERSION 3.15)
146

15-
# ─── zlib is needed by the test's own ZIP builder (uses crc32/inflate) ────────
16-
# On MSVC the vendored zlib.h is used (same as zip_reader.cpp).
17-
# On Linux/macOS/MinGW we link the system libz.
7+
# ─── zlib ────────────────────────────────────────────────────────────────────
8+
# On MSVC: crc32 body is compiled into the test TU via VENDOR_ZLIB_IMPLEMENTATION;
9+
# no library link needed.
10+
# On Linux / macOS / MinGW: link the system libz.
1811
if(NOT MSVC)
1912
find_package(ZLIB REQUIRED)
2013
endif()
@@ -24,7 +17,6 @@ add_executable(test_docx_parser
2417
test_docx_parser.cpp
2518
)
2619

27-
# Inherit C++17 from parent; make it explicit here as a safety net
2820
set_target_properties(test_docx_parser PROPERTIES
2921
CXX_STANDARD 17
3022
CXX_STANDARD_REQUIRED ON
@@ -33,52 +25,85 @@ set_target_properties(test_docx_parser PROPERTIES
3325

3426
target_include_directories(test_docx_parser
3527
PRIVATE
36-
# Public headers of the library under test
3728
${CMAKE_SOURCE_DIR}/include
38-
# Vendor dir: test_docx_parser.cpp includes vendor/zlib/zlib.h on MSVC
3929
$<$<CXX_COMPILER_ID:MSVC>:${CMAKE_SOURCE_DIR}/vendor>
4030
)
4131

4232
target_link_libraries(test_docx_parser
4333
PRIVATE
44-
# The shared library being tested (provides docx:: API)
4534
docx_comment_parser
46-
# zlib — crc32() is called by the in-memory ZIP builder in the test.
47-
# On MSVC the vendored header is used; no link step is needed there.
4835
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:ZLIB::ZLIB>
4936
)
5037

5138
target_compile_options(test_docx_parser PRIVATE
5239
$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -Wpedantic>
53-
# Debug build: keep symbols for readable stack traces
54-
$<$<CONFIG:Debug>:-g -O0>
55-
# Release build: full optimisation, suppress debug info
56-
$<$<CONFIG:Release>:-O2 -DNDEBUG>
40+
$<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:GNU,Clang>>:-g -O0>
41+
$<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:GNU,Clang>>:-O2 -DNDEBUG>
5742
)
5843

59-
# ─── CTest registration ───────────────────────────────────────────────────────
60-
# One test entry per logical group so CTest can report them individually.
61-
# All groups are driven by the single binary; the binary's own main() returns
62-
# non-zero on any failure, which CTest treats as a test failure.
44+
# ─── Windows DLL placement ────────────────────────────────────────────────────
45+
# The runtime loader searches the exe's own directory first. Copy our DLL
46+
# there so the test runs without any extra PATH setup.
47+
if(WIN32)
48+
add_custom_command(TARGET test_docx_parser POST_BUILD
49+
COMMAND ${CMAKE_COMMAND} -E copy_if_different
50+
$<TARGET_FILE:docx_comment_parser>
51+
$<TARGET_FILE_DIR:test_docx_parser>
52+
COMMENT "Copying docx_comment_parser DLL next to test executable"
53+
VERBATIM
54+
)
55+
56+
# On MinGW: also copy zlib1.dll (runtime dependency of our DLL) and
57+
# pre-resolve the compiler bin dir for use in ENVIRONMENT_MODIFICATION below.
58+
if(MINGW)
59+
get_filename_component(_mingw_bin "${CMAKE_CXX_COMPILER}" DIRECTORY)
60+
61+
find_file(_zlib1_dll
62+
NAMES zlib1.dll
63+
HINTS "${_mingw_bin}"
64+
NO_DEFAULT_PATH
65+
)
66+
if(_zlib1_dll)
67+
add_custom_command(TARGET test_docx_parser POST_BUILD
68+
COMMAND ${CMAKE_COMMAND} -E copy_if_different
69+
"${_zlib1_dll}"
70+
$<TARGET_FILE_DIR:test_docx_parser>
71+
COMMENT "Copying zlib1.dll next to test executable"
72+
VERBATIM
73+
)
74+
endif()
75+
endif()
76+
endif()
6377

78+
# ─── CTest registration ───────────────────────────────────────────────────────
6479
add_test(
6580
NAME DocxParser.BasicParsing
6681
COMMAND test_docx_parser
6782
)
6883

69-
# Working directory: project root so that relative paths (e.g. sample .docx
70-
# files placed there in future) resolve correctly.
7184
set_tests_properties(DocxParser.BasicParsing PROPERTIES
7285
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
73-
# Fail the test if it takes more than 30 seconds (catches infinite loops)
7486
TIMEOUT 30
75-
# Pass these back to CTest's output for easier diagnosis
7687
LABELS "unit;docx;parser"
7788
)
7889

90+
# Prepend the MinGW compiler bin dir to PATH so CTest finds libgcc_s_seh-1.dll,
91+
# libstdc++-6.dll, libwinpthread-1.dll even when MSYS2 is not on the system PATH.
92+
# Must be set AFTER add_test().
93+
# ENVIRONMENT_MODIFICATION (CMake 3.22+) correctly handles the OS path separator.
94+
if(WIN32 AND MINGW)
95+
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22")
96+
set_tests_properties(DocxParser.BasicParsing PROPERTIES
97+
ENVIRONMENT_MODIFICATION
98+
"PATH=path_list_prepend:${_mingw_bin}"
99+
)
100+
endif()
101+
# For CMake < 3.22 the DLL copies above are the fallback: zlib1.dll is
102+
# copied next to the exe; libgcc / libstdc++ / libwinpthread are assumed
103+
# to be reachable through the existing system PATH (standard MSYS2 setup).
104+
endif()
105+
79106
# ─── Optional: valgrind memory-check target ───────────────────────────────────
80-
# Creates a second CTest entry that runs the binary under valgrind when it is
81-
# available. Skipped silently on systems without valgrind.
82107
find_program(VALGRIND_EXECUTABLE valgrind)
83108
if(VALGRIND_EXECUTABLE)
84109
add_test(

tests/test_docx_parser.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@
1818
#include <stdexcept>
1919
#include <string>
2020
#include <vector>
21-
// On MSVC the test's in-memory ZIP builder uses crc32(), Bytef, and uInt.
22-
// The vendored header supplies all three without requiring a system zlib.
23-
// On Linux/macOS/MinGW the system <zlib.h> is used (no IMPLEMENTATION define,
24-
// so the function bodies live only in zip_reader.cpp's TU).
21+
// On MSVC the test's in-memory ZIP builder uses crc32(), Bytef, and uInt from
22+
// the vendored single-header zlib. VENDOR_ZLIB_IMPLEMENTATION activates the
23+
// function bodies in this TU — the same flag zip_reader.cpp uses. Each TU
24+
// that defines it gets its own private copy; there is no ODR conflict because
25+
// the test executable and the shared library are separate binaries.
26+
// Without this define the bodies live only inside the DLL and are not exported,
27+
// causing LNK2001 "unresolved external symbol crc32".
28+
// On Linux/macOS/MinGW the system <zlib.h> is used; crc32 is resolved via -lz.
2529
#ifdef _MSC_VER
30+
# define VENDOR_ZLIB_IMPLEMENTATION
2631
# include "../vendor/zlib/zlib.h"
2732
#else
2833
# include <zlib.h>
@@ -185,6 +190,18 @@ static const char* DOCUMENT_XML = R"(<?xml version="1.0" encoding="UTF-8" standa
185190

186191
// ─── Helpers ─────────────────────────────────────────────────────────────────
187192

193+
static std::string temp_docx_path() {
194+
// /tmp does not exist on Windows; use %TEMP% / %TMP% instead.
195+
#ifdef _WIN32
196+
const char* dir = std::getenv("TEMP");
197+
if (!dir) dir = std::getenv("TMP");
198+
if (!dir) dir = "C:\\Temp";
199+
return std::string(dir) + "\\test_docx_parser_fixture.docx";
200+
#else
201+
return "/tmp/test_docx_parser_fixture.docx";
202+
#endif
203+
}
204+
188205
static std::string make_temp_docx() {
189206
ZipBuilder zb;
190207
zb.add("[Content_Types].xml", CONTENT_TYPES);
@@ -196,8 +213,7 @@ static std::string make_temp_docx() {
196213

197214
auto bytes = zb.build();
198215

199-
// Write to temp file
200-
std::string path = "/tmp/test_docx_parser_fixture.docx";
216+
std::string path = temp_docx_path();
201217
std::ofstream f(path, std::ios::binary);
202218
if (!f) throw std::runtime_error("Cannot create temp file: " + path);
203219
f.write(reinterpret_cast<const char*>(bytes.data()), bytes.size());

0 commit comments

Comments
 (0)