1

I'm trying to build curl library sample program that downloads file from ftp. I'm using Eclipse IDE , OS -Ubuntu.

I have installed curl using command: apt-get install libcurl4-gnutls-dev

I see heades files in /usr/include/curl (I don't know where are c files)

Looks Eclipse is happy with #include <curl/curl.h> , bu all curl functions used in program are maked with 'undefined reference'.

Compilation failes with linking errors:

**** Build of configuration Debug for project updDown ****

make all 
Building target: updDown
Invoking: GCC C Linker
gcc  -o "updDown"  ./src/updDown.o   
./src/updDown.o: In function `main':
/home/g/proj/updDown/Debug/../src/updDown.c:45: undefined reference to `curl_global_init'
/home/g/proj/updDown/Debug/../src/updDown.c:47: undefined reference to `curl_easy_init'
/home/g/proj/updDown/Debug/../src/updDown.c:52: undefined reference to `curl_easy_setopt'
/home/g/proj/updDown/Debug/../src/updDown.c:55: undefined reference to `curl_easy_setopt'
/home/g/proj/updDown/Debug/../src/updDown.c:57: undefined reference to `curl_easy_setopt'
/home/g/proj/updDown/Debug/../src/updDown.c:60: undefined reference to `curl_easy_setopt'
/home/g/proj/updDown/Debug/../src/updDown.c:62: undefined reference to `curl_easy_perform'
/home/g/proj/updDown/Debug/../src/updDown.c:65: undefined reference to `curl_easy_cleanup'
/home/g/proj/updDown/Debug/../src/updDown.c:76: undefined reference to `curl_global_cleanup'
collect2: error: ld returned 1 exit status
make: *** [updDown] Error 1

**** Build Finished ****

How to solve this problem?

Hwole code:

/*
 ============================================================================
 Name        : updDown.c
 Author      : 
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

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

struct FtpFile {
  const char *filename;
  FILE *stream;
};

static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
  struct FtpFile *out=(struct FtpFile *)stream;
  if(out && !out->stream) {
    /* open file for writing */
    out->stream=fopen(out->filename, "wb");
    if(!out->stream)
      return -1; /* failure, can't open file to write */
  }
  return fwrite(buffer, size, nmemb, out->stream);
}


int main(void)
{

    puts("starting");

  CURL *curl;
  CURLcode res;
  struct FtpFile ftpfile={
    "curl.tar.gz", /* name to store the file as if succesful */
    NULLs
  };

  curl_global_init(CURL_GLOBAL_DEFAULT);

  curl = curl_easy_init();
  if(curl) {
    /*
     * You better replace the URL with one that works!
     */
    curl_easy_setopt(curl, CURLOPT_URL,
                     "ftp://ftp.example.com/pub/www/utilities/curl/curl-7.9.2.tar.gz");
    /* Define our callback to get called when there's data to be written */
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
    /* Set a pointer to our struct to pass to the callback */
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);

    /* Switch on full protocol/debug output */
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

    res = curl_easy_perform(curl);

    /* always cleanup */
    curl_easy_cleanup(curl);

    if(CURLE_OK != res) {
      /* we failed */
      fprintf(stderr, "curl told us %d\n", res);
    }
  }

  if(ftpfile.stream)
    fclose(ftpfile.stream); /* close the local file */

  curl_global_cleanup();

  return 0;
}
vico
  • 17,051
  • 45
  • 159
  • 315
  • Consider using makefiles too https://stackoverflow.com/questions/56047948/compiling-and-linking-curl-easy-interface-with-c/56049124#56049124 – greg May 08 '19 at 21:21

1 Answers1

1

You shall specify the linker option of -lcurl, at the location of C/C++ build -> Settings -> GCC C Linker -> Libraries in project properties.

EDITED:

Let's be more detailed.

I see heades files in /usr/include/curl (I don't know where are c files)

Typically such packages don't consist of source codes, instead they provide pre-compiled object files called libraries.bu all curl functions used in program are maked with 'undefined reference'.

Looks Eclipse is happy with #include

That's true since the path /usr/include/ is typically inside the include path (where the compiler tries to find the header files), so you don't need to setup anything for this.

bu all curl functions used in program are maked with 'undefined reference'.

In the code you use functions like curl_global_init without implementing them yourself, which means those functions are treated as external functions that are expected to be imported. You shall "tell" the linker where to find these functions (to be more exact, these symbols). That's done by using the option -l followed by the library name. And for specifying the paths of libraries, use -L.

For further information, you could see the section of linker options in Option Sammary of GCC

starrify
  • 14,307
  • 5
  • 33
  • 50
  • Exactly. The `undefined reference` error means that the linker has not found the definition of that function anywhere in your code nor in any specified library. – José M. Benítez Nov 25 '13 at 11:59