C C Programming with libcurl

Its been a while since I last posted here. I had a question about some code I was recently trying to run:

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

int main(void)
{
  CURL *curl;
  FILE *fp;
  CURLcode res;
  char *url = "http://teamsloth.net/index.html";
  char outfilename[FILENAME_MAX] = "page.html";
  curl = curl_easy_init();  
  if (curl)
  {  
  fp = fopen(outfilename,"wb");
  curl_easy_setopt(curl, CURLOPT_URL, url);
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
  res = curl_easy_perform(curl);
  curl_easy_cleanup(curl);
  fclose(fp);
  }  
  return 0;
}

This failed to compile and from searching online I found I needed to 'make install clean' in /usr/ports/ftp/curl. I did this, but experienced the same error:

Code:
$ cc curlit.c -o curlit 
curlit.c:2:10: fatal error: 'curl/curl.h' file not found
#include <curl/curl.h>
  ^
1 error generated.

Did some more digging and found I needed to call /usr/local/include/ at compile time, but received this:

Code:
 $ cc -v curlit.c -o curlit -I/usr/local/include/
FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM 3.8.0)
Target: x86_64-unknown-freebsd11.0
Thread model: posix
InstalledDir: /usr/bin
 "/usr/bin/cc" -cc1 -triple x86_64-unknown-freebsd11.0 -emit-obj -mrelax-all -disable-free -main-file-name curlit.c -mrelocation-model static -mthread-model posix -mdisable-fp-elim -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -v -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/bin/../lib/clang/3.8.0 -I /usr/local/include/ -fdebug-compilation-dir /usr/home/ph33r -ferror-limit 19 -fmessage-length 159 -fobjc-runtime=gnustep -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/curlit-23a77e.o -x c curlit.c
clang -cc1 version 3.8.0 based upon LLVM 3.8.0 default target x86_64-unknown-freebsd11.0
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/bin/../lib/clang/3.8.0/include
 /usr/include
End of search list.
 "/usr/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --hash-style=both --enable-new-dtags -o curlit /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /tmp/curlit-23a77e.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
/tmp/curlit-23a77e.o: In function `main':
curlit.c:(.text+0x41): undefined reference to `curl_easy_init'
curlit.c:(.text+0x7e): undefined reference to `curl_easy_setopt'
curlit.c:(.text+0x98): undefined reference to `curl_easy_setopt'
curlit.c:(.text+0xb2): undefined reference to `curl_easy_setopt'
curlit.c:(.text+0xc1): undefined reference to `curl_easy_perform'
curlit.c:(.text+0xcd): undefined reference to `curl_easy_cleanup'
cc: error: linker command failed with exit code 1 (use -v to see invocation)

I don't know if there's something else I need to link or install or if the following just isn't defined in the libcurl version of FreeBSD:

Code:
curlit.c:(.text+0x41): undefined reference to `curl_easy_init'
curlit.c:(.text+0x7e): undefined reference to `curl_easy_setopt'
curlit.c:(.text+0x98): undefined reference to `curl_easy_setopt'
curlit.c:(.text+0xb2): undefined reference to `curl_easy_setopt'
curlit.c:(.text+0xc1): undefined reference to `curl_easy_perform'
curlit.c:(.text+0xcd): undefined reference to `curl_easy_cleanup'

Any thoughts well appreciated.
 
I don't know if there's something else I need to link or install or if the following just isn't defined in the libcurl version of FreeBSD:
You get these undefined references because you didn't link with libcurl.
Any thoughts well appreciated.
Most libraries provide a pkg-config file which outputs the necessary parameters to compile and link code against them. Check pkg-config --cflags --libs libcurl to see what's needed on your system. pkg-config is provided by devel/pkgconf.

You can embed that in your compiler invocation like cc `pkg-config --cflags --libs libcurl` curlit.c -o curlit
 
It looks like you are simply not linking libcurl into the binary. -L/usr/local/lib -lcurl should do the trick, probably.

Are you sure that C is really your best choice for whatever it is you are wanting to do? Your example might much easier to implement and maintain as a simple script (actually, barely a script, as you can just use the standard /usr/local/bin/curl binary directly), or perhaps you should consider Perl or Python. Just a thought. I've been a C coder since sometime in the 1980s, and it wouldn't necessarily be my first choice for such a thing. Of course, it all depends on what your big picture is here.
 
This didn't work:

Code:
cc curlit.c -o curlit -L/usr/local/lib -lcurl
curlit.c:2:10: fatal error: 'curl/curl.h' file not found
#include <curl/curl.h>
  ^
1 error generated.

However, this did after installing devel/pkgconf as suggested:

Code:
$ cc `pkg-config --cflags --libs libcurl` curlit.c -o curlit


Murph - If my only goal was to download a single file, you would be correct. This could probably be done with one line in a shell script. However, I plan to add a lot more to this code in the near future. As later parts of the code will need to be in C, I wish to keep it all the same language.

Thank you both for the suggestions!
 
This didn't work:

Code:
cc curlit.c -o curlit -L/usr/local/lib -lcurl
curlit.c:2:10: fatal error: 'curl/curl.h' file not found
#include <curl/curl.h>
  ^
1 error generated.

Ahh, sorry, I wasn't entirely clear. I meant you to add that, not replace the -I... with it. I.e. -I/usr/local/include -L/usr/local/lib -lcurl, which is exactly what you are getting from pkg-config(8) anyway. Stick with that method, it's the more modern way of doing things (rather than using the raw parameters).

Murph - If my only goal was to download a single file, you would be correct. This could probably be done with one line in a shell script. However, I plan to add a lot more to this code in the near future. As later parts of the code will need to be in C, I wish to keep it all the same language.

Fair enough. If C is a good choice for the majority of the code, and this is just one tiny component, it's reasonable to choose it. My overall point is basically that C is fantastic and I love it, but it's always a case of trying to pick the overall best tools for each job; sometimes that's C, other times it should be Perl/Python/etc. One random thought for you, if memory management starts to become a pain for you in C, Objective-C/ObjC is an interesting alternative with all the low level power of C but easy automatic memory management where you need it. Learning ObjC is also extremely useful for developing things for the various Apple environments.
 
Back
Top