Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake build prints "Static linking is broken!" #841

Closed
zethon opened this issue May 30, 2016 · 9 comments
Closed

CMake build prints "Static linking is broken!" #841

zethon opened this issue May 30, 2016 · 9 comments
Labels

Comments

@zethon
Copy link

zethon commented May 30, 2016

I want to statically link libcurl into an app I'm writing. I'm using the CMake build system since I'm trying to build with clang. However, the CMake build system is very clear:

CMake Warning at CMakeLists.txt:1137 (message):
Static linking is broken!

However, when I generate and then build I see it's built a file ./lib/libcurl.a

Can this file be trusted?

@bagder bagder added the cmake label May 31, 2016
@bagder
Copy link
Member

bagder commented May 31, 2016

That message was introduced in commit 8ed66f9 by @Lekensteyn . You remember the reason? Is it still valid?

@Lekensteyn
Copy link
Contributor

Lekensteyn commented May 31, 2016

This likely refers to the generated curl-config file that is unusable in a certain configuration involving static libs, the actual library could still be functional.

What if you make install the library and then try to link with curl-config --static-libs? Does that work or will you get an error?

There is also this TODO within that commit:

TODO CURL_LIBS also contains absolute paths which don't work with static -l...

@zethon
Copy link
Author

zethon commented May 31, 2016

curl-config --static-libs does work with valid-looking output and no errors.

@Lekensteyn
Copy link
Contributor

Lekensteyn commented May 31, 2016

It seems that the problem is related to the inclusion of other shared libraries:

$ curl --libcurl example.c example.com -s -o /dev/null
$ /tmp/curl-root/bin/curl-config --static-libs
/tmp/curl-root/lib/libcurl.a -lc -lidn -llber -lldap -ldl -l/usr/lib64/libssl.so -l/usr/lib64/libcrypto.so -l/usr/lib64/libz.so -l/usr/lib64/libssh2.so
$ gcc example.c `/tmp/curl-root/bin/curl-config --static-libs`
/usr/bin/ld: cannot find -l/usr/lib64/libssl.so
/usr/bin/ld: cannot find -l/usr/lib64/libcrypto.so
/usr/bin/ld: cannot find -l/usr/lib64/libz.so
/usr/bin/ld: cannot find -l/usr/lib64/libssh2.so
collect2: error: ld returned 1 exit status

The cmake scripts have to be modified to return a static library (libssl.a, etc.) instead of the shared libs. That is a bit complicated... FindXXX modules are supposed to export the static library locations. For example, only CMake 3.4 has done this for OpenSSL: https://cmake.org/cmake/help/v3.4/module/FindOpenSSL.html

The problem is that -l/usr/lib/x86_64-linux-gnu/libssl.a does not work, it really has to be -lssl (with an appropriate -L... as needed). Setting ENABLE_STATIC to no has as only side-effect that the curl-config command refuses to output something for --static-libs.

Here is a WIP patch to prefer linking to static libs, but that still results in invalid linker commands (the TODO on the end is not resolved yet):

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 06f18cf..6eff378 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -94,6 +94,15 @@ if (ENABLE_CURLDEBUG)
   set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG)
 endif()

+# Prefer linking to static libraries when building a static library.
+if(CURL_STATICLIB)
+  if(WIN32)
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  else()
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  endif()
+endif()
+
 # initialize CURL_LIBS
 set(CURL_LIBS "")

@@ -310,6 +319,9 @@ if(CMAKE_USE_OPENSSL)
   find_package(OpenSSL)
   if(OPENSSL_FOUND)
     list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
+    if(CURL_STATICLIB)
+      list(APPEND CURL_LIBS ${CMAKE_DL_LIBS})
+    endif()
     set(USE_OPENSSL ON)
     set(HAVE_LIBCRYPTO ON)
     set(HAVE_LIBSSL ON)
@@ -1133,9 +1145,7 @@ set(CURL_CA_BUNDLE          "")
 set(CURLVERSION             "${CURL_VERSION}")
 set(ENABLE_SHARED           "yes")
 if(CURL_STATICLIB)
