Setting up libcurl on Linux - c

I'm trying to use libcurl, but am failing to set it up correctly. I've been reading the documentation for the past hours, but I'm confused and lost. (This is my first time using an external library with C)
Based on these instructions, I've correctly configured and installed libcurl and curl-config. A minimal C program that simply includes <curl/curl.h> compiles; however, when I run any example program (say, chkspeed.c), I get the following "undefined" errors.
/tmp/ccprXNBB.o: In function `main':
chkspeed.c:(.text+0x1bf): undefined reference to `curl_version'
chkspeed.c:(.text+0x408): undefined reference to `curl_global_init'
chkspeed.c:(.text+0x40d): undefined reference to `curl_easy_init'
chkspeed.c:(.text+0x432): undefined reference to `curl_easy_setopt'
chkspeed.c:(.text+0x454): undefined reference to `curl_easy_setopt'
chkspeed.c:(.text+0x476): undefined reference to `curl_easy_setopt'
chkspeed.c:(.text+0x482): undefined reference to `curl_easy_perform'
chkspeed.c:(.text+0x4b0): undefined reference to `curl_easy_getinfo'
chkspeed.c:(.text+0x50b): undefined reference to `curl_easy_getinfo'
chkspeed.c:(.text+0x566): undefined reference to `curl_easy_getinfo'
chkspeed.c:(.text+0x5c9): undefined reference to `curl_easy_getinfo'
chkspeed.c:(.text+0x624): undefined reference to `curl_easy_getinfo'
chkspeed.c:(.text+0x66a): undefined reference to `curl_easy_strerror'
chkspeed.c:(.text+0x696): undefined reference to `curl_easy_cleanup'
chkspeed.c:(.text+0x69b): undefined reference to `curl_global_cleanup'
collect2: error: ld returned 1 exit status
The following is my output for the three curl-config flags featured in this guide. I'm not sure how to use this information:
$: curl-config --cflags
-I/usr/local/include
$: curl-config --libs
-L/usr/local/lib -lcurl
$: curl-config --feature
IPv6
UnixSockets
libz
AsynchDNS
I would really appreciate any help that might get me in the right direction, if not solve the issue. Thank you for your time!

You should compile it like this:
$ gcc chkspeed.c -o chkspeed $(curl-config --cflags) $(curl-config --libs)
so that the gcc command can have the proper CFLAGS and LDFLAGS for compiling and linking against libcurl.
Note when working with a shell (like bash) and you execute a command like this:
$ cmd1 arg1 arg2 $(cmd2 arg3)
the shell will evaluate first cmd arg3 by executing it and using the stdout output of cmd2 as an argument of for cmd1. Let's say that cmd2 arg3 prints (on stdout) hello, then the shell will execute cmd1 arg1 arg2 hello.
So
$ gcc chkspeed.c -o chkspeed $(curl-config --cflags) $(curl-config --libs)
will be executed as
$ gcc chkspeed.c -o chkspeed -I/usr/local/include -L/usr/local/lib -lcurl
because the output of curl-config --cflags is -I/usr/local/include and the output of curl-config --libs is -L/usr/local/lib -lcurl.

Related

GCC gives undefined reference when using pkg-config to link with the XCB library

