For a GUI project, we have a makefile which builds a library (.a) from all the .o files, which is then linked for each test.
When doing so, any function not used is thus not included in the executable. In order not to have to rebuild every test every time, we decided to switch to .so and use dynamic linking. This code uses OpenGL and glad.o (glad.c --> glad.o)
libgrail.so: undefined reference to `glad_glProgramBinary'
libgrail.so: undefined reference to `glad_glGetProgramBinary'
I had a glad.o, and not even sure how we got it. It has the above symbols defined, but it is not compiled with -fPIC and cannot be linked into the shared library.
When I build with glad.c, the resulting glad.o does NOT have the symbols
Looking at the header file glad.h
GLAPI PFNGLPROGRAMBINARYPROC glad_glProgramBinary;
#define glProgramBinary glad_glProgramBinary
These are called in compiling shaders.
So perhaps our source of glad.c is bad. I looked all over, and can find it in various opengl demos, but I do not understand where it really comes from.
I found this generator:
https://glad.dav1d.de/
and generated code for OpenGL 3.3 (.c and .h)
compiling that code has the same errors.
So what version of glad.c should I get in order to correctly generate these symbols?
Related
I am looking for a way to suppress/satisfy the linker when a symbol is undefined at compile time.
To illustrate what I am trying to accomplish I will put up a simple example:
CoreCpp.h file:
#include <stdio.h>
int calculate();
CoreCpp.cpp file:
#include "CoreCPP.h"
int calculate(){
return 0;
}
With these two files above I will create a .a static library.
Then in Xcode I will create a simple command line project as you can see in the image below:
If I link the static library, the project will compile without any issue of course:
However, if I don't link the static library, it will throw an undefined symbol error.
Undefined symbols for architecture x86_64:
"calculate()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
Question: Is there a way that I can suppress the error or somehow make the linker happy at compile time? Can we apply the concept of weak linking here?
I'm not familiar with Xcode, but its compilation/linking process should be similar to Eclipse. So first you should understand the differences between compilation, linking, and building. Then you should also realize that there are 2 ways of building your project: either compile your source code files separately and then link them together to get machine-executable instructions, OR to compile and link in one single step/command. In the step of compilation only, you can either get an output of a static or dynamic library, or a .o object file, which will be used later in the linking step. With separate steps of compile/link you have more control over your build process. What Eclipse (and supposedly Xcode) is doing when you build your project, is either of those 2 ways, depending on your project settings. If you'd like to take a full control over the process of building in Eclipse or whatever IDE you have, you should take care of your project settings, or even better to set it up to work with a Makefile, where you can define exactly how your source code should be compiled and linked and in which steps/order. In Eclipse you need to create a Makefile-project and edit your Makefile alongside the project files.
In this your question above, what you were trying to do (or asking for help) is forcing the IDE to build your project without specifying the library, for which obviously your linker was complaining about. Instead, if you specify the library it doesn't complain any more. But be careful, you should make sure your IDE settings are fine to (re)compile your library from its source upon changes, otherwise you may end-up linking an old version of the compiled library file with your main.cpp and other files.
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.
Let's say I have a C++ library code, with some definitions wrapped with extern "C" { ... }.
I also have a C library code which uses that C++ library.
What I want to do is to create a single .so file, so that only one call to dlopen should be enough to start using this library.
Here's what I do now: I'm first compiling my C++ library to a .so file with -shared -rdynamic -fPIC. Then I'm compiling my C library to a .so file with same parameters. After that, I have to load C++ library with dload before loading the C library. Otherwise loading fails with a undefined symbol error.
What I want to do is to compile this two libraries into one .so file so that only one call to dload should be enough to use it.
How can I do that?
Thanks in advance.
EDIT: Compiling to .o files and then combining doesn't work for me. Here's what I do:
I compile each file to object file with -fPIC parameter
I link them with clang [list of object files] -shared -rdynamic -fPIC -o libmylib.so
When I try to load, I get undefined symbol: __gxx_personality_v0 error.
EDIT2: Ahh, I forgoto to link it against libstdc++, it works now. Thanks.
The easiest way is to combine them into a single .so file by either combining all object files, or building two static .a libraries and then linking them into a single shared library.
If you really want to keep two .so files, link the first library to the second, as you would with executable. E.g. if libfoo depends on libbar, compile libfoo with -lbar. You'd have to have the dependent libraries in your default library path or in LD_LIBRARY_PATH environment variable.
I have a program which statically links to another library in linux using -L(mylib.a) when compiling (using eclipse cdt).
To my meager understanding, the fact that the link is static means that the library is inserted into my binary. Does this mean that if I make a change to mylib I need to recompile my binary?
I assume so, but I wanted to make sure, as it is a big overhead in time. Note that if a change was made to mylib, then eclipse recognizes that it needs to be recompiled, but it doesn't recognize that the binary itself needs to be recompiled, even though it links to the mylib.
If you did not change the interface of the library (i.e. the headers), only a re-link is enough.
Yes, You should rebuild your code with the modified library to produce the binary which links to the new and updated library.
The building of a project can be broken in to two milestone phases:
Compilation:
During this stage the compiler compiles each Translation Unit. It checks the source code for valid syntax etc and produces object files.These object files contain the assembly code output of the source code.
Linking:
During this stage the linker links together the object files and the libraries to generate an executable.
When a application or project uses a static library it includes the header file which is typically called as library interface which contains the list of api and other construct which the application uses.The application also needs to link against the library file.
Obviously, if the interfaces are intact ie the library header file included by your application is unchanged, a compilation is not required but you just need to link to the updated library.
However, I dont think there is a way to just relink updated libraries through eclipse IDE so you should rebuild your project which would essentially do the needful.
i.e:
recompile your project and relink the new library to it or
just relink the new library to your project.
I've written some code (static library) in c++, with (i think so, C compatiblity - got 'extern C' and so on), and then i wanted to use it in my C application.
When im runing my C app, i got error:
undefined symbol: _ZTISt9exception
c++ code was compiled with gcc with : -std=c++0x -lstdc++ flags
then, on obj files i run ar
i suppose that symbol comes direct from c++ library. When im compiling my C app I of course add my C++ lib in my makefile, and compilation finishes with no error.
What might be wrong ?
thx for all help
A static library is not linked, it is just a collection of object files in an archive. All files names like libxxx.a are static libraries, while files named like libyyy.so are dynamic libraries.
This means that the the external symbols in your library are never resolved until you link with it to make an executable. Then you need all the library files needed by your library as well.
You'll need to link the final executable with the C++ runtime library (-lstdc++); it has no effect when compiling the C++ objects, only linking the executable.