From 3d315ba123ee3db9187411daa29839d3574714d8 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Sat, 14 Mar 2020 14:19:13 -0300 Subject: [PATCH] More static build linking fixes Static linking is a dumpster fire. --- CMakeLists.txt | 53 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5058698..373d08b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,8 +37,14 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(lokimq PRIVATE Threads::Threads) -include(FindPkgConfig) -pkg_search_module(libzmq QUIET libzmq>=4.3) +# libzmq is nearly impossible to link statically from a system-installed static library: it depends +# on a ton of other libraries which typically are not all statically available. So if the caller +# asked us to do things statically, don't even try to find a system lib and just build it. If they +# really want it, they can set up the libzmq_FOUND etc. variables themselves. +if(BUILD_SHARED_LIBS) + include(FindPkgConfig) + pkg_search_module(libzmq QUIET libzmq>=4.3) +endif() if(NOT libzmq_FOUND) message(STATUS "libzmq >= 4.3 not found, building bundled 4.3.2") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/local-libzmq") @@ -63,26 +69,45 @@ set_target_properties(lokimq PROPERTIES POSITION_INDEPENDENT_CODE ON ) -if(BUILD_SHARED_LIBS) - target_link_libraries(lokimq PUBLIC cppzmq) -else() - target_link_libraries(lokimq PUBLIC cppzmq-static) -endif() - if(NOT SODIUM_LIBRARIES) pkg_search_module(SODIUM REQUIRED libsodium) endif() +# allow adding links to non-local targets (which is allowed even under old policy as long as the +# target is an interface, but under new cmake it spews out warnings). +cmake_policy(SET CMP0079 NEW) + +function(link_dep_libs target linktype libdirs) + foreach(lib ${ARGN}) + find_library(link_lib-${lib} NAMES ${lib} PATHS ${libdirs}) + if(link_lib-${lib}) + target_link_libraries(${target} ${linktype} ${link_lib-${lib}}) + endif() + endforeach() +endfunction() + # Really want to just use SODIUM_LINK_LIBRARIES here, but that isn't in older cmake: -find_library(libsodium_link_libs NAMES ${SODIUM_LIBRARIES} PATHS ${SODIUM_LIBRARY_DIRS}) -target_link_libraries(lokimq PRIVATE ${libsodium_link_libs}) +if(BUILD_SHARED_LIBS) + link_dep_libs(lokimq PRIVATE ${SODIUM_LIBRARY_DIRS} ${SODIUM_LIBRARIES}) + target_include_directories(lokimq PRIVATE ${SODIUM_INCLUDE_DIRS}) -if(NOT BUILD_SHARED_LIBS) - target_link_libraries(cppzmq-static INTERFACE ${libsodium_link_libs}) + target_link_libraries(lokimq PUBLIC cppzmq) +else() + link_dep_libs(lokimq PRIVATE "${SODIUM_STATIC_LIBRARY_DIRS}" ${SODIUM_STATIC_LIBRARIES}) + target_include_directories(lokimq PRIVATE ${SODIUM_STATIC_INCLUDE_DIRS}) + + if (libzmq_FOUND) + # cppzmq doesn't properly set up its libzmq target dependencies so do it here (this isn't the + # normal case: we only get here if someone pre-set libzmq_FOUND etc. *and* wants static libs) + link_dep_libs(cppzmq-static INTERFACE "${PC_LIBZMQ_STATIC_LIBRARY_DIRS}" ${PC_LIBZMQ_STATIC_LIBRARIES}) + else() + # Otherwise we built a static vendored one, so make sure it links to the static libsodium + link_dep_libs(libzmq_vendor INTERFACE "${SODIUM_STATIC_LIBRARY_DIRS}" ${SODIUM_STATIC_LIBRARIES}) + endif() + + target_link_libraries(lokimq PUBLIC cppzmq-static) endif() -target_include_directories(lokimq PRIVATE ${SODIUM_INCLUDE_DIRS}) - add_library(lokimq::lokimq ALIAS lokimq) export(