Skip to content

Commit 7247284

Browse files
wprzytuladkropachev
andcommitted
static linking: publish transitive deps in .pc
Based on my research, using `pkg-config` is a common way to handle transitive dependencies for static linking. Example invocation: `cc \ $(pkg-config --cflags scylladb_static) \ ../examples/ssl/ssl.c \ $(pkg-config --libs --static scylladb_static) \ -o ssl_example` Declare the static driver's transitive dependencies (OpenSSL, system libs, threading, macOS frameworks) in the generated scylladb_static.pc metadata via Requires.private and Libs.private. This lets installed consumers resolve all required symbols via `pkg-config --static` without hardcoding platform-specific flags. Co-authored-by: Dmitry Kropachev <dmitry.kropachev@gmail.com>
1 parent 8648a4e commit 7247284

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

scylla-rust-wrapper/CMakeLists.txt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,47 +128,93 @@ if(CASS_BUILD_STATIC)
128128
# The word "INTERFACE" in CMake doesn't mean "public API" in the C++ sense — it means "propagated to consumers."
129129
# For an IMPORTED static library, ALL transitive dependencies are necessarily interface dependencies because
130130
# the static archive is opaque to CMake (it can't see inside it to know what symbols are needed).
131+
#
132+
# ## Comparison with `Libs.private` in pkg-config
133+
#
134+
# This is the CMake equivalent of `Libs.private` in the `.pc` file — both say
135+
# "consumers need these additional libraries when linking statically."
136+
# The naming is confusing but semantically correct:
137+
# - pkg-config: `Libs.private` = "needed by consumers for static linking"
138+
# - CMake: `INTERFACE_LINK_LIBRARIES` on IMPORTED STATIC = "needed by consumers"
131139
set(_STATIC_INTERFACE_LIBS "")
132140

141+
# These variables are used to generate the static library pkg-config file,
142+
# and are separate from _STATIC_INTERFACE_LIBS because pkg-config requires
143+
# a different format (e.g. "-lssl -lcrypto" instead of a list of library paths).
144+
set(scylladb_static_requires_private "")
145+
set(scylladb_static_libs_private "")
146+
133147
if(CASS_USE_OPENSSL AND OPENSSL_LIBRARIES)
134148
list(APPEND _STATIC_INTERFACE_LIBS ${OPENSSL_LIBRARIES})
149+
list(APPEND scylladb_static_requires_private openssl)
135150
endif()
136151

137152
if(WIN32)
138153
# Windows system libraries required by Rust runtime and its dependencies
139154
list(APPEND _STATIC_INTERFACE_LIBS ws2_32 bcrypt ntdll userenv crypt32 secur32 ncrypt)
155+
list(APPEND scylladb_static_libs_private
156+
"-lws2_32" "-lbcrypt" "-lntdll" "-luserenv" "-lcrypt32" "-lsecur32" "-lncrypt")
140157
elseif(APPLE)
141158
list(APPEND _STATIC_INTERFACE_LIBS ${CMAKE_DL_LIBS} m)
159+
if(CMAKE_DL_LIBS)
160+
list(APPEND scylladb_static_libs_private "-l${CMAKE_DL_LIBS}")
161+
endif()
162+
list(APPEND scylladb_static_libs_private "-lm")
142163
find_package(Threads)
143164
if(Threads_FOUND)
144165
list(APPEND _STATIC_INTERFACE_LIBS Threads::Threads)
166+
if(CMAKE_THREAD_LIBS_INIT)
167+
list(APPEND scylladb_static_libs_private "${CMAKE_THREAD_LIBS_INIT}")
168+
endif()
145169
endif()
146170
# CoreFoundation is needed by the iana-time-zone crate on macOS
147171
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
148172
if(COREFOUNDATION_LIBRARY)
149173
list(APPEND _STATIC_INTERFACE_LIBS ${COREFOUNDATION_LIBRARY})
174+
list(APPEND scylladb_static_libs_private "-framework CoreFoundation")
150175
endif()
151176
# SystemConfiguration and Security may also be needed on macOS
152177
find_library(SYSTEMCONFIGURATION_LIBRARY SystemConfiguration)
153178
if(SYSTEMCONFIGURATION_LIBRARY)
154179
list(APPEND _STATIC_INTERFACE_LIBS ${SYSTEMCONFIGURATION_LIBRARY})
180+
list(APPEND scylladb_static_libs_private "-framework SystemConfiguration")
155181
endif()
156182
find_library(SECURITY_LIBRARY Security)
157183
if(SECURITY_LIBRARY)
158184
list(APPEND _STATIC_INTERFACE_LIBS ${SECURITY_LIBRARY})
185+
list(APPEND scylladb_static_libs_private "-framework Security")
159186
endif()
160187
else() # non-Windows and non-Apple - assume Unix-like, such as Linux
161188
list(APPEND _STATIC_INTERFACE_LIBS ${CMAKE_DL_LIBS} m)
189+
if(CMAKE_DL_LIBS)
190+
list(APPEND scylladb_static_libs_private "-l${CMAKE_DL_LIBS}")
191+
endif()
192+
list(APPEND scylladb_static_libs_private "-lm")
162193
find_package(Threads)
163194
if(Threads_FOUND)
164195
list(APPEND _STATIC_INTERFACE_LIBS Threads::Threads)
196+
if(CMAKE_THREAD_LIBS_INIT)
197+
list(APPEND scylladb_static_libs_private "${CMAKE_THREAD_LIBS_INIT}")
198+
endif()
165199
endif()
166200
endif()
167201

168202
if(_STATIC_INTERFACE_LIBS)
169203
set_target_properties(scylladb_static PROPERTIES
170204
INTERFACE_LINK_LIBRARIES "${_STATIC_INTERFACE_LIBS}")
171205
endif()
206+
207+
if(scylladb_static_requires_private)
208+
list(REMOVE_DUPLICATES scylladb_static_requires_private)
209+
string(JOIN " " scylladb_static_requires_private
210+
${scylladb_static_requires_private})
211+
endif()
212+
213+
if(scylladb_static_libs_private)
214+
list(REMOVE_DUPLICATES scylladb_static_libs_private)
215+
string(JOIN " " scylladb_static_libs_private
216+
${scylladb_static_libs_private})
217+
endif()
172218
endif()
173219

174220
#-------------------------------------

scylla-rust-wrapper/scylladb_static.pc.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ includedir=@includedir@
66
Name: scylladb
77
Description: ScyllaDB CPP RS Driver
88
Version: @version@
9-
Requires: openssl
9+
Requires.private: @scylladb_static_requires_private@
1010
Libs: -L${libdir} -lscylladb_static
11+
Libs.private: @scylladb_static_libs_private@
1112
Cflags: -I${includedir}
1213
URL: https://github.com/scylladb/cpp-rs-driver/

0 commit comments

Comments
 (0)