11cmake_minimum_required (VERSION 3.15 )
22project (docx_comment_parser VERSION 1.0.0 LANGUAGES CXX )
33
4- # ─── Standard & optimisation flags ──────────────────────────────────────────
5- set (CMAKE_CXX_STANDARD 17)
4+ # ─── Policy: normalise install() DESTINATION paths (fixes CMP0177 warning) ───
5+ # Python3_SITEARCH on MinGW contains backslashes which CMake 3.26+ normalises
6+ # automatically under the NEW policy. Setting it explicitly silences the warning
7+ # on all CMake versions ≥ 3.15 that support CMP0177.
8+ if (POLICY CMP0177)
9+ cmake_policy (SET CMP0177 NEW )
10+ endif ()
11+
12+ # ─── C++ standard ─────────────────────────────────────────────────────────────
13+ set (CMAKE_CXX_STANDARD 17)
614set (CMAKE_CXX_STANDARD_REQUIRED ON )
7- set (CMAKE_CXX_EXTENSIONS OFF )
15+ set (CMAKE_CXX_EXTENSIONS OFF )
816
917if (NOT CMAKE_BUILD_TYPE )
1018 set (CMAKE_BUILD_TYPE Release)
1119endif ()
1220
13- # LTO for Release builds
14- include (CheckIPOSupported )
15- check_ipo_supported (RESULT _ipo_ok OUTPUT _ipo_err )
16- if (_ipo_ok)
17- set (CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON )
21+ # ─── LTO (Release only, skip on MinGW where it is unreliable) ─────────────────
22+ if (NOT MINGW)
23+ include (CheckIPOSupported )
24+ check_ipo_supported (RESULT _ipo_ok OUTPUT _ipo_err )
25+ if (_ipo_ok)
26+ set (CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON )
27+ endif ()
1828endif ()
1929
20- # ─── Dependencies ────────────────────────────────────────────────────────────
21- # libxml2 not required - using built-in XML parser
22- find_package (ZLIB REQUIRED )
30+ # ─── Dependencies ─────────────────────────────────────────────────────────────
31+ # No libxml2 required — self-contained XML parser.
32+ #
33+ # zlib strategy:
34+ # MSVC — no system zlib exists. zip_reader.cpp compiles the vendored
35+ # single-header inflate from vendor/zlib/zlib.h; no link step needed.
36+ # MinGW — zlib1.dll + libz.a ship with every MinGW-w64 installation.
37+ # Linux / macOS — system zlib (apt install zlib1g-dev / brew install zlib).
38+ if (NOT MSVC )
39+ find_package (ZLIB REQUIRED )
40+ endif ()
2341
24- # ─── Core shared library ─────────────────────────────────────────────────────
42+ # ─── Core shared library ──────────────────────────────────────────────────────
2543add_library (docx_comment_parser SHARED
2644 src/docx_parser.cpp
2745 src/batch_parser.cpp
2846 src/zip_reader.cpp
2947 src/xml_parser.cpp
3048)
3149
50+ # Tell the compiler which TUs are *building* the DLL so DOCX_API expands to
51+ # dllexport; consumers that only include the header get dllimport instead.
52+ target_compile_definitions (docx_comment_parser PRIVATE DOCX_BUILDING_DLL )
53+
3254target_include_directories (docx_comment_parser
3355 PUBLIC
3456 $<BUILD_INTERFACE :${CMAKE_CURRENT_SOURCE_DIR} /include >
3557 $<INSTALL_INTERFACE :include >
3658 PRIVATE
59+ # On MSVC the vendored zlib.h is included by zip_reader.cpp via a
60+ # relative path "../vendor/zlib/zlib.h". Adding vendor/ here makes
61+ # the path work regardless of which directory cl.exe is invoked from.
62+ $<$<CXX_COMPILER_ID :MSVC >:${CMAKE_CURRENT_SOURCE_DIR} /vendor >
3763)
3864
3965target_link_libraries (docx_comment_parser
4066 PRIVATE
41- ZLIB::ZLIB
67+ # Link system zlib on non-MSVC platforms only.
68+ # On MSVC, inflate is compiled directly into zip_reader.cpp.
69+ $<$<NOT :$<CXX_COMPILER_ID :MSVC >>:ZLIB ::ZLIB >
4270)
4371
44- # Hide all symbols except those explicitly exported with DOCX_API
45- set_target_properties (docx_comment_parser PROPERTIES
46- CXX_VISIBILITY_PRESET hidden
47- VISIBILITY_INLINES_HIDDEN ON
48- VERSION ${PROJECT_VERSION}
49- SOVERSION 1
50- )
72+ # On MinGW, link the standard threading and networking libs that std::thread
73+ # and socket code pull in indirectly.
74+ if (MINGW)
75+ target_link_libraries (docx_comment_parser PRIVATE -lws2_32 -lmswsock )
76+ endif ()
77+
78+ # Symbol visibility — ELF only. On Windows (PE/DLL) visibility is handled by
79+ # __declspec(dllexport/dllimport) in the header; the GCC attribute is a no-op
80+ # there but can confuse some linker versions, so guard it explicitly.
81+ if (NOT WIN32 )
82+ set_target_properties (docx_comment_parser PROPERTIES
83+ CXX_VISIBILITY_PRESET hidden
84+ VISIBILITY_INLINES_HIDDEN ON
85+ )
86+ endif ()
87+
88+ # VERSION / SOVERSION are ELF-only concepts (produce .so.1 symlinks on Linux).
89+ # MinGW/Windows uses a different DLL versioning mechanism; setting these
90+ # properties on a PE target causes the ld "error: ld returned 5" link failure.
91+ if (NOT WIN32 )
92+ set_target_properties (docx_comment_parser PROPERTIES
93+ VERSION ${PROJECT_VERSION}
94+ SOVERSION 1
95+ )
96+ endif ()
5197
5298target_compile_options (docx_comment_parser PRIVATE
5399 $<$<CXX_COMPILER_ID :GNU ,Clang >:-Wall -Wextra -Wpedantic >
54100 $<$<CONFIG :Release >:-O3 -DNDEBUG >
55101)
56102
57- # ─── Python extension (optional) ─────────────────────────────────────────────
103+ # ─── Python extension (optional) ──────────────────────────────────────────────
58104option (BUILD_PYTHON_BINDINGS "Build Python bindings via pybind11" ON )
59105
60106if (BUILD_PYTHON_BINDINGS)
61107 find_package (Python3 REQUIRED COMPONENTS Interpreter Development )
62108 find_package (pybind11 CONFIG QUIET )
63109
64110 if (NOT pybind11_FOUND)
65- # Try to locate pybind11 via pip-installed package
111+ # Locate pybind11 installed via pip
66112 execute_process (
67113 COMMAND ${Python3_EXECUTABLE} -c "import pybind11; print(pybind11.get_cmake_dir())"
68114 OUTPUT_VARIABLE _pybind11_cmake_dir
@@ -79,48 +125,55 @@ if(BUILD_PYTHON_BINDINGS)
79125 python/python_bindings.cpp
80126 )
81127
128+ # The extension builds *into* the DLL — it also needs DOCX_BUILDING_DLL
129+ # so that DOCX_API expands to dllexport when compiling its TU on Windows.
130+ target_compile_definitions (_docx_comment_parser PRIVATE DOCX_BUILDING_DLL )
131+
82132 target_include_directories (_docx_comment_parser PRIVATE
83133 ${CMAKE_CURRENT_SOURCE_DIR} /include
84-
134+ # Vendor dir for MSVC (same reason as the main library target)
135+ $<$<CXX_COMPILER_ID :MSVC >:${CMAKE_CURRENT_SOURCE_DIR} /vendor >
85136 )
86137
87138 target_link_libraries (_docx_comment_parser PRIVATE
88139 docx_comment_parser
89-
90- ZLIB::ZLIB
140+ $<$<NOT :$<CXX_COMPILER_ID :MSVC >>:ZLIB ::ZLIB >
91141 )
92142
93- # Install alongside the Python package
143+ # CMP0177 NEW: CMake normalises the path before passing it to install(),
144+ # so backslashes from Python3_SITEARCH on Windows are converted to slashes.
94145 install (TARGETS _docx_comment_parser
95- LIBRARY DESTINATION ${Python3_SITEARCH}
146+ LIBRARY DESTINATION "${Python3_SITEARCH} "
147+ RUNTIME DESTINATION "${Python3_SITEARCH} "
96148 )
97149 else ()
98- message (WARNING "pybind11 not found – Python bindings will not be built. "
99- "Install with: pip install pybind11" )
150+ message (WARNING
151+ "pybind11 not found — Python bindings will not be built.\n "
152+ "Install with: pip install pybind11" )
100153 endif ()
101154endif ()
102155
103156# ─── Install rules ────────────────────────────────────────────────────────────
104157include (GNUInstallDirs )
105158
106159install (TARGETS docx_comment_parser
107- EXPORT docx_comment_parserTargets
108- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
109- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
110- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
111- INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
160+ EXPORT docx_comment_parserTargets
161+ LIBRARY DESTINATION " ${CMAKE_INSTALL_LIBDIR} "
162+ ARCHIVE DESTINATION " ${CMAKE_INSTALL_LIBDIR} "
163+ RUNTIME DESTINATION " ${CMAKE_INSTALL_BINDIR} "
164+ INCLUDES DESTINATION " ${CMAKE_INSTALL_INCLUDEDIR} "
112165)
113166
114167install (FILES
115168 include/docx_comment_parser.h
116169 include/zip_reader.h
117- DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} /docx_comment_parser
170+ DESTINATION " ${CMAKE_INSTALL_INCLUDEDIR} /docx_comment_parser"
118171)
119172
120173install (EXPORT docx_comment_parserTargets
121- FILE docx_comment_parserTargets.cmake
122- NAMESPACE docx::
123- DESTINATION ${CMAKE_INSTALL_LIBDIR} /cmake/docx_comment_parser
174+ FILE docx_comment_parserTargets.cmake
175+ NAMESPACE docx::
176+ DESTINATION " ${CMAKE_INSTALL_LIBDIR} /cmake/docx_comment_parser"
124177)
125178
126179# ─── Tests ────────────────────────────────────────────────────────────────────
0 commit comments