Error linking with libcurl4-gnutls-dev 7.22.0-3ubuntu4 - bad documentation
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Curl |
Unknown
|
Unknown
|
|||
curl (Ubuntu) |
Triaged
|
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/
$ `curl-config --cc --cflags --libs` -o simple simple.c
/tmp/ccwzHN2E.o: In function `main':
simple.
simple.
simple.
simple.
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("/
[pid 2956] open("/
Compare with the same strace on 10.04 we had:
[pid 2752] stat("/
[pid 2752] open("/
[pid 2752] stat("/
[pid 2752] open("/
[pid 2752] stat("/
[pid 2752] open("/
[pid 2752] stat("/
[pid 2752] open("/
[pid 2752] stat("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
[pid 2752] open("/
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/
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.
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`