Error linking with libcurl4-gnutls-dev 7.22.0-3ubuntu4 - bad documentation

Bug #1001576 reported by Zakhar on 2012-05-19
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Curl
Unknown
Unknown
curl (Ubuntu)
Low
Unassigned

Bug Description

$ lsb_release -rd
Description: Ubuntu 12.04 LTS
Release: 12.04

$ uname -a
Linux user-Notebook-PC 3.2.0-24-generic #37-Ubuntu SMP Wed Apr 25 08:43:22 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

$ LANG=EN && dpkg-query --list '*curl*' | grep ii
ii curl 7.22.0-3ubuntu4 Get a file from an HTTP, HTTPS or FTP server
ii libcurl3 7.22.0-3ubuntu4 Multi-protocol file transfer library (OpenSSL)
ii libcurl3-gnutls 7.22.0-3ubuntu4 Multi-protocol file transfer library (GnuTLS)
ii libcurl3-nss 7.22.0-3ubuntu4 Multi-protocol file transfer library (NSS)
ii libcurl4-gnutls-dev 7.22.0-3ubuntu4 Development files and documentation for libcurl (GnuTLS)
ii python-pycurl 7.19.0-4ubuntu3 Python bindings to libcurl

--------------------------------------------------------

WHAT HAPPENS:
----------------------
Programs using the curl library (curl_easy_init, curl_easy_perform, etc...) fail to link.
It was working as a charm in 10.04

STEP TO REPRODUCE
------------------------
From a fresh install of 12.04 x 64, you need to install curl and the libcurl4 development package

$ sudo apt-get install curl libcurl4-gnutls-dev

We will use the simple.c example given in the documentation (in /tmp so we don't mess up things)
We compile as it is recommended in the README on the same directory where simple.c is.

$ cd /tmp
$ cp /usr/share/doc/libcurl4-gnutls-dev/examples/simple.c .

$ `curl-config --cc --cflags --libs` -o simple simple.c
/tmp/ccwzHN2E.o: In function `main':
simple.c:(.text+0x99): undefined reference to `curl_easy_init'
simple.c:(.text+0xc6): undefined reference to `curl_easy_setopt'
simple.c:(.text+0xd2): undefined reference to `curl_easy_perform'
simple.c:(.text+0xe1): undefined reference to `curl_easy_cleanup'
collect2: ld returned 1 exit status

WHAT SHOULD HAPPEN
-------------------------
Examples given should compile and link as explained in the documentation.
All worked well in 10.04 (so it could be a side effect of "multiarch")

FURTHER INVESTIGATION
--------------------------
It is not a compile issue, because I made the object from simple.c ( gcc -c -o simple.o simple.c) and used it successfuly on 10.04

I did an strace (-f -e trace=file) of the linking process in both 10.04 and 12.04. The initial collect2 phase look the same, but the ld phase is much shorter with 12.04 without any obvious errors. The libcurl.so is found and opened on both cases. What I see is that ld seems to scan a lot of libraries then loops opening simple.o (our test program) and libraries, that is on 10.04. Under 12.04, it does not seem to loop but rather gives up after the first scan.

$ strace -f -e trace=file `curl-config --cc --cflags --libs` -o simple simple.o 2>&1 | grep libcurl
[pid 2956] stat("/usr/lib/x86_64-linux-gnu/libcurl.so", {st_mode=S_IFREG|0644, st_size=360488, ...}) = 0
[pid 2956] open("/usr/lib/x86_64-linux-gnu/libcurl.so", O_RDONLY) = 7

Compare with the same strace on 10.04 we had:
[pid 2752] stat("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libcurl.so", 0x7fff7a893690) = -1 ENOENT (No such file or directory)
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libcurl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 2752] stat("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libcurl.a", 0x7fff7a8936e0) = -1 ENOENT (No such file or directory)
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libcurl.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 2752] stat("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libcurl.so", 0x7fff7a893690) = -1 ENOENT (No such file or directory)
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libcurl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 2752] stat("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libcurl.a", 0x7fff7a8936e0) = -1 ENOENT (No such file or directory)
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libcurl.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 2752] stat("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", {st_mode=S_IFREG|0644, st_size=274368, ...}) = 0
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 7
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 12
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 4
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 6
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 8
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10
[pid 2752] open("/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/libcurl.so", O_RDONLY) = 10

As we can see, the first opening after the successful stat is the same, but then 10.04 'loops' and opens many times the file (and others), whereas 12.04 stops.

The symbols we need from simple.o are indeed
$ nm -a simple.o | grep 'U '
                 U curl_easy_cleanup
                 U curl_easy_init
                 U curl_easy_perform
                 U curl_easy_setopt

The library in 12.04 appears to have this symbols
$ nm -D /usr/lib/x86_64-linux-gnu/libcurl.so | grep curl_easy
000000000002a650 T curl_easy_cleanup
000000000002a770 T curl_easy_duphandle
00000000000235f0 T curl_easy_escape
000000000002a730 T curl_easy_getinfo
000000000002a490 T curl_easy_init
000000000002ab20 T curl_easy_pause
000000000002a570 T curl_easy_perform
000000000002acb0 T curl_easy_recv
000000000002a950 T curl_easy_reset
000000000002ad70 T curl_easy_send
000000000002a4d0 T curl_easy_setopt
0000000000035210 T curl_easy_strerror
0000000000023880 T curl_easy_unescape

FIX OPTIONS:
---------------

I might be wrong and fail to understand how to link such simple programs with the new multiarch.
If so, the README should be adapted to reflect this specificity of Ubuntu, and should give the appropriate steps to compile/link programs with libcurl, and it is then simply a "documentation bug".

If I did nothing wrong in respect to multiarch, there is definitely a bug or something installed incorrectly by the packages. Sorry I couldn't track it down any further.

Julian Taylor (jtaylor) wrote :

since 11.10 shared libraries must be placed behind objects needing their symbols (as it was always the case for static libraries)
this due to the linker flag --as-needed being default now.

the correct compile line is:
`curl-config --cc --cflags` -o simple simple.c `curl-config --libs`

Changed in curl (Ubuntu):
status: New → Invalid
Zakhar (alainb06) wrote :

Thank you for your very quick answer and it works like a charm.

But then I confirm there is indeed a *documentation bug*

Please do the following command:

$ sed -n 88p /usr/share/doc/libcurl4-gnutls-dev/html/curl-config.html
<p class="level0">&nbsp; $ `curl-config --cc --cflags --libs` -o example example.c

It should read instead:
$ sed -n 88p /usr/share/doc/libcurl4-gnutls-dev/html/curl-config.html
<p class="level0">&nbsp; $ `curl-config --cc --cflags` -o example example.c `curl-config --libs`

I attach the patch for the file:
/usr/share/doc/libcurl4-gnutls-dev/html/curl-config.html

Should be applied as
$ sudo patch -b /usr/share/doc/libcurl4-gnutls-dev/html/curl-config.html patch_curl-config.txt
patching file /usr/share/doc/libcurl4-gnutls-dev/html/curl-config.html

Julian Taylor (jtaylor) wrote :

I forwarded the issue to upstream.

summary: - Error linking with libcurl4-gnutls-dev 7.22.0-3ubuntu4
+ Error linking with libcurl4-gnutls-dev 7.22.0-3ubuntu4 - bad
+ documentation
Changed in curl (Ubuntu):
status: Invalid → Triaged
importance: Undecided → Low
tags: added: bite-size
Zakhar (alainb06) wrote :

Sorry for the bad format of patch file.

You can now apply the file correctly with

$ sudo patch -p0 <patch_curl-config.txt

(Summary comment inside the patch)

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.