How do I link libcurl to my c++ program in linux? - c++

I need to use libcurl in a piece of software I am writing on my ubuntu machine. I am using Eclipse to write and compile all of the software. When I put the libcurl files in the same folder as the .cpp file, and include the curl.h file in the header, When I attempt to compile the program, It comes up with these errors:
Building target: sms
Invoking: GCC C++ Linker
g++ -o"sms" ./src/sms.o
./src/sms.o: In function `main':
/home/geekman/workspace/sms/Debug/../src/sms.cpp:38: undefined reference to `curl_easy_init'
/home/geekman/workspace/sms/Debug/../src/sms.cpp:42: undefined reference to `curl_easy_setopt'
/home/geekman/workspace/sms/Debug/../src/sms.cpp:44: undefined reference to `curl_easy_setopt'
/home/geekman/workspace/sms/Debug/../src/sms.cpp:46: undefined reference to `curl_easy_perform'
/home/geekman/workspace/sms/Debug/../src/sms.cpp:47: undefined reference to `curl_easy_cleanup'
collect2: ld returned 1 exit status
make: *** [sms] Error 1
I took the contents of the include folder from libcurl, and placed them in the same folder as the .cpp file. then in the header of the .cpp file, I typed:
#include <curl/curl.h>
I also tried:
#include "curl/curl.h"
Any ideas on the problem? Thanks.

Your header file inclusions are just fine; your problem is occurring at the linking step. In order to link against libcurl, you need to add the -lcurl command line option, assuming it's installed in a standard directory:
g++ -o sms ./src/sms.o -lcurl
If it's not installed in a standard directory, you also need to add the -L/path/to/libcurl, e.g. something like:
# Assuming that /home/geekman/workspace/libcurl is where libcurl.a is located
g++ -o sms ./src/sms.o -L/home/geekman/workspace/libcurl -lcurl
Also note that the -lcurl option has to appear after the list of object files you're linking, otherwise it won't link properly.

You can try to use curl-config --libs.

An alternate answer (the first one is excellent). Consider using the output returned by "pkg-config --libs libcurl" as an argument to your compiler.
For example,
CPPFLAGS=`pkg-config --libs libcurl`
g++ $CPPFLAGS myfile.o
Pkg-config is a standard way for open source libraries to communicate to you how to link against them / #include their files.

Anyone who is using ecplise CDT then you need to do following. First on terminal enter
curl-config --libs
On my machine, the result is
-L/usr/lib/i386-linux-gnu -lcurl
then do according to this screenshot and you will be able to compile. btw don't forget to add header files in your code
So you enter library folder path without -L and library name without -l because they will be automatically added by linker.

You have to link the library to your program. With gcc (and most other compilers) you can specify the libraries to link with -lname_wo_lib, e.g. -lcurl

Also see GNU GCC Manual - Options for Linking for a detailed explanation of the options Adam Rosenfield said. For standard search directories, see An Introduction to GCC - for the GNU Compilers gcc and g++ - Setting Search Paths.

In addition to the first answer, I had to link the curlpp library too. So to compile the main.cpp file which included the curlpp I had to do:
g++ main.cpp -lcurl -lcurlpp
Using only one of the two links would return different errors regarding different links. It is important to remind that this only worked because I had installed all the necessary libraries in the standard include folders

Related

"multiple definition of `atexit'" when linking with DLL

