I want to create static library and something goes wrong. I have makefile:
static: main.c tree.c
gcc -c -Wall tree.c -o tree.o
ar crs libtree.a tree.o
gcc -Wall -static main.c -L. -ltree -o main
./main
When I write "make static", it shows me:
gcc -c -Wall tree.c -o tree.o
ar crs libtree.a tree.o
gcc -Wall -static main.c -L. -ltree -o main
ld: library not found for -lcrt0.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [static] Error 1
It created files: tree.o and libtree.a. I don't know why it doesn't want to find a library. Do you know how to solve it?
Most probably, your system is not set up for static linking. Most newer Linux distributions aren't as static linking is highly discouraged.
Look for a package named glibc-static or similar and install.
In case your system is not Linux (could be MacOS X as well, you didn't state that) - You're doomed. Static linking is not supported on that platform at all.
When I compile code using GNU Make I get multiple warnings like:
clang: warning: -lGui: 'linker' input unused
This is probably because I have messed something up in my Makefile (below). Can anyone point me toward the problem?
CXX=g++
CC=g++
CXXFLAGS=-g -Wall -W -Wshadow -Wcast-qual -Wwrite-strings $(shell root-config --cflags --glibs)
CPPFLAGS+=-MMD -MP
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)
xSec_x: xSec_x.o xSec.o Analysis.o
-include xSec_x.d xSec.d Analysis.d
xSec.o: xSec.cpp xSec.h Analysis.h Analysis.cpp
xSec_x.o: xSec_x.cpp xSec.h Analysis.h
clean:
rm -f #rm -f $(PROGRAMS) *.o *.d
That message means you are passing linker flags (like -l which tells the linker to pull in a library) to the compiler.
This means that the result of running root-config --cflags --glibs is generating linker flags, and those are going into CXXFLAGS, which is being passed to the compiler. I don't know what root-config is, but you should investigate its command line and invoke it in a way where it doesn't generate linker flags. Probably removing the --glibs option will do it.
ETA: you really want to be using := to assign these flags variables if you're going to run $(shell ...) there. It will work either way, but if you use = then the shell command will be run every time make expands the variable, which is once per compilation. If you use := it will only be run once, when the makefile is parsed.
I got this same error and the reason was that I forgot to add -I in front of my included paths for cflags in makefile. For example:
CFLAGS += $(path)/dir/subdir/include -> Got the above mentioned error.
CFLAGS += -I$(path)/dir/subdir/include -> Fixed the issue.
I'm trying to combine object files created from C++ files into an executable using gcc. Unfortunately, gcc is giving me thousands of undefined reference errors to strings, arrays, etc.
I am doing this on a Windows machine, so no terminal commands; only cmd commands.
I'm simply doing:
gcc a.o b.o c.o -o prgm.exe
What am I missing/doing wrong?
EDIT:
I recreated the .o files with g++ doing:
g++ a.cpp -g -c -Wall -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -IC:\SDL-1.2.14\include -o a.o, where a.cpp and a.o are the directories where i keep the files, not the g++ directory
Then, I did g++ a.o b.o c.o -o prgm.exe. This gave dozens (I guess that's an improvement?) errors like
undefined reference to `_SDL_SetColorKey'
but I included SDL didnt I?
The final error from this is:
c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.7.0/../../../li
bmingw32.a(main.o):main.c:(.text.startup+0xa7): undefined reference to `_WinMain
#16'
collect2.exe: error: ld returned 1 exit status
int main(int argc, char * argv[]) is in the code
You are trying to link a C++ program with the C linker. You need to use g++ instead of gcc.
Generally speaking gcc is for compiling/linking C, while g++ is for C++. IIRC compiling C++-code with gcc works by virtue of dispatching according to the file extension. Linking C++ code with gcc however does not work, since it won't link the C++ standard libraries, resulting in your undefined reference errors.
If this does not solve your problem, you might want to give us a more concrete description of your errors and your system.
Based upon your updates then I think you'd need to do the following:
g++ a.cpp b.cpp c.cpp -g -Wall -IC:\SDL-1.2.14\include -LC:\SDL-1.2.14\lib -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -o prgm.exe
I'm guessing C:\SDL-1.2.14\lib exists based upon where the headers are located.
GCC is the C compiler. Your code is C++ so you need to use G++ to do the linking:
g++ a.o b.o c.o -o prgm.exe
This automatically adds the C++ libraries to the link line, resolving many if not all of your missing references.
I've got a problem that's a bit strange.
We have a project that we compile for several different architectures, notably these 2: SH4 and MIPS.
We've had a problem for some time, where some code would compile in SH4, but not for MIPS, because of missing includes. I've narrowed down the problem to this test file:
#include <sstream>
// deliberately not including the needed includes
int main()
{
const char *toto = "Hello World";
// using printf and strlen which require <stdio.h> and <string.h>
printf("Toto has len %d\n", strlen(toto));
return 0;
}
Compiling to SH4 with this command
$ sh4-linux-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -o test
$
-> no problem at all. The file actually executes normally.
Whereas with MIPS
$ mips-linux-gnu-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -o test
test.cpp: In function 'int main()':
test.cpp:6: error: 'strlen' was not declared in this scope
$
Now, I've run several things, notably the dependency generation of both g++. What I see is this:
SH4
$ sh4-linux-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -M |grep "/string.h"
/opt/STM/STLinux-2.3/devkit/sh4/target/usr/include/string.h \
-> string.h automatically included.
MIPS
mips-linux-gnu-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -M |grep "/string.h"
-> string.h missing in includes
For information:
SH4 version = 4.2.4 (2007)
MIPS version = 4.3.2 (2008)
What's going on here? The <sstream> include seems to drag along all what's needed for strlen() when compiling on SH4, whereas on MIPS it doesn't. I suspect this is because the versions are different, but I'm not sure.
My real problem, in the end, is that when I develop on SH4, I'd like to be sure that if it compiles, it will compile on all targets.
Is there a solution to this?
What's going on here?
You're basically asking "why does my non-standard code compile with one version of a compiler but not another?" Of course it's because the versions are different.
See the GCC 4.3 changes which say this under the Runtime Library (libstdc++) section:
Header dependencies have been streamlined, reducing unnecessary includes and pre-processed bloat.
We've continued reducing header dependencies in more recent versions too, to be stricter and to reduce namespace pollution (e.g. 4.6 avoids including <cstddef> unnecessarily, and 4.7 no longer includes <unistd.h> unnecessarily), so to answer your final question I would suggest using the most recent GCC version you can (even if only to check the code not for production builds) as it has the strictest, cleanest headers and will find the most problems. Another option would be to use an even stricter standard library implementation, such as libcomo.
Why does the order in which libraries are linked sometimes cause errors in GCC?
(See the history on this answer to get the more elaborate text, but I now think it's easier for the reader to see real command lines).
Common files shared by all below commands
// a depends on b, b depends on d
$ cat a.cpp
extern int a;
int main() {
return a;
}
$ cat b.cpp
extern int b;
int a = b;
$ cat d.cpp
int b;
Linking to static libraries
$ g++ -c b.cpp -o b.o
$ ar cr libb.a b.o
$ g++ -c d.cpp -o d.o
$ ar cr libd.a d.o
$ g++ -L. -ld -lb a.cpp # wrong order
$ g++ -L. -lb -ld a.cpp # wrong order
$ g++ a.cpp -L. -ld -lb # wrong order
$ g++ a.cpp -L. -lb -ld # right order
The linker searches from left to right, and notes unresolved symbols as it goes. If a library resolves the symbol, it takes the object files of that library to resolve the symbol (b.o out of libb.a in this case).
Dependencies of static libraries against each other work the same - the library that needs symbols must be first, then the library that resolves the symbol.
If a static library depends on another library, but the other library again depends on the former library, there is a cycle. You can resolve this by enclosing the cyclically dependent libraries by -( and -), such as -( -la -lb -) (you may need to escape the parens, such as -\( and -\)). The linker then searches those enclosed lib multiple times to ensure cycling dependencies are resolved. Alternatively, you can specify the libraries multiple times, so each is before one another: -la -lb -la.
Linking to dynamic libraries
$ export LD_LIBRARY_PATH=. # not needed if libs go to /usr/lib etc
$ g++ -fpic -shared d.cpp -o libd.so
$ g++ -fpic -shared b.cpp -L. -ld -o libb.so # specifies its dependency!
$ g++ -L. -lb a.cpp # wrong order (works on some distributions)
$ g++ -Wl,--as-needed -L. -lb a.cpp # wrong order
$ g++ -Wl,--as-needed a.cpp -L. -lb # right order
It's the same here - the libraries must follow the object files of the program. The difference here compared with static libraries is that you need not care about the dependencies of the libraries against each other, because dynamic libraries sort out their dependencies themselves.
Some recent distributions apparently default to using the --as-needed linker flag, which enforces that the program's object files come before the dynamic libraries. If that flag is passed, the linker will not link to libraries that are not actually needed by the executable (and it detects this from left to right). My recent archlinux distribution doesn't use this flag by default, so it didn't give an error for not following the correct order.
It is not correct to omit the dependency of b.so against d.so when creating the former. You will be required to specify the library when linking a then, but a doesn't really need the integer b itself, so it should not be made to care about b's own dependencies.
Here is an example of the implications if you miss specifying the dependencies for libb.so
$ export LD_LIBRARY_PATH=. # not needed if libs go to /usr/lib etc
$ g++ -fpic -shared d.cpp -o libd.so
$ g++ -fpic -shared b.cpp -o libb.so # wrong (but links)
$ g++ -L. -lb a.cpp # wrong, as above
$ g++ -Wl,--as-needed -L. -lb a.cpp # wrong, as above
$ g++ a.cpp -L. -lb # wrong, missing libd.so
$ g++ a.cpp -L. -ld -lb # wrong order (works on some distributions)
$ g++ -Wl,--as-needed a.cpp -L. -ld -lb # wrong order (like static libs)
$ g++ -Wl,--as-needed a.cpp -L. -lb -ld # "right"
If you now look into what dependencies the binary has, you note the binary itself depends also on libd, not just libb as it should. The binary will need to be relinked if libb later depends on another library, if you do it this way. And if someone else loads libb using dlopen at runtime (think of loading plugins dynamically), the call will fail as well. So the "right" really should be a wrong as well.
The GNU ld linker is a so-called smart linker. It will keep track of the functions used by preceding static libraries, permanently tossing out those functions that are not used from its lookup tables. The result is that if you link a static library too early, then the functions in that library are no longer available to static libraries later on the link line.
The typical UNIX linker works from left to right, so put all your dependent libraries on the left, and the ones that satisfy those dependencies on the right of the link line. You may find that some libraries depend on others while at the same time other libraries depend on them. This is where it gets complicated. When it comes to circular references, fix your code!
Here's an example to make it clear how things work with GCC when static libraries are involved. So let's assume we have the following scenario:
myprog.o - containing main() function, dependent on libmysqlclient
libmysqlclient - static, for the sake of the example (you'd prefer the shared library, of course, as the libmysqlclient is huge); in /usr/local/lib; and dependent on stuff from libz
libz (dynamic)
How do we link this? (Note: examples from compiling on Cygwin using gcc 4.3.4)
gcc -L/usr/local/lib -lmysqlclient myprog.o
# undefined reference to `_mysql_init'
# myprog depends on libmysqlclient
# so myprog has to come earlier on the command line
gcc myprog.o -L/usr/local/lib -lmysqlclient
# undefined reference to `_uncompress'
# we have to link with libz, too
gcc myprog.o -lz -L/usr/local/lib -lmysqlclient
# undefined reference to `_uncompress'
# libz is needed by libmysqlclient
# so it has to appear *after* it on the command line
gcc myprog.o -L/usr/local/lib -lmysqlclient -lz
# this works
If you add -Wl,--start-group to the linker flags it does not care which order they're in or if there are circular dependencies.
On Qt this means adding:
QMAKE_LFLAGS += -Wl,--start-group
Saves loads of time messing about and it doesn't seem to slow down linking much (which takes far less time than compilation anyway).
Another alternative would be to specify the list of libraries twice:
gcc prog.o libA.a libB.a libA.a libB.a -o prog.x
Doing this, you don't have to bother with the right sequence since the reference will be resolved in the second block.
A quick tip that tripped me up: if you're invoking the linker as "gcc" or "g++", then using "--start-group" and "--end-group" won't pass those options through to the linker -- nor will it flag an error. It will just fail the link with undefined symbols if you had the library order wrong.
You need to write them as "-Wl,--start-group" etc. to tell GCC to pass the argument through to the linker.
You may can use -Xlinker option.
g++ -o foobar -Xlinker -start-group -Xlinker libA.a -Xlinker libB.a -Xlinker libC.a -Xlinker -end-group
is ALMOST equal to
g++ -o foobar -Xlinker -start-group -Xlinker libC.a -Xlinker libB.a -Xlinker libA.a -Xlinker -end-group
Careful !
The order within a group is important !
Here's an example: a debug library has a debug routine, but the non-debug
library has a weak version of the same. You must put the debug library
FIRST in the group or you will resolve to the non-debug version.
You need to precede each library in the group list with -Xlinker
Link order certainly does matter, at least on some platforms. I have seen crashes for applications linked with libraries in wrong order (where wrong means A linked before B but B depends on A).
I have seen this a lot, some of our modules link in excess of a 100 libraries of our code plus system & 3rd party libs.
Depending on different linkers HP/Intel/GCC/SUN/SGI/IBM/etc you can get unresolved functions/variables etc, on some platforms you have to list libraries twice.
For the most part we use structured hierarchy of libraries, core, platform, different layers of abstraction, but for some systems you still have to play with the order in the link command.
Once you hit upon a solution document it so the next developer does not have to work it out again.
My old lecturer used to say, "high cohesion & low coupling", it’s still true today.