10
votes

There is a following code:

#include <stdio.h>
#include <curl/curl.h>

int main(void){
  CURL *curl;
  CURLcode res;

  curl = curl_easy_init();

  if(curl == NULL)
    return 0;

  curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/getAccessAttributes?id=1");

  res = curl_easy_perform(curl);

  if(res != CURLE_OK) {
    fprintf(stderr, "Error: %s\n", curl_easy_strerror(res));
    return 0;
  }

  curl_easy_cleanup(curl);
  return 0;
}

Everything works fine if you collect it from the dynamic link library:

gcc test.c -lcurl -o test

Now I want to raise a static program:

gcc test.c /tmp/curl/lib/libcurl.a -static -lcurl -lssl -lcrypto -ldl -lm -lz -DCURL_STATICLIB -I/tmp/curl/include -o test

He is going with errors:

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function dlfcn_globallookup': (.text+0x11): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /tmp/curl/lib/libcurl.a(libcurl_la-netrc.o): In functionCurl_parsenetrc': netrc.c:(.text+0x3c8): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /tmp/curl/lib/libcurl.a(libcurl_la-curl_addrinfo.o): In function `Curl_getaddrinfo_ex': curl_addrinfo.c:(.text+0x60): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

The program works only if you specify a host ip address and not example.com. Otherwise the program can not resolve the domain name:

$ ./test
Error: Couldn't resolve host name

How can I solve the problem of name resolution? Thanks!

P.S. Static libcurl I collected the following method:

wget http://curl.haxx.se/download/curl-7.44.0.tar.lzma
tar xf curl-7.44.0.tar.lzma
cd curl-7.44.0
./configure --disable-shared --enable-static --prefix=/tmp/curl --disable-ldap --disable-sspi --without-librtmp --disable-ftp --disable-file --disable-dict --disable-telnet --disable-tftp --disable-rtsp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-smb --without-libidn
make && make install
2
I don't see how the warnings you post relate to the problem you describe. - Lightness Races in Orbit
You want to link against the static versions of all libraries or simply with libcurl? Also why do you specify it twice (the one from tmp and -lcurl; you should use -L in order to specify library paths: check ld man page).After you statically build your application, what's ldd test output? - CristiFati

2 Answers

8
votes

This is how it looks with dynamic libcurl.

$ ldd test
    linux-vdso.so.1 (0x00007ffcca3aa000)
    libcurl.so.4 => /usr/lib64/libcurl.so.4 (0x00007f5536ed6000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f5536b3e000)
    libssl.so.1.0.0 => /usr/lib64/libssl.so.1.0.0 (0x00007f55368d3000)
    libcrypto.so.1.0.0 => /usr/lib64/libcrypto.so.1.0.0 (0x00007f5536503000)
    libz.so.1 => /lib64/libz.so.1 (0x00007f55362ed000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f5537138000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f55360e9000)

If you want to link only curl statically, do not use -static. Just add libcurl.a as one of the objects files or use -lcurl, you don't need to specify it twice. After

gcc test.c curl-7.44.0/lib/.libs/libcurl.a -lssl -lcrypto -ldl -lm -lz -DCURL_STATICLIB -o test

you'll get

$ ldd test
    linux-vdso.so.1 (0x00007ffd9a0a7000)
    libssl.so.1.0.0 => /usr/lib64/libssl.so.1.0.0 (0x00007f947cc7e000)
    libcrypto.so.1.0.0 => /usr/lib64/libcrypto.so.1.0.0 (0x00007f947c8ae000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f947c6aa000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f947c3b1000)
    libz.so.1 => /lib64/libz.so.1 (0x00007f947c19b000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f947be03000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f947cee9000)

-static means that you want link all statically. Then you need all libraries prepared as static and the result will be:

$ ldd test
    not a dynamic executable
6
votes

I found a way. libcurl must be configured with key "--enable-ares".

./configure --disable-shared --enable-static --prefix=/tmp/curl --disable-ldap --disable-sspi --without-librtmp --disable-ftp --disable-file --disable-dict --disable-telnet --disable-tftp --disable-rtsp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-smb --without-libidn --enable-ares

Then the program will feature gethostbyname and will be able to resolve the domain name.

Thank you all for the comments.