I use MinGW32 more specifically TDM-GCC-32. I have very simple project I link to one custom library but this error pops out:
>g++ -D_WIN32 -D_MINGW -lgdi32 -lgdiplus -Linterception/x86 -linterception main.cpp -o interceptor.exe
interception/x86/libinterception.a(dgnes00125.o):(.text+0x0): multiple definitio
n of `atexit'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../crt2.o:crt1.c:(.text+0x2c0):
first defined here
interception/x86/libinterception.a(dgnes00109.o):(.text+0x0): multiple definitio
n of `_onexit'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../crt2.o:crt1.c:(.text+0x2d0):
first defined here
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../../mingw32/bin/ld.exe: C:/TD
M-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../crt2.o: bad reloc address 0x20 in
section `.eh_frame'
collect2.exe: error: ld returned 1 exit status
Commands I use to build the library:
gcc -DINTERCEPTION_EXPORT -D_WIN32 -D_MINGW -shared -o interception.dll interception.c
dlltool -z interception.def --export-all-symbol interception.dll
dlltool -d interception.def -l libinterception.a
I guess I have to use different options for compiling the library to avoid redefinitions..
The dlltool method I believe is currently deprecated. I can't fault you here though, as most of the available documentation still says to do it this way.
Gcc will link directly against .dll files, making .a files obsolete (at least for dealing with dll's - the only current reason to use a .a file is for static linking). You don't even have to specify the dll with the -l flag, although you have to specify the path of the dll if it's not in your current directory
C:\Users\burito>gcc main.o opengl32.dll -o main.exe
gcc: error: opengl32.dll: No such file or directory
C:\Users\burito>gcc main.o c:\Windows\system32\opengl32.dll -o main.exe
C:\Users\burito>
Ok, opengl32.dll is perhaps not a great example, but I hope I've given you the general idea.
I believe MSVC still needs its .lib files to use a .dll, for which there are several ways of making them if the library doesn't come with one.
In your specific case, the command that should work would be...
g++ -D_WIN32 -D_MINGW -lgdi32 -lgdiplus interception/x86/interception.dll main.cpp -o interceptor.exe
If for whatever reason you really do need to create a .a file from a .dll, the command that has worked for me is...
gendef interception.dll
dlltool -l interception.a -d interception.def -k -A
As the repository you linked does provide .dll files in its releases, you shouldn't have to build them yourself

Libquantum code Understanding Makefile

I tried to run .c file called grover.c in this C application libquantum
www.libquantum.de/files/libquantum-1.1.1.tar.gz
Now I this application already contains a Makefile.in and I can generate the executables called shor and grover using the command
./configure
make
make demos
But when I try to run grover.c using gcc or clan like this
clang grover.c
It gives me error of lots of undefined function reference.
In function oracle':
grover.c:(.text+0x50): undefined reference toquantum_sigma_x'
grover.c:(.text+0x89): undefined reference to quantum_toffoli'
grover.c:(.text+0xc8): undefined reference toquantum_toffoli'
grover.c:(.text+0xf2): undefined reference to quantum_cnot'
grover.c:(.text+0x137): undefined reference toquantum_toffoli'
grover.c:(.text+0x16b): undefined reference to quantum_toffoli'
grover.c:(.text+0x1b0): undefined reference toquantum_sigma_x'
I need to know how can I remove this error and if I can run this c code called grover.c in this application.
Thanks,
It looks like your compiler can not find one or more libraries to link to. My hunch is that the makefile has the appropriate commands to invoke the linker.
If you look at your makefile, you probably will see some commands like -L -l,
when the flag -L add a directory to the default search path for libraries and the flag -l is used to name the library to link.
for example -L/lib/openGL -lglut32 would cause the library libglut32.so.X.Y.Z which is found in the directory /lib/openGL. (not this is for a Linux system, but it should be fairly similar for Mac).
N.B. X.Y.Z are the version number of the library.
Once you work this out, there may be issues with the load finding the libraries, especially if they are in non-standard locations.
------------------------ edit --------------------------
After I posted this, and went to bed I realized that I missed a potential case (and thanks to Paul Griffiths for also noticing my omission.....teach me to do multiple things at once).
Any how, just compiling a simple file, say hello.c, as clang hello.c -o hello works because everything is in one file and clang will automatically link to the C run-time library.
If, in your case the code is spread across multiple files, say grover.c and file1.c you would need to do:
clang -c grover.c -o grover.o
clang -c file1.c -o file1.o
clang grover.o file1.o -o grover
(or alteratively clang grover.c file1.c -o grover)
SO what the first two lines are doing is translating the source-code files (grover.c and file1.c) into object files. THe third line covers the two object files into an executable.
Finally, both these cases can be involved. You could have multiple files as well as missing libraries.

Cannot find .dll using MinGW and MSYS

OS: Windows 7
I have the source, as well as all the library files I'm using in one directory, on my desktop. I'm running the shell by using msys.bat, which was created when I installed MinGW. I've tried to run the following (and many others):
g++ -I. -L. -o opengltest.exe opengltest.cpp -lglew32 -lglew32s -lglew32.dll
I recieve the following error:
c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/ld.exe: cannot find -lglew32.dll
collect2: ld returned 1 exit status
This also happens when I use the -L switch and the entire C:/Users/... path, but I get the same error. Again, glew32.dll is in the same directory that the .cpp is in, which is the same directory I'm working in within the shell. I've tried multiple solutions from multiple posts, and it still seems like I'm missing something. I thought using the -L. was a straightforward way to tell MinGW to look in the working directory, but apparently it doesn't work that way.
Do not link against both the dynamic and static linking version of glew in the same application. This makes no sense. Also do no link against glew32.dll, this makes equally little sense.
Most importantly, do not use the DLL version of glew with g++ at all - it will not work (see one of my previous answers to understand why). Instead, #define GLEW_STATIC (better if you use -DGLEW_STATIC as a compiler switch) and only link to glew32s.

boost test - 'undefined reference' errors

I have two simple files:
runner.cpp:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Main
#include <boost/test/unit_test.hpp>
and test1.cpp:
#define BOOST_TEST_DYN_LINK
#ifdef STAND_ALONE
# define BOOST_TEST_MODULE Main
#endif
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE( Foo)
BOOST_AUTO_TEST_CASE( TestSomething )
{
BOOST_CHECK( true );
}
BOOST_AUTO_TEST_SUITE_END()
To compile, I'm using:
$ g++ -I/e/code/boost_1_52_0 -o runner -lboost_unit_test_framework runner.cpp test1.cpp
I get the following error:
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text+0x8c): multiple definition of `main'
c:/pdev/mingw/bin/../lib/gcc/i686-pc-mingw32/4.7.2/../../../libboost_unit_test_framework.a(unit_test_main.o):unit_test_main.cpp:(.text.startup+0x0): first defined here
c:/pdev/mingw/bin/../lib/gcc/i686-pc-mingw32/4.7.2/../../../libboost_unit_test_framework.a(unit_test_main.o):unit_test_main.cpp:(.text.startup+0x14): undefined reference to `init_unit_test_suite(int, char**)'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text+0x52): undefined reference to `_imp___ZN5boost9unit_test9framework17master_test_suiteEv'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text+0xb0): undefined reference to `_imp___ZN5boost9unit_test14unit_test_mainEPFbvEiPPc'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text$_ZN5boost9unit_test13test_observerD2Ev[__ZN5boost9unit_test13test_observerD2Ev]+0xe): undefined reference to `_imp___ZTVN5boost9unit_test13test_observerE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text$_ZN5boost9unit_test13test_observerC2Ev[__ZN5boost9unit_test13test_observerC2Ev]+0xe): undefined reference to `_imp___ZTVN5boost9unit_test13test_observerE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text$_ZN5boost9unit_test15unit_test_log_tC1Ev[__ZN5boost9unit_test15unit_test_log_tC1Ev]+0x22): undefined reference to `_imp___ZTVN5boost9unit_test15unit_test_log_tE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x88): undefined reference to `_imp___ZN5boost9unit_test15unit_test_log_t14set_checkpointENS0_13basic_cstringIKcEEjS4_'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x136): undefined reference to `_imp___ZN5boost10test_tools9tt_detail10check_implERKNS0_16predicate_resultERKNS_9unit_test12lazy_ostreamENS5_13basic_cstringIKcEEjNS1_10tool_levelENS1_10check_typeEjz'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x21d): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24auto_test_unit_registrarC1ENS0_13basic_cstringIKcEE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x284): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24auto_test_unit_registrarC1EPNS0_9test_caseEm'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x2a4): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24auto_test_unit_registrarC1Ei'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text$_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[__ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x1d): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24normalize_test_case_nameENS0_13basic_cstringIKcEE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text$_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[__ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x5b): undefined reference to `_imp___ZN5boost9unit_test9test_caseC1ENS0_13basic_cstringIKcEERKNS0_9callback0INS0_9ut_detail6unusedEEE'
collect2.exe: error: ld returned 1 exit status
I'm using g++ 4.7.2 on MinGW, with boost 1.52.0.
I get the same errors when only trying to compile test1.cpp - except the "multiple main definition" one.
I perused the official documentation for quite a while, but its scarce on details regarding linking options. When I compiled the boost libs, besides unit_test_framework, I also got prg_exec_monitor and test_exec_monitor; perhaps I should link these somehow ? I tried many combinations, but all resulted in some kind of undefined reference linker error.
Complete list of boost generated libraries - I have them all in the project root:
libboost_prg_exec_monitor-mgw47-mt-1_52.a
libboost_prg_exec_monitor-mgw47-mt-1_52.dll
libboost_prg_exec_monitor-mgw47-mt-1_52.dll.a
libboost_prg_exec_monitor-mgw47-mt-d-1_52.a
libboost_prg_exec_monitor-mgw47-mt-d-1_52.dll
libboost_prg_exec_monitor-mgw47-mt-d-1_52.dll.a
libboost_test_exec_monitor-mgw47-mt-1_52.a
libboost_test_exec_monitor-mgw47-mt-d-1_52.a
libboost_unit_test_framework-mgw47-mt-1_52.a
libboost_unit_test_framework-mgw47-mt-1_52.dll
libboost_unit_test_framework-mgw47-mt-1_52.dll.a
libboost_unit_test_framework-mgw47-mt-d-1_52.a
libboost_unit_test_framework-mgw47-mt-d-1_52.dll
libboost_unit_test_framework-mgw47-mt-d-1_52.dll.a
With help from #llonesmiz, a number of issues were identified.
1. Libraries need to be specified after objects and sources which use them.
As described here:
The traditional behavior of linkers is to search for external functions from
left to right in the libraries specified on the command line. This means that a
library containing the definition of a function should appear after any source
files or object files which use it. This includes libraries specified with the
short-cut -l option, as shown in the following command:
$ gcc -Wall calc.c -lm -o calc (correct order)
With some linkers the opposite ordering (placing the -lm option before the file
which uses it) would result in an error,
$ cc -Wall -lm calc.c -o calc (incorrect order)
main.o: In function 'main':
main.o(.text+0xf): undefined reference to 'sqrt'
because there is no library or object file containing sqrt after ‘calc.c’. The
option -lm should appear after the file ‘calc.c’
2. Library paths should be explicitly specified.
If no lib paths are specified, the linker might look for the libs in a series
of default folders, thus loading a different library then intended. This is what
happened in my case - I wanted to link boost_unit_test_framework, but did not
specify a path because I assumed the linker would look in the current folder.
That's what happens at runtime, after all - if the dll is in the same folder
with the exe, it will find it.
I found it a little bit strange the linker would find the lib, since it was
named ibboost_unit_test_framework-mgw47-mt-1_52.dll. When I tried to link to
a non-existing lib, the linker complained though, so I assumed this isn't an
issue, and MinGW 's linker ignores those suffixes.
After some more research, I found this article about MinGW library paths.
The folders MinGW searches for libs can be found in the output of gcc -print-search-dirs.
The article also contains some bash magic to make sense of that output:
gcc -print-search-dirs | sed '/^lib/b 1;d;:1;s,/[^/.][^/]*/\.\./,/,;t 1;s,:[^=]*=,:;,;s,;,; ,g' | tr \; \\012 | grep -v '^ */'
This will print a nice list of those folders. gcc will not, by default,
look in the current directory for libs. I looked in each of them, and found the
lib that was being loaded - libboost_unit_test_framework.a, a static lib.
This brings into light another issue worth mentioning:
3. Static versus dynamic linking
I did not specify whether I want boost_unit_test_framework linked statically or dynamically.
In this case, gcc prefers dynamic linking:
Because of these advantages gcc compiles programs to use shared libraries by
default on most systems, if they are available. Whenever a static library
‘libNAME.a’ would be used for linking with the option -lNAME the compiler
first checks for an alternative shared library with the same name and a ‘.so’
extension.
(so is the extension for dynamic libraries on Unix - on Windows, the equivalent is dll.)
So, what happened is that gcc looked for libboost_unit_test_framework.dll
in all it's default folders, but couldn't find it. Then it looked for
libboost_unit_test_framework.a, and statically linked that. This resulted in
linking errors because the sources have #define BOOST_TEST_DYN_LINK, and
therefore expect to have the lib dynamically linked.
To enforce static or dynamic linking, the -Wl,-Bstatic and -Wl,-Bdynamic
linker options come into play, described here.
If I tell the linker that I want dynamic linking:
$ g++ -I/e/code/boost_1_52_0 runner.cpp test1.cpp -o runner -Wl,Bdynamic -lboost_unit_test_framework
This will fail, because the linker will not be able to find the dll.
4.Summary
The issues were:
libraries where specified before the sources which used them
the lib path wasn't specified
the type of linking wasn't specified
the name of the library was not correct
Final, working command:
$ g++ -I/e/code/boost_1_52_0 -o runner runner.cpp test1.cpp -L. -Wl,-Bdynamic -lboost_unit_test_framework-mgw47-mt-1_52

Building code that uses EVP_* functions in Ubuntu

I am trying to build some code that uses the EVP_* functions in Ubuntu, however when I build, I get the dreaded "undefined reference" errors.
I am using Ubuntu 11.10.
The following line is how I compile:
g++ -lcrypto -lssl *.cpp -o IOService
[...]
crypto.cpp:(.text+0x8): undefined reference to `EVP_md5'
[...]
The cpp files include openssl/evp.h.
I have installed the libssl1.0.0-dbg package, but those libraries get installed in /usr/lib/debug/lib/i386-linux-gnu/ where my linker doesn't seem to find them. I tried softlinking and copying the .so files, to no avail (and I have the feeling this is not the way to go).
ld is a one-pass linker, meaning that you have to add libraries after the object files that use them: g++ *.cpp -o IOService -lcrypto (I think libssl is not needed if all you need is md5)