@@ -99,6 +99,76 @@ if(CASS_BUILD_STATIC)
9999 if (CASS_INSTALL_CASSANDRA_COMPAT AND NOT WIN32 )
100100 create_symlink (${INSTALL_NAME_STATIC} ${CASSANDRA_COMPAT_STATIC_SYMLINK} )
101101 endif ()
102+
103+ # The Rust staticlib contains unresolved references to OpenSSL and system
104+ # libraries. Declare them as transitive (INTERFACE) dependencies so that
105+ # any target linking against scylladb_static automatically pulls
106+ # in the required symbols in the correct order.
107+ #
108+ # NOTE: Some of these libraries (e.g. OpenSSL, ws2_32, crypt32, userenv on
109+ # Windows) also appear in CASS_LIBS (populated by cmake/Dependencies.cmake).
110+ # This causes them to appear twice on the linker command line, which is
111+ # intentional and harmless -- linkers silently ignore duplicate inputs --
112+ # but it keeps the static target self-contained so it works correctly even
113+ # when linked outside the integration-test build where CASS_LIBS is set.
114+
115+ # ## `INTERFACE_LINK_LIBRARIES` on an IMPORTED target
116+ # For an **IMPORTED** target (which `scylladb_static` is — `add_library(scylladb_static STATIC IMPORTED GLOBAL)`),
117+ # the `INTERFACE_LINK_LIBRARIES` property means: "when something links against this target,
118+ # also link against these libraries. This is actually the **correct** property to use here. The distinction:
119+ # - `LINK_LIBRARIES` — libraries used to build the target itself (irrelevant for IMPORTED targets
120+ # since they're pre-built)
121+ # - `INTERFACE_LINK_LIBRARIES` — libraries that **consumers** of this target must also link against
122+ #
123+ # Since `scylladb_static` is a pre-built static archive, it doesn't get "built" by CMake — it's already compiled.
124+ # But any executable that links against it (like `cassandra-integration-tests`) needs to also link
125+ # `-lssl -lcrypto -ldl -lm -lpthread` to resolve the symbols that the archive references.
126+ # That's exactly what `INTERFACE_LINK_LIBRARIES` communicates.
127+ #
128+ # The word "INTERFACE" in CMake doesn't mean "public API" in the C++ sense — it means "propagated to consumers."
129+ # For an IMPORTED static library, ALL transitive dependencies are necessarily interface dependencies because
130+ # the static archive is opaque to CMake (it can't see inside it to know what symbols are needed).
131+ set (_STATIC_INTERFACE_LIBS "" )
132+
133+ if (CASS_USE_OPENSSL AND OPENSSL_LIBRARIES)
134+ list (APPEND _STATIC_INTERFACE_LIBS ${OPENSSL_LIBRARIES} )
135+ endif ()
136+
137+ if (WIN32 )
138+ # Windows system libraries required by Rust runtime and its dependencies
139+ list (APPEND _STATIC_INTERFACE_LIBS ws2_32 bcrypt ntdll userenv crypt32 secur32 ncrypt)
140+ elseif (APPLE )
141+ list (APPEND _STATIC_INTERFACE_LIBS ${CMAKE_DL_LIBS } m)
142+ find_package (Threads )
143+ if (Threads_FOUND)
144+ list (APPEND _STATIC_INTERFACE_LIBS Threads::Threads)
145+ endif ()
146+ # CoreFoundation is needed by the iana-time-zone crate on macOS
147+ find_library (COREFOUNDATION_LIBRARY CoreFoundation )
148+ if (COREFOUNDATION_LIBRARY)
149+ list (APPEND _STATIC_INTERFACE_LIBS ${COREFOUNDATION_LIBRARY} )
150+ endif ()
151+ # SystemConfiguration and Security may also be needed on macOS
152+ find_library (SYSTEMCONFIGURATION_LIBRARY SystemConfiguration )
153+ if (SYSTEMCONFIGURATION_LIBRARY)
154+ list (APPEND _STATIC_INTERFACE_LIBS ${SYSTEMCONFIGURATION_LIBRARY} )
155+ endif ()
156+ find_library (SECURITY_LIBRARY Security )
157+ if (SECURITY_LIBRARY)
158+ list (APPEND _STATIC_INTERFACE_LIBS ${SECURITY_LIBRARY} )
159+ endif ()
160+ else () # non-Windows and non-Apple - assume Unix-like, such as Linux
161+ list (APPEND _STATIC_INTERFACE_LIBS ${CMAKE_DL_LIBS } m)
162+ find_package (Threads )
163+ if (Threads_FOUND)
164+ list (APPEND _STATIC_INTERFACE_LIBS Threads::Threads)
165+ endif ()
166+ endif ()
167+
168+ if (_STATIC_INTERFACE_LIBS)
169+ set_target_properties (scylladb_static PROPERTIES
170+ INTERFACE_LINK_LIBRARIES "${_STATIC_INTERFACE_LIBS} " )
171+ endif ()
102172endif ()
103173
104174#-------------------------------------
0 commit comments