Skip to content

Commit 5c6fe0b

Browse files
committed
Apply patches from sccn/liblsl#304
1 parent abac6fd commit 5c6fe0b

3 files changed

Lines changed: 318 additions & 0 deletions

File tree

‎.github/workflows/build.yml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ jobs:
5757
git clone https://github.com/sccn/liblsl.git
5858
git -C liblsl checkout "${LIBLSL_VERSION}"
5959
60+
- name: Apply liblsl patches
61+
shell: bash
62+
run: |
63+
cd liblsl
64+
git apply --check \
65+
"${GITHUB_WORKSPACE}/0001-Fix-transitive-dependencies-for-static-LSL-lsl.patch" \
66+
"${GITHUB_WORKSPACE}/0002-Don-t-export-Boost-as-a-dependency-of-LSL-lsl.patch"
67+
git apply \
68+
"${GITHUB_WORKSPACE}/0001-Fix-transitive-dependencies-for-static-LSL-lsl.patch" \
69+
"${GITHUB_WORKSPACE}/0002-Don-t-export-Boost-as-a-dependency-of-LSL-lsl.patch"
70+
6071
- name: Install dependencies on Linux
6172
if: runner.os == 'Linux' && matrix.bundled_boost == 'OFF'
6273
run: |
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
From 892320ffc446eb2d18b19fff73f8fdbadf834f68 Mon Sep 17 00:00:00 2001
2+
From: myd7349 <myd7349@gmail.com>
3+
Date: Mon, 21 Sep 2026 00:04:51 +0800
4+
Subject: [PATCH 1/2] Fix transitive dependencies for static LSL::lsl
5+
6+
Static builds of lsl did not forward its transitive dependencies
7+
(Threads, Windows iphlpapi/winmm/mswsock/ws2_32, Linux rt/dl, system
8+
pugixml) because they were linked PRIVATE via the lslobj object
9+
library. Consumers linking LSL::lsl therefore had to manually add
10+
these transitive dependencies themselves.
11+
---
12+
cmake/Dependencies.cmake | 49 +++++++++++++++++++++++++++++++++++-----
13+
cmake/Installation.cmake | 22 +++++++++++-------
14+
cmake/LSLConfig.cmake.in | 17 ++++++++++++++
15+
cmake/TargetLib.cmake | 2 +-
16+
cmake/TargetObjLib.cmake | 21 +----------------
17+
testing/CMakeLists.txt | 10 --------
18+
6 files changed, 76 insertions(+), 45 deletions(-)
19+
create mode 100644 cmake/LSLConfig.cmake.in
20+
21+
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake
22+
index 223cfe11..125b5a9f 100644
23+
--- a/cmake/Dependencies.cmake
24+
+++ b/cmake/Dependencies.cmake
25+
@@ -26,9 +26,6 @@ if(LSL_FETCH_PUGIXML)
26+
FetchContent_MakeAvailable(pugixml)
27+
set(BUILD_SHARED_LIBS ${_lsl_saved_build_shared_libs})
28+
unset(_lsl_saved_build_shared_libs)
29+
- if(TARGET pugixml AND NOT TARGET pugixml::pugixml)
30+
- add_library(pugixml::pugixml ALIAS pugixml)
31+
- endif()
32+
# Hide pugixml symbols - apply hidden visibility to the pugixml target
33+
set_target_properties(pugixml PROPERTIES
34+
CXX_VISIBILITY_PRESET hidden
35+
@@ -50,9 +47,6 @@ else()
36+
unset(_lsl_arch_count)
37+
endif()
38+
find_package(pugixml REQUIRED)
39+
- if(NOT TARGET pugixml::pugixml)
40+
- add_library(pugixml::pugixml ALIAS pugixml)
41+
- endif()
42+
set(LSL_PUGIXML_IS_FETCHED FALSE)
43+
endif()
44+
45+
@@ -73,3 +67,46 @@ else()
46+
target_link_libraries(lslboost INTERFACE Boost::boost Boost::disable_autolinking)
47+
endif()
48+
target_compile_definitions(lslboost INTERFACE BOOST_ALL_NO_LIB)
49+
+
50+
+# Single source of truth for every external (system/third-party) library lsl needs to link
51+
+# against. lslobj (which internal tests also link directly) and the real lsl target both
52+
+# link this same list, so it only has to be kept up to date in one place. Having lsl itself
53+
+# link these directly (not only indirectly via lslobj) matters for static builds: CMake
54+
+# records a STATIC library's PRIVATE link dependencies as $<LINK_ONLY:...> entries in its
55+
+# exported INTERFACE_LINK_LIBRARIES, so consumers linking the installed LSL::lsl get them
56+
+# transitively instead of having to add them by hand. For shared builds these stay private/
57+
+# hidden, which is correct since the dependencies are already resolved inside the shared lib.
58+
+set(lsllinklibs Threads::Threads)
59+
+
60+
+if(NOT LSL_PUGIXML_IS_FETCHED)
61+
+ if(TARGET pugixml::pugixml)
62+
+ list(APPEND lsllinklibs pugixml::pugixml)
63+
+ elseif(TARGET pugixml)
64+
+ # For pugixml versions before 1.11
65+
+ list(APPEND lsllinklibs pugixml)
66+
+ else()
67+
+ message(FATAL_ERROR "pugixml library target not found!")
68+
+ endif()
69+
+endif()
70+
+
71+
+if(NOT LSL_BUNDLED_BOOST)
72+
+ list(APPEND lsllinklibs Boost::boost Boost::disable_autolinking)
73+
+endif()
74+
+
75+
+if(MINGW)
76+
+ list(APPEND lsllinklibs bcrypt)
77+
+endif()
78+
+
79+
+if(UNIX AND NOT APPLE)
80+
+ # check that clock_gettime is present in the stdlib, link against librt otherwise
81+
+ include(CheckSymbolExists)
82+
+ check_symbol_exists(clock_gettime time.h HAS_GETTIME)
83+
+ if(NOT HAS_GETTIME)
84+
+ list(APPEND lsllinklibs rt)
85+
+ endif()
86+
+ if(LSL_DEBUGLOG)
87+
+ list(APPEND lsllinklibs dl)
88+
+ endif()
89+
+elseif(WIN32)
90+
+ list(APPEND lsllinklibs iphlpapi winmm mswsock ws2_32)
91+
+endif()
92+
diff --git a/cmake/Installation.cmake b/cmake/Installation.cmake
93+
index 19e57233..51710f56 100644
94+
--- a/cmake/Installation.cmake
95+
+++ b/cmake/Installation.cmake
96+
@@ -61,23 +61,29 @@ install(TARGETS ${LSLTargets}
97+
install(DIRECTORY include/lsl DESTINATION ${LSL_INSTALL_INCLUDEDIR})
98+
install(FILES include/lsl_c.h include/lsl_cpp.h DESTINATION ${LSL_INSTALL_INCLUDEDIR})
99+
100+
-# Generate the LSLConfig.cmake file and mark it for installation
101+
+# Export the targets to a separate LSLTargets.cmake file, included by the
102+
+# LSLConfig.cmake below.
103+
install(EXPORT LSLTargets
104+
- FILE LSLConfig.cmake
105+
+ FILE LSLTargets.cmake
106+
COMPONENT liblsl
107+
NAMESPACE "LSL::"
108+
DESTINATION ${LSL_CONFIG_INSTALL_DIR}
109+
)
110+
-# A common alternative to installing the exported package config file is to generate it from a template.
111+
-#configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/lslConfig.cmake.in
112+
-# ${CMAKE_CURRENT_BINARY_DIR}/LSLConfig.cmake
113+
-# INSTALL_DESTINATION ${LSL_CONFIG_INSTALL_DIR})
114+
-# If we use this method, then we need a corresponding install(FILES ...) command to install the generated file.
115+
116+
-# Install the version file and the helper CMake script.
117+
+# Generate LSLConfig.cmake from a template so it can call find_dependency() for
118+
+# the transitive dependencies that a static LSL::lsl requires its consumers to
119+
+# link against.
120+
+configure_package_config_file(
121+
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/LSLConfig.cmake.in
122+
+ ${CMAKE_CURRENT_BINARY_DIR}/LSLConfig.cmake
123+
+ INSTALL_DESTINATION ${LSL_CONFIG_INSTALL_DIR}
124+
+)
125+
+
126+
+# Install the version file, generated config file, and the helper CMake script.
127+
install(
128+
FILES
129+
cmake/LSLCMake.cmake
130+
+ ${CMAKE_CURRENT_BINARY_DIR}/LSLConfig.cmake
131+
${CMAKE_CURRENT_BINARY_DIR}/LSLConfigVersion.cmake
132+
COMPONENT liblsl
133+
DESTINATION ${LSL_CONFIG_INSTALL_DIR}
134+
diff --git a/cmake/LSLConfig.cmake.in b/cmake/LSLConfig.cmake.in
135+
new file mode 100644
136+
index 00000000..0a7bc0ba
137+
--- /dev/null
138+
+++ b/cmake/LSLConfig.cmake.in
139+
@@ -0,0 +1,17 @@
140+
+@PACKAGE_INIT@
141+
+
142+
+include(CMakeFindDependencyMacro)
143+
+
144+
+find_dependency(Threads)
145+
+
146+
+if(NOT @LSL_BUNDLED_BOOST@)
147+
+ find_dependency(Boost)
148+
+endif()
149+
+
150+
+if(NOT @LSL_FETCH_PUGIXML@)
151+
+ find_dependency(pugixml)
152+
+endif()
153+
+
154+
+include("${CMAKE_CURRENT_LIST_DIR}/LSLTargets.cmake")
155+
+
156+
+check_required_components(LSL)
157+
diff --git a/cmake/TargetLib.cmake b/cmake/TargetLib.cmake
158+
index 89606b6e..45097421 100644
159+
--- a/cmake/TargetLib.cmake
160+
+++ b/cmake/TargetLib.cmake
161+
@@ -30,7 +30,7 @@ endif()
162+
# but are used by the internal tests.
163+
# Note: We use BUILD_INTERFACE to avoid requiring lslobj in the export set - the object library's
164+
# objects are linked directly into lsl, so consumers don't need lslobj.
165+
-target_link_libraries(lsl PRIVATE $<BUILD_INTERFACE:lslobj>)
166+
+target_link_libraries(lsl PRIVATE $<BUILD_INTERFACE:lslobj> ${lsllinklibs})
167+
168+
# Set the include directories for the lsl target.
169+
# Note: We had to link lslobj as a PRIVATE dependency, therefore we must manually expose the include directories
170+
diff --git a/cmake/TargetObjLib.cmake b/cmake/TargetObjLib.cmake
171+
index 8c1f6afb..24720bd6 100644
172+
--- a/cmake/TargetObjLib.cmake
173+
+++ b/cmake/TargetObjLib.cmake
174+
@@ -29,23 +29,7 @@ target_include_directories(lslobj
175+
176+
# Link system libs
177+
# (boost might be bundled or system)
178+
-target_link_libraries(lslobj PRIVATE lslboost Threads::Threads)
179+
-if(MINGW)
180+
- target_link_libraries(lslobj PRIVATE bcrypt)
181+
-endif()
182+
-if(UNIX AND NOT APPLE)
183+
- # check that clock_gettime is present in the stdlib, link against librt otherwise
184+
- include(CheckSymbolExists)
185+
- check_symbol_exists(clock_gettime time.h HAS_GETTIME)
186+
- if(NOT HAS_GETTIME)
187+
- target_link_libraries(lslobj PRIVATE rt)
188+
- endif()
189+
- if(LSL_DEBUGLOG)
190+
- target_link_libraries(lslobj PRIVATE dl)
191+
- endif()
192+
-elseif(WIN32)
193+
- target_link_libraries(lslobj PRIVATE iphlpapi winmm mswsock ws2_32)
194+
-endif()
195+
+target_link_libraries(lslobj PRIVATE lslboost ${lsllinklibs})
196+
197+
# Compiler settings
198+
target_compile_definitions(lslobj
199+
@@ -102,7 +86,4 @@ if(LSL_PUGIXML_IS_FETCHED)
200+
if(UNIX AND NOT APPLE)
201+
target_link_options(lslobj PRIVATE "LINKER:--exclude-libs,libpugixml.a")
202+
endif()
203+
-else()
204+
- # System pugixml may be shared or static
205+
- target_link_libraries(lslobj PRIVATE pugixml::pugixml)
206+
endif()
207+
diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt
208+
index fa66c7d9..a71c4eb2 100644
209+
--- a/testing/CMakeLists.txt
210+
+++ b/testing/CMakeLists.txt
211+
@@ -102,8 +102,6 @@ target_link_libraries(lsl_test_internal PRIVATE lslobj lslboost common catch_mai
212+
# Internal tests need pugixml headers (lslobj links pugixml privately)
213+
if(LSL_PUGIXML_IS_FETCHED)
214+
target_include_directories(lsl_test_internal PRIVATE ${pugixml_SOURCE_DIR}/src)
215+
-else()
216+
- target_link_libraries(lsl_test_internal PRIVATE pugixml::pugixml)
217+
endif()
218+
# Pretend that lsl_test_internal is part of a shared lib so that it can use the __export symbols lslobj. REQ by MinGW.
219+
target_compile_definitions(lsl_test_internal PRIVATE LIBLSL_EXPORTS)
220+
@@ -120,8 +118,6 @@ target_compile_definitions(lsl_test_resolve_bad_interface PRIVATE LIBLSL_EXPORTS
221+
# Needs pugixml headers (resolver_impl.h -> stream_info_impl.h includes pugixml)
222+
if(LSL_PUGIXML_IS_FETCHED)
223+
target_include_directories(lsl_test_resolve_bad_interface PRIVATE ${pugixml_SOURCE_DIR}/src)
224+
-else()
225+
- target_link_libraries(lsl_test_resolve_bad_interface PRIVATE pugixml::pugixml)
226+
endif()
227+
228+
# resolve_machine test sets the api_config singleton, so it lives in its own executable.
229+
@@ -131,8 +127,6 @@ target_compile_definitions(lsl_test_resolve_machine PRIVATE LIBLSL_EXPORTS)
230+
# Needs pugixml headers (resolver_impl.h -> stream_info_impl.h includes pugixml)
231+
if(LSL_PUGIXML_IS_FETCHED)
232+
target_include_directories(lsl_test_resolve_machine PRIVATE ${pugixml_SOURCE_DIR}/src)
233+
-else()
234+
- target_link_libraries(lsl_test_resolve_machine PRIVATE pugixml::pugixml)
235+
endif()
236+
237+
# resolve_over_tcp test sets the api_config singleton, so it lives in its own executable.
238+
@@ -142,8 +136,6 @@ target_compile_definitions(lsl_test_resolve_over_tcp PRIVATE LIBLSL_EXPORTS)
239+
# Needs pugixml headers (resolver_impl.h -> stream_info_impl.h includes pugixml)
240+
if(LSL_PUGIXML_IS_FETCHED)
241+
target_include_directories(lsl_test_resolve_over_tcp PRIVATE ${pugixml_SOURCE_DIR}/src)
242+
-else()
243+
- target_link_libraries(lsl_test_resolve_over_tcp PRIVATE pugixml::pugixml)
244+
endif()
245+
246+
# resolve_query_port test sets the api_config singleton, so it lives in its own executable.
247+
@@ -153,8 +145,6 @@ target_compile_definitions(lsl_test_resolve_query_port PRIVATE LIBLSL_EXPORTS)
248+
# Needs pugixml headers (resolver_impl.h -> stream_info_impl.h includes pugixml)
249+
if(LSL_PUGIXML_IS_FETCHED)
250+
target_include_directories(lsl_test_resolve_query_port PRIVATE ${pugixml_SOURCE_DIR}/src)
251+
-else()
252+
- target_link_libraries(lsl_test_resolve_query_port PRIVATE pugixml::pugixml)
253+
endif()
254+
255+
if(LSL_BENCHMARKS)
256+
--
257+
2.55.0.windows.2
258+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
From a16e9e4a68ed532e4d1fd8e4310eb12243fd209c Mon Sep 17 00:00:00 2001
2+
From: myd7349 <myd7349@gmail.com>
3+
Date: Mon, 21 Sep 2026 23:26:48 +0800
4+
Subject: [PATCH 2/2] Don't export Boost as a dependency of LSL::lsl
5+
6+
Boost is only ever a header-only, PRIVATE compile-time dependency of
7+
lslobj (via the lslboost interface target), whether bundled or system-
8+
provided. Since lslobj is linked into lsl only through
9+
$<BUILD_INTERFACE:lslobj>, this dependency never reaches lsl's
10+
exported link interface, so it doesn't belong in lsllinklibs, and the
11+
installed LSLConfig.cmake doesn't need find_dependency(Boost) either.
12+
---
13+
cmake/Dependencies.cmake | 4 ----
14+
cmake/LSLConfig.cmake.in | 4 ----
15+
2 files changed, 8 deletions(-)
16+
17+
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake
18+
index 125b5a9f..67a09467 100644
19+
--- a/cmake/Dependencies.cmake
20+
+++ b/cmake/Dependencies.cmake
21+
@@ -89,10 +89,6 @@ if(NOT LSL_PUGIXML_IS_FETCHED)
22+
endif()
23+
endif()
24+
25+
-if(NOT LSL_BUNDLED_BOOST)
26+
- list(APPEND lsllinklibs Boost::boost Boost::disable_autolinking)
27+
-endif()
28+
-
29+
if(MINGW)
30+
list(APPEND lsllinklibs bcrypt)
31+
endif()
32+
diff --git a/cmake/LSLConfig.cmake.in b/cmake/LSLConfig.cmake.in
33+
index 0a7bc0ba..e15477d8 100644
34+
--- a/cmake/LSLConfig.cmake.in
35+
+++ b/cmake/LSLConfig.cmake.in
36+
@@ -4,10 +4,6 @@ include(CMakeFindDependencyMacro)
37+
38+
find_dependency(Threads)
39+
40+
-if(NOT @LSL_BUNDLED_BOOST@)
41+
- find_dependency(Boost)
42+
-endif()
43+
-
44+
if(NOT @LSL_FETCH_PUGIXML@)
45+
find_dependency(pugixml)
46+
endif()
47+
--
48+
2.55.0.windows.2
49+

0 commit comments

Comments
 (0)