I'm following an X11 programming tutorial from here. The page gives 2 commands that can be used to compile an XCB-based program:
gcc -Wall prog.c -o prog `pkg-config --cflags --libs xcb`
and
gcc -Wall prog.c -lxcb
Now, I've tried both. The first one says gcc: error: unrecognized command-line option ‘--cflags’. Apparently this is a shell related problem (As I've seen here). So I tried bash. And this gives a different error:
/usr/bin/ld: /tmp/ccnURTF3.o: in function `useXlib':
example.c:(.text+0xd6): undefined reference to `XInternAtom'
/usr/bin/ld: /tmp/ccnURTF3.o: in function `useXlibProperly':
example.c:(.text+0x163): undefined reference to `XInternAtoms'
/usr/bin/ld: /tmp/ccnURTF3.o: in function `main':
example.c:(.text+0x4b1): undefined reference to `XOpenDisplay'
/usr/bin/ld: example.c:(.text+0x559): undefined reference to `XCloseDisplay'
collect2: error: ld returned 1 exit status
This is the same as what I get with gcc -Wall prog.c -lxcb. So I guess bash fixed the problem but there are 2. And in Atom, when you hover over a function, it shows you which header it is from. But in this one I didnt't get anything.
Thanks in advance
Looks like over the years the libraries got splitted and the function declarations were moved to a different library. And now xcb depends on X11 or something like that or maybe pkg-config --libs xcb should output -lX11, no idea. Anyway, the following works:
gcc -Wall 1.c -lxcb -lX11
or the following works too:
gcc -Wall 1.c $(pkg-config --cflags --libs xcb) $(pkg-config --cflags --libs x11)
Would be nice to ping the maintainer of that introduction to let him know he should update the page.

How to use dialog.h in a c program

I am trying to use dialog.hin my C program. For this I looked up the manual (man 3 dialog) and used the example code, which they have provided. This is how my C program look like (it is called main.c):
#include <dialog.h>
int main(void)
{
int status;
init_dialog(stdin, stdout);
status = dialog_yesno(
"Hello, in dialog-format",
"Hello World!",
0, 0);
end_dialog();
return status;
}
After research I figured out, that the dialog program is based on ncurses. So I have installed both libraries, which contains the required header files.
I am working on Debian so:
apt install dialog libncurses5-dev libncursesw5-dev
In the next step I have called the compiler, and I have also linked the libraries: gcc main.c -ldialog -lncurses
But compiling did not succeed.
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(util.o): In function `dlg_auto_size':
(.text+0x1a06): undefined reference to `sqrt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(trace.o): In function `dlg_trace_win':
(.text+0x29c): undefined reference to `win_wch'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(trace.o): In function `dlg_trace_win':
(.text+0x2ab): undefined reference to `wunctrl'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_arrows2':
(.text+0x2c4): undefined reference to `_nc_wacs'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_arrows2':
(.text+0x2d6): undefined reference to `wadd_wch'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_arrows2':
(.text+0x43c): undefined reference to `_nc_wacs'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_arrows2':
(.text+0x44e): undefined reference to `wadd_wch'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_scrollbar':
(.text+0x878): undefined reference to `_nc_wacs'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(arrows.o): In function `dlg_draw_scrollbar':
(.text+0x88f): undefined reference to `wvline_set'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(inputstr.o): In function `dlg_index_columns':
(.text+0x932): undefined reference to `setcchar'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(inputstr.o): In function `dlg_index_columns':
(.text+0x93c): undefined reference to `wunctrl'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libdialog.a(ui_getc.o): In function `dlg_getc':
(.text+0x603): undefined reference to `wget_wch'
collect2: error: ld returned 1 exit status
After research I found out that the missing references to some functions like win_wch, wunctrl, etc. are all defined in curses.h.
Regarding to this post (What's the difference between -lcurses and -lncurses when compiling C using ncurses lib?) ncurses and curses are the same due curses is linked to ncurses.
But anyway, I have tried to compile with the curses library too: gcc main.c -lcurses -lncurses -ldialog. But it did not work either.
What am I missing? Why did compiling fail?
I did some testing on a Debian-based system (a Beaglebone), and this was not an obvious fix. Turns out there are multiple versions of the ncurses library, and the dialog library was built with one of them, just not the one you were using.
The way you're supposed to figure this out is with the dialog-config command, which has options to show which CFLAGS or libraries you need on the compile line (or in the makefile), but I didn't find it on my system, so I looked at /usr/include/dlg_config.h for some clues:
...
#define DLG_HAVE_LIBINTL_H 1
#define DLG_HAVE_LIBNCURSESW 1 <---
#define DLG_HAVE_LIMITS_H 1
Hmmm, this suggests it needs -lncursesw instead of -lncurses, so we see this compile:
$ gcc dlg.c -ldialog -lncursesw
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabihf/8/../../../arm-linux-gnueabihf/libdialog.a(util.o): in function `dlg_auto_size':
(.text+0x13d2): undefined reference to `sqrt'
Ok, so a lot closer: sqrt() is in the math library, so adding -lm gets it over the goal line:
$ gcc dlg.c -ldialog -lncursesw -lm
It seems that ncursesw is a wide-character version that works with an international character set, which was new to me.
EDIT: Elaborating on the "dialog-config" stuff: The way you're supposed to do this is documented in the dialog(3) manual page:
gcc $(dialog-config --cflags) file ... $(dialog-config --libs)
The idea is that a package can publish what it needs to build in a command, so in this case I imagine that dialog-config --cflags might not output anything, but dialog-config --libs would output -ldialog -lncursesw -lm, so you could embed this in your makefile and have it do the right thing.
This paradigm is common, and on my system I see (for example) /usr/bin/python-config that shows how it was built on this machine:
$ python-config --cflags
-I/usr/include/python2.7 -I/usr/include/arm-linux-gnueabihf/python2.7
-fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g
-fdebug-prefix-map=/build/python2.7-RT6aMn/python2.7-2.7.16=.
-fstack-protector-strong -Wformat -Werror=format-security -DNDEBUG
-g -fwrapv -O2 -Wall -Wstrict-prototypes
$ python-config --libs
-lpython2.7 -lpthread -ldl -lutil -lm
If you were trying to build some kind of Python plugin, guessing the above parameters would be a real challenge.

C program using net-snmp does not compile

I have installed net-snmp 5.8 on a Ubuntu 16.0.4 machine and then I have checked the correct installation:
snmpget --version
NET-SNMP version: 5.8
Next, I am trying to write and compile my first SNMP C program example.
I have copied the one that is included as example on the tutorial from Ben Rockwood ("The Net-SNMP Programming Guide) and I have tried to compile it with the command:
gcc ‘net-snmp-config --cflags‘ ‘net-snmp-config --libs‘ \
> ‘net-snmp-config --external-libs‘ snmp_test.c -o snmp_test
As indicated in this tutorial.
When do, I get the errors:
gcc: error: unrecognized command line option ‘--cflags‘’
gcc: error: unrecognized command line option ‘--libs‘’
gcc: error: unrecognized command line option ‘--external-libs‘’
Then I have changed the gcc command to:
gcc net-snmp-config --cflags net-snmp-config --libs \
net-snmp-config --external-libs snmp_test.c -o snmp_test
And get the error:
bash: net-snmp-config --external-libs: ambiguous redirect
What is wrong on the gcc call? Any comments or suggestions are welcome.
You are probably using the wrong ticks. Use this method for command substitution, it is a bit safer:
gcc $(net-snmp-config --cflags) $(net-snmp-config --libs) $(net-snmp-config --external-libs) snmp_test.c -o snmp_test
The ticks you show here (‘) are the wrong ones, the ones you need are these: ` . However, I prefer the $() syntax, which has the additional advantage, that it is nestable.
I have tryied the command you tell me:
gcc $(net-snmp-config --cflags) $(net-snmp-config --libs) $(net-snmp-config --external-libs) snmp_test.c -o snmp_test
And I get these errors:
/tmp/ccKrUliA.o: In function `main':
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:29: undefined reference to `init_snmp'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:31: undefined reference to `snmp_sess_init'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:36: undefined reference to `snmp_open'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:38: undefined reference to `add_mibdir'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:39: undefined reference to `read_mib'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:40: undefined reference to `snmp_pdu_create'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:42: undefined reference to `read_objid'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:43: undefined reference to `snmp_add_null_var'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:45: undefined reference to `read_objid'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:46: undefined reference to `snmp_add_null_var'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:48: undefined reference to `snmp_synch_response'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:51: undefined reference to `print_value'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:53: undefined reference to `snmp_free_pdu'
/home/jose/NETWORK_PROTOCOLS/ej_02_SNMP/snmp_test.c:54: undefined reference to `snmp_close'
collect2: error: ld returned 1 exit status
Then I have tried to add -L and -lsnmp, with this result:
jose#jose-VirtualBox:~/NETWORK_PROTOCOLS/ej_02_SNMP$ gcc -L/usr/locallib/ -lsnmp $(net-snmp-config --cflags) $(net-snmp-config --libs) $(net-snmp-config --external-libs) snmp_test.c -o snmp_test
/usr/bin/ld: cannot find -lsnmp
collect2: error: ld returned 1 exit status

Error while compiling PortAudio examples

(I am on Ubuntu) I am trying to run the PortAudio examples, but getting many errors (mentioned below). I have placed the header file portaudio.h in the directory of the program. I have no idea about it. I think it is linker error. Please help!
/tmp/cc5EbTlT.o: In function main':
paex_record.c:(.text+0x37e): undefined reference toPa_Initialize'
paex_record.c:(.text+0x397): undefined reference to Pa_GetDefaultInputDevice'
paex_record.c:(.text+0x3de): undefined reference toPa_GetDeviceInfo'
paex_record.c:(.text+0x436): undefined reference to Pa_OpenStream'
paex_record.c:(.text+0x45a): undefined reference toPa_StartStream'
paex_record.c:(.text+0x493): undefined reference to Pa_Sleep'
paex_record.c:(.text+0x4c2): undefined reference toPa_IsStreamActive'
paex_record.c:(.text+0x4eb): undefined reference to Pa_CloseStream'
paex_record.c:(.text+0x5fa): undefined reference toPa_GetDefaultOutputDevice'
paex_record.c:(.text+0x641): undefined reference to Pa_GetDeviceInfo'
paex_record.c:(.text+0x6b2): undefined reference toPa_OpenStream'
paex_record.c:(.text+0x6e3): undefined reference to Pa_StartStream'
paex_record.c:(.text+0x71c): undefined reference toPa_Sleep'
paex_record.c:(.text+0x728): undefined reference to Pa_IsStreamActive'
paex_record.c:(.text+0x74e): undefined reference toPa_CloseStream'
paex_record.c:(.text+0x77d): undefined reference to Pa_Terminate'
paex_record.c:(.text+0x7e5): undefined reference toPa_GetErrorText'
collect2: error: ld returned 1 exit status
Assuming you are compiling using gcc and you have a single C file foo.c, the compiler command would be
gcc -o foo foo.c -lrt -lasound -ljack -lpthread -lportaudio
The -l parameters are there to link the required libraries to your program, e.g. -lrt will link librt.a. The order does matter.
I got the required libraries from here: http://www.portaudio.com/docs/v19-doxydocs/compile_linux.html#comp_linux3. Don't know if they are correct. At least you need -lportaudio, obviously.
If the libraries are not found, you have to provide gcc a path, e.g.
gcc -L/usr/lib -o foo foo.c -lrt -lasound -ljack -lpthread -lportaudio
Regarding the header, you don't actually need to copy it into your program's directory. You'd rather include it as
#include <portaudio.h>
and add its directory to the include search path:
gcc -I/usr/include -L/usr/lib -o foo foo.c -lrt -lasound -ljack -lpthread -lportaudio
Of course, all this is better done in a Makefile.

Compiling an allegro5 program using make

I have a program called zone.c that uses the allegro5 library.
I have a makefile that consists of just these two lines.
zone: zone.c
gcc zone.c -o zone $(pkg-config --cflags --libs allegro-5.0 allegro_primitives-5.0)
when I type "make" I get these errors:
/tmp/ccyCx3Hy.o: In function main':
zone.c:(.text+0x14): undefined reference toal_install_system'
zone.c:(.text+0x23): undefined reference to al_create_display'
zone.c:(.text+0x3b): undefined reference toal_map_rgb'
zone.c:(.text+0x70): undefined reference to al_clear_to_color'
zone.c:(.text+0x84): undefined reference toal_map_rgb'
zone.c:(.text+0xd1): undefined reference to al_draw_filled_circle'
zone.c:(.text+0xe5): undefined reference toal_map_rgb'
zone.c:(.text+0x132): undefined reference to al_draw_filled_circle'
zone.c:(.text+0x137): undefined reference toal_flip_display'
zone.c:(.text+0x14f): undefined reference to al_rest'
zone.c:(.text+0x15b): undefined reference toal_destroy_display'
collect2: error: ld returned 1 exit status
make: * [zone] Error 1
But if I just copy out the line "gcc zone.c -o zone $(pkg-config --cflags --libs allegro-5.0 allegro_primitives-5.0)" and run it manually, it compiles fine and the program works.
If I use similar makefiles to compile programmes that don't use allegro5, then make works.
Does anybody have a clue what's going on?
If you want a literal $ in your rule, you have to escape it from make by writing $$ instead:
zone: zone.c
gcc zone.c -o zone $$(pkg-config --cflags --libs allegro-5.0 allegro_primitives-5.0)

Resources