How can i compile a project with libqrencode? - c++

I am trying to compile this code but it always gives me "Undefined reference to QRcode_encodeString and QRcode_free". I have done the ./configure, make and make install, no errors where shown. I have no idea what flags i need to use in other to compile it. I'm currently using slackware 3.10 i686. I'm only trying to compile with gcc -Wall main.c. I'm still trying to understand linux libraries and shared objects. Any clue to what might be the problem? My source code is in the same directory as the qrencode.h file. I tried #include and "qrencode.h".

You're forgetting to link with your library.
In other words, the compiler knows what to do with the code (since you're including the header and so on), but the linker does not (since it doesn't "know" where to find the implementation of that --- you need to tell it!).
Add -lqrencode to your compiler flags. If the library is in some directory not searched by default, you also need to add -L/path/to/libdir.
This may be of some help (it gives a few examples for compiling and linking): https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html
One additional node: The linker is already involved in building your program: It links your separate object files (assuming you have multiple *.c files) into one. It also it links with at least libc; however, that library is special in that GCC links it implicitly (that is, you don't have to say -lc), since it's the C standard library.

Related

Locating "undefined" references in a C/C++ Project

I am building a C++ project on my Ubuntu 64bit system using a provided Makefile, and this project also provides an API library for developers.
The compilation was successful, no errors at all, but when I try to include in my files the API libraries provided in the "api" folder, then g++ complains about undefined references.
It is not a problem about dependencies (I already built the project succesfully), in fact the missing references are about classes and functions provided by the project, but they are in some specific (sub-)folders (I don't know which ones!), I guess in some .so files, and g++ is not finding them, probably because it does not know they are in those specific subfolders.
It is not the first time this happens when trying to use APIs from any project, then I think I am missing something or I am doing something wrong in general when trying to use the libraries provided in a project.
In particular, the main problem is that I don't know how to tell the compiler where some classes or data structures are declared, and moreover I don't know how to locate them in order to know where they are.
Usually, a workaround I use to avoid this problem is to run make install (as root or using sudo) so that libraries and APIs are installed in standard folders (like /usr/include or /usr/lib) and if I do this thend I can include the API libraries using #include <library>, but in this last case it didn't work either, because perhaps some required files containing the not found classes/structures are not properly installed in the right folders in the system.
Another workaround I used sometimes is to try to put all the project files in the same folder instead of using the project folder structure, but clearly this is not good! :-)
But I noticed that several other people managed to use the APIs, then apparently they know some way of finding the files containing the "undefined" references and including them in the compilation.
Then my general question is: given a "classic" C++ project based on "Makefile" files and with usual folder names like src, lib, build, bin, etc., if I want to write C++ files using the libraries provided by the project, but the compiler complains about undefined references, how can I find the files (.so or .o or .cpp) containing such references? Is there any tool to find them? And how can I tell the compiler where they are? Should I use some command-line option for g++ or should I use the #include macro in some smart way?
PS I also tried to use the pkc-config linux tool to get right options to use for compilation and they were available, but the compiler still complains about the undefined references.
Some more degails about the project i tried:
For interested people a link to the project is below:
https://github.com/dreal/dreal3
And instructions on how to build it:
http://dreal.github.io/download/
Look into the -rpath linker option - specifically with the "$ORIGIN" argument. That lets you find libraries relative to your executable location so you don't have to install them to the standard locations but just need to put them somewhere known, relative to the executable. That should help you with one piece of the puzzle.
Note: -Wl, can be used to pass arguments to the linker via g++.
As for pointing the compiler/linker at a library so it can resolve undefined references by using that library, use the -l (that's lowercase L) option to specify the library name and -L to specify directories to search for libraries.
As for looking into a library (.so) file to see what symbols are in there, you have a few tools at your disposal: objdump, nm, readelf and objcopy.

How to get clang to link against a library without the "lib" prefix?

My situation is I have a library that doesn't have a "lib" prefix. I'd like to link against it, and I can't recompile it (it's actually a Python module).
Now, if you use the '-l' flag with GCC or clang, then the lib prefix is automatically added and the library is not found. For GCC, I can use '-l:mylib.so' to get it to link against an arbitrary file.
However, this doesn't work for clang. Is it possible to get clang to link against a particular library without the 'lib' prefix?
This answers the question, but from a somewhat different angle. See the related question C++ 11 code compiles with `clang++`, but not with `clang -x c++`.
The gcc documention states:
Object files are distinguished from libraries by the linker according to the file contents.
This does not work if you use clang++ -x c++. Instead, the library file is taken as a C++ source file, and this generates a million or so compile errors. And you can't put the library file before the -x c++, because the needed symbols won't be linked in.
One obvious solution is to rename your source files to have a .cpp extension, so the -x switch is unnecessary (or use symbolic links). But this might be a pain to add to your build system.
Another solution, directly related to the OP's question, is to specify the library via the flags:
-L. -l:mylib.foo
If the library is not in the local directory, change the dot . accordingly.

CURL is in /usr/include but still won't automatically be found by g++

Every time I want to use CURL in one of my C++ programs, I have to add the flag -lcurl as a flag onto g++. This can be especially annoying when working with Eclipse. If /usr/include/curl/curl.h exists, what do I need to do to have CURL always be within the include path for g++?
tl;dr: you have to add the flag.
The linker needs libcurl, not the compiler. The compiler needs the header; the linker needs the lib.
To simplify things quite a bit, the header file tells the compiler that the declarations will be defined later. libcurl is what actually defines them.
The linker does not guess-and-check what to link against (doing so would be a horrible idea). You must explicitly tell it what to link against (except for the default libs). In particular, the linker has to know to use libcurl to find the declarations that curl.h laid out. Without libcurl, the linker is missing functions and thus cannot produce a complete binary.
I'm not familiar with Eclipse, but I'm nearly positive that it has an option where you can specify additional libraries. Yes, you'll have to do that once per project, but that shouldn't be a major overhead.
Try adding curl path in
Properties -> C/C++ General -> Paths and Symbols:
This is just how linking works in C and C++.
When you compile the program, you include the header file /usr/include/curl/curl.h. The compiler does this part. The header file contains all of the definitions for the library interface.
When you link the program, you link in the library /usr/lib/libcurl.so, or whatever it happens to be named. The linker does this part. The library contains the implementation in either a loadable (for dynamic libraries) or linkable (for static libraries) format.
The C and C++ languages have no way of specifying which libraries should be linked in, so you have to pass -lcurl to the linker. This is just the way it is.
There are some extensions to C and C++ that allow you to encode library dependencies in your source code, e.g., #pragma comment with MSC, but they're not supported by your typical ELF toolchain, as far as I know.
Note: Actually, the -lcurl flag is not for g++, but it is for the linker, ld. When you pass -lcurl to g++, g++ passes it through to the linker.

Which libraries do I need to link against with MinGW for an object file built with Clang?

I'm using an object file built with Clang. But no matter what library arguments I pass to ld.exe, it seems to always spit back unresolved references, stuff like memcpy, Standard library, stuff, and implementation stuff like _cxa_atexit.
What libraries (and in what order?) do I need to pass to the MinGW linker to get it to link my object file into an executable?
Edit:
I changed the triple from "i686-pc-mingw" to "i686-pc-mingw32" and it solved most of the problems- Clang does the old D3D9 trick of "Silently fail when the input is clearly wrong and there's no way the output could be correct". But I'm left with just two unresolved externals- it's some std::_Hash_impl for float and double, with no change. The program is just "Hello, World!". Curiously, neither clang++.exe nor g++.exe have a problem with compiling the source, but if I compile it using the Clang C++ API to .o, and then pass it back to MinGW, I get the unresolved externals.
In general, it's not a good idea to use different toolchains when building a binary. It is entirely possible that the different tools' ideas of names of symbols won't match up.
Still, trying to answer your actual quesiton:
-lstdc would be a minimum requirement and -lstdc++ if it's C++ code. without knowing what your code does, it's impossible to say if you need more of them.

g++ linking issues: undefined reference to functions

I used CMake and Visual C++ to build the HyDE library. Then, still in VC++, I was able to successfully create code and build an executable that links into HyDE.lib and the HyDE header files.
I then discovered that in order to work with others at my company, it would be preferable to develop in Eclipse CDT. Knowing very little about Eclipse CDT, I created a default hello world project, deleted the code and then dumped in all of my code into the src folder. Then I attempted to change the includes and lib path and libs to mirror what had worked in VC++. At this point everything seems to compile, but I get an error in linking:
/cygdrive/c/EclipseWorkspace/425HyDE/Debug/../src/FS5HyDE.cpp:16: undefined reference to `HyDEAPI::HyDE::HyDE(HyDESystemModel::SystemModel*, bool)'
(There are many more errors like this, all referring to HyDE methods.) Here is what is being run at the command line:
g++ -L"C:\Progra~1\boost\boost_1_42\lib" -L"C:\EclipseWorkspace\HyDE" -o"425HyDE.exe" ./src/Adapter_FS5HyDE.o ./src/EPSCommands.o ./src/EPSCurrentSensor.o ./src/EPSFault.o ./src/FS5HyDE.o ./src/HyDEObservation.o ./src/MCDH.o ./src/MCDH_Module.o ./src/PDBComponent.o ./src/PowerSystem.o ./src/Program.o ./src/SSPCComponent.o ./src/Telemetry.o ./src/TelemetryReport.o -l:libboost_thread-vc90-mt-gd-1_42.lib -lHyDE
This is definitely not a library ordering problem because I've the other ordering as well (there are only two). Is it possible that there is a problem with compiling HyDE.lib in VC++ (which uses a Windows compiler) and compiling my program with g++? Could there be a problem in the way that Eclipse CDT is autogen'ing the makefiles? Any other ideas?
(Note: there appear to be plenty of others questions on SO with similar problems, but after reading through them I have yet to find one that addresses my problem.)
Classic missing symbol error. Which source file defines:
HyDEAPI::HyDE::HyDE(HyDESystemModel::SystemModel*, bool)' ?
Was this file added to the compilation? Can you spot it on the command line you pasted?
If this symbol belongs to an external library, after adding the directory path with -L , you could add the name of the specific library you want to link with your program using -l.
I'm going to suggest that you try to add to the compilation command the directory path to HyDE.lib, followed immediately by the library name, like this:
-L"C:\path_to_hyde_library" -l:HyDE.lib
and then tell us what happened.
Solution: Since the HyDE library was compiled with the Visual Studios compiler and I'm attempting to build the code that links to it with the Cygwin toolchain the two compilers use different name mangling schemes so that the latter linker can not find the expected symbols in the HyDE library. The only solution that I've found is to recompile the HyDE library with the Cygwin toolchain or compile the new code with whatever compiler Visual Studios is using. (grumble grumble)
./src/FS5HyDE.o and ./src/HyDEObservation.o should be the latest parameter if other object files (*.o files) need them, it means that the most needed object files should be appeared as last as possible in the parameters list.