-  # Broken: LIBCURL_LIBS below; .a lib is not built
-  message(WARNING "Static linking is broken!")
-  set(ENABLE_STATIC         "no")
+  set(ENABLE_STATIC         "yes")
 else()
   set(ENABLE_STATIC         "no")
 endif()
@@ -1144,7 +1154,6 @@ set(includedir              "\${prefix}/include")
 set(LDFLAGS                 "${CMAKE_SHARED_LINKER_FLAGS}")
 set(LIBCURL_LIBS            "")
 set(libdir                  "${CMAKE_INSTALL_PREFIX}/lib")
-# TODO CURL_LIBS also contains absolute paths which don't work with static -l...
 foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
   set(LIBCURL_LIBS          "${LIBCURL_LIBS} -l${_lib}")
 endforeach()

@bagder
Copy link
Member

bagder commented Jun 1, 2016

Static linking of libcurl is however the ability to build a static libcurl. Using a static libcurl is harder and we actually can't presume that we can figure out and provide the dependency chain of possible libs.

Lekensteyn added a commit to Lekensteyn/curl that referenced this issue Jun 1, 2016
Libraries for `curl-config --static-libs` are required to have the form
-ldl. Assume library paths like /usr/lib/libssl.so and map it to "ssl"
for curl-config.

This removes the confusing messag "Static linking is broken" which was
printed because curl-config --static-libs was disfunctional while the
static libcurl.a is fine.

Fixes curl#841
@zethon
Copy link
Author

zethon commented Jun 4, 2016

Sorry to be using this as a message board for trouble-shooting but you guys seem responsive! :)

I've tried building a simple C++ app with the static library and I am getting several ldap linking errors:

Undefined symbols for architecture x86_64:
"_ldap_url_parse", referenced from:
_Curl_ldap in libcurl.a(ldap.c.o)
"_ldap_set_option", referenced from:
_Curl_ldap in libcurl.a(ldap.c.o)
(and on and on)

The thing that is confusing me is that I have disabled LDAP support:

image

So, I'm not sure why libcurl.a still references LDAP or how to fix this (without having to needlessly link to the LDAP's libs).

Suggestions? Thanks!

@zethon
Copy link
Author

zethon commented Jun 4, 2016

I've made a little more progress. I was able get past the Linker errors (I think I may have just needed to clear my CMake cache and start from scratch) but now I don't seem to have any HTTP support (I'm on OSX 10.11.3). A simple call to an https site returns Unsupported protocol.

I'm certainly linking to the OpenSSL (and ZLib) libraries when I build libcurl, as well as in my app.

image

However it doesn't look like it:

$> src/curl -V
curl 7.50.0-DEV (Darwin) libcurl/7.50.0-DEV zlib/1.2.5
Protocols: http
Features: IPv6 libz UnixSockets

Thoughts?

@bagder
Copy link
Member

bagder commented Jun 4, 2016

For general questions, help and support, please use curl-library mailing list. For specific bugs/issues you find, file them here.

Lekensteyn added a commit to Lekensteyn/curl that referenced this issue Aug 8, 2016
The `curl-config --static-libs` command should not output paths like
-l/usr/lib/libssl.so, instead print the absolute path without `-l`.

This also removes the confusing message "Static linking is broken" which
was printed because curl-config --static-libs was disfunctional even
though the static libcurl.a library works properly.

Fixes curl#841
@bagder
Copy link
Member

bagder commented Sep 11, 2016

Fixed

@bagder bagder closed this as completed Sep 11, 2016
Lekensteyn added a commit that referenced this issue Sep 11, 2016
The `curl-config --static-libs` command should not output paths like
-l/usr/lib/libssl.so, instead print the absolute path without `-l`.

This also removes the confusing message "Static linking is broken" which
was printed because curl-config --static-libs was disfunctional even
though the static libcurl.a library works properly.

Fixes #841
@lock lock bot locked as resolved and limited conversation to collaborators May 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

No branches or pull requests

3 participants