ld: unrecognized -a option `tic-libstdc++' when using -static-libstdc++ in Makefile? - c++

I am trying to link the "fstream" library to my kernel in C++.
But linker has to have -static-libstdc++ in order for this to work (And G++). But when I go to compile, it says:
ld: unrecognized -a option `tic-libstdc++'
PS: I typed the whole thing (-static-libstdc++)
Does anybody know why this is happening?
Here is my linker command:
ld -z max-page-size=0x1000 -Ttext=0x01000000 -static -Bsymbolic -static-libstdc++ -o $(TARGET) $(OBJS) build/GDT/GDTASM.o

-static-libstdc++ is a compiler option, not a linker option. You already set the linker to link the object files with static libraries (-static). Use -lstdc++:
ld -z max-page-size=0x1000 -Ttext=0x01000000 -static -Bsymbolic -o $(TARGET) $(OBJS) build/GDT/GDTASM.o -lstdc++
Libraries must be listed after object files.
It is better if you do not use ld:
g++ -static-libstdc++ -Wl,-z -Wl,max-page-size=0x1000 -Wl,-Ttext=0x01000000 -Wl,-Bsymbolic -o $(TARGET) $(OBJS) build/GDT/GDTASM.o

Related

make command error: ld cannot find libraries that exist

I'm running make and ld will not find libraries that I have verified to exist using dnf provides '*/libpthread.so' for example. I get the following error code:
g++ -fopenmp -static -lpthread -o bayescan_2.1 start.o beta.o dirichlet.o RJupdates.o MHupdates.o likelihood.o read_write.o anyoption.o
/bin/ld: cannot find -lpthread
/bin/ld: cannot find -lm
/bin/ld: cannot find -ldl
/bin/ld: cannot find -lpthread
/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
make: *** [Makefile:4: bayescan_2.1] Error 1
These libraries all are found in /usr/lib64 on my chair's computing cluster. However the ld.so.conf file does not include a path that only goes to /usr/lib64 and I don't have admin permissions to create a new .conf file in /etc/ld.so.conf.d/.
Is there any way I can force make to search for the libraries in /usr/lib64?
Here is the actual Makefile in question:
# BayeScan makefile
bayescan_2.1: start.o beta.o dirichlet.o RJupdates.o MHupdates.o likelihood.o read_write.o anyoption.o
g++ -fopenmp -static -lpthread -o bayescan_2.1 start.o beta.o dirichlet.o RJupdates.o MHupdates.o likelihood.o read_write.o anyoption.o
start.o: start.cpp errors.cpp anyoption.h global_defs.h
g++ -fopenmp -c start.cpp errors.cpp
beta.o: beta.cpp global_defs.h
g++ -fopenmp -c beta.cpp
dirichlet.o: dirichlet.cpp global_defs.h
g++ -fopenmp -c dirichlet.cpp
RJupdates.o: RJupdates.cpp global_defs.h
g++ -fopenmp -c RJupdates.cpp
MHupdates.o: MHupdates.cpp global_defs.h
g++ -fopenmp -c MHupdates.cpp
likelihood.o: likelihood.cpp global_defs.h
g++ -fopenmp -c likelihood.cpp
read_write.o: read_write.cpp errors.cpp global_defs.h
g++ -fopenmp -c read_write.cpp errors.cpp
anyoption.o: anyoption.cpp anyoption.h
g++ -fopenmp -c anyoption.cpp
clean:
rm *.o bayescan_2.1
EDIT:
Turns out ld was trying to find static libraries with the -static flag. Removing this flag from the Makefile fixed the issue.
Simply add -L/usr/lib64 to the link command. See Directory Options in the GCC manual:
-Ldir
Add directory dir to the list of directories to be searched for -l.
If you can't or don't want to edit the Makefile, you can supply additional search directories through an environment variable
LIBRARY_PATH
The value of LIBRARY_PATH is a colon-separated list of directories, much like PATH. When configured as a native compiler, GCC tries the directories thus specified when searching for special linker files, if it cannot find them using GCC_EXEC_PREFIX. Linking using GCC also uses these directories when searching for ordinary libraries for the -l option (but directories specified with -L come first).
For example, run this in your shell before invoking make:
$ export LIBRARY_PATH="$LIBRARY_PATH:/usr/lib64"

Igraph makevars will not link to static library, i can use data structures but cannot functions while importing igraph c++ library

I am trying to install my C++ igraph library from https://github.com/igraph/igraph to visual studio code using the following method this is my makefile made according to this link.
CXX = g++
CXX_FLAGS = -std=c++17 -O3 -march=native -DNDEBUG
LIB = -Llib
INC = -Iinclude
.PHONY: all
all: a.out
a.out: main.cpp
$(CXX) $(CXX_FLAGS) $(INC) $(LIB) -ligraph -lm -lstdc++ -lgomp -lpthread -o $# main.cpp
.PHONY: clean
clean:
rm a.out
The compiler will always return something like:
g++ -std=c++17 -O3 -march=native -DNDEBUG -Iinclude -Llib -ligraph -lm -lstdc++ -lgomp -lpthread -o a.out main.cpp
/usr/bin/ld: /tmp/ccqJLfvi.o: in function `main':
main.cpp:(.text.startup+0x9): undefined reference to `igraph_rng_default'
/usr/bin/ld: main.cpp:(.text.startup+0x16): undefined reference to `igraph_rng_seed'
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: a.out] Error 1
If i only want to use data structures such as igraph_t graph* it will work, but if i try to call fucntion it will return error and will not generate a.out file. It would be incredablly good if someone would be able to explain why this happens cuz it really got on my nerve right now.
Please follow the instructions in the documentation to set up your package to link to igraph.
Instructions to install igraph: https://igraph.org/c/html/latest/igraph-Installation.html Note that you must both build and install the package. Make a note of the location you used to install it to (the value of CMAKE_INSTALL_PREFIX)
Instructions on compiling your first igraph program: https://igraph.org/c/html/latest/igraph-Tutorial.html Unless you are already comfortable with writing C programs and linking them to external libraries, I strongly recommend that you use CMake to set up your project, as described in the linked tutorial. CMake works the same way on all platforms (Windows/macOS/Linux) and will automatically figure out how to link your program to igraph correctly. When configuring your project, be sure to set CMAKE_PREFIX_PATH to the location where you installed igraph earlier.

how to create dylibs that link to boost

I am using clang and boost 1.57 on OSX Yosemite. I am trying to create a dylib for a python application (used swig to make the wrappers). I have successfully compiled this code for Windows and Linux, so I know it is the build/link phase on OSX that is causing me issues. Here is my makefile (which is wrong, somehow):
CC=clang++
vpath %.c ./
vpath %.h ./
SRCS=RecorderLib.cpp RecorderLib_wrap.cpp
OBJS=$(SRCS:.cpp=.o)
LIBS= -lpython2.7 -lboost_iostreams-mt -lboost_system-mt -lboost_thread-mt -lboost_date_time-mt -lboost_chrono-mt -lboost\
_filesystem-mt -lboost_regex-mt -lboost_atomic-mt -lboost_serialization-mt -lboost_program_options-mt
CFLAGS=-arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.5 -pipe -O2 -c -stdlib=libstdc++
LINKFLAGS = -dynamiclib -undefined suppress -flat_namespace
.PHONY: RecorderLib64.dylib
all: RecorderLib_wrap.o RecorderLib.o RecorderLib64.dylib
RecorderLib_wrap.o:
$(CC) RecorderLib_wrap.cpp $(CFLAGS) $(LIBS) -o RecorderLib_wrap.o
RecorderLib.o:
$(CC) RecorderLib.cpp $(CFLAGS) $(LIBS) -o RecorderLib.o
RecorderLib64.dylib:
$(CC) $(LINKFLAGS) $(OBJS) $(LIBS) \
-o RecorderLib64.dylib
mv RecorderLib64.dylib ../../
clean:
rm *.o
If I remove the -undefined suppress -flat_namespace flags, the thing will toss me a million symbol not found for architecture x86_64 errors for all the boost functions that I reference.
When I include those flags, the library compiles but when I fire up the host application I get an error such as
OSError: dlopen(/Users/myself/RecorderApp/src/RecorderLib64.dylib, 6): Symbol not found: __ZN5boost9iostreams15file_descriptor4seekElSt12_Ios_Seekdir
which I interpret to mean the dylib doesn't know about boost.
One other thing that I don't understand, but is possibly related, is that when I compile the source objects, it tosses me errors such as:
clang: warning: -lpython2.7: 'linker' input unused
On linux, you want to link to libraries both at the compile stage and the link stage (at least this is my understanding -- in any case my Makefile.gnu which I am basing this off of does this and works beautifully).
I should also mention that I can compile applications on this system that link to boost and various dylibs and they work perfectly, so I know my boost installation etc. is alright. Also, inspecting the libraries I link to with the file command tells me they are of the correct x86_64 architecture.
Later:
So, I realize now that the symbol(s) not found for architecture x86_64 errors were actually pointing to functions in the stdlib (but were referenced from boost), i.e.:
"std::basic_streambuf<char, std::char_traits<char> >::setbuf(char*, long)", referenced from:
vtable for boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink, std::char_traits<char>, std::allocator<char>, boost::iostreams::output> in RecorderLib.o
Changing the makefile so that the min osx version is 10.7 and using -stdlib=libc++ gets rid of all theses errors, but I am still getting symbol(s) not found for a boost:iostreams call:
"boost::iostreams::file_descriptor::seek(long,std::__1::ios_base::seekdir)"

linking static library instead of dynamic

I have a directory named FOO which has X.a and X.so . I want to choose only X.a.
So in my makefile I am using the following to link it
EXE: OBJ.o
g++ -L/PATH/TO/FOO -o $# $< -static -lX
But when I do that, I get the following error
/usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
How should this be done properly. One way is to give abs path of X.a. Is there some other way?
Try this:
EXE: OBJ.o
g++ -L/PATH/TO/FOO -o $# $< -Wl,-Bstatic -lX -Wl,-Bdynamic
If I'm reading the documentation for ld correctly, you don't have to specify the absolute path, but you can specify a library using its full name as such:
EXE: OBJ.o
g++ -L/PATH/TO/FOO -o $# $< -l:X.a

boost and cpp-netlib make compile ERROR

[SOLVED] created symlinks from /usr/lib/lib/* to /usr/lib*
[UPDATE 3] NEW VERSION:
Ok, I think I fixed something
use find / -name "libboost_system.*"
outout was
/usr/include/boost/lib/libboost_system.so
/usr/include/boost/lib/libboost_system.a
/usr/include/boost/lib/libboost_system.so.1.46.1
/usr/lib/lib/libboost_system.so
/usr/lib/lib/libboost_system.a
/usr/lib/lib/libboost_system.so.1.46.1
/usr/local/include/boost_1_46_1/bin.v2/libs/system/build/gcc-4.4.3/release/link-static/threading-multi/libboost_system.a
/usr/local/include/boost_1_46_1/bin.v2/libs/system/build/gcc-4.4.3/release/threading-multi/libboost_system.so.1.46.1
/usr/local/lib/libboost_system.so
/usr/local/lib/libboost_system.a
/usr/local/lib/libboost_system.so.1.46.1
/root/tmp/boost_1_46_1/bin.v2/libs/system/build/gcc-4.4.3/release/link-static/threading-multi/libboost_system.a
/root/tmp/boost_1_46_1/bin.v2/libs/system/build/gcc-4.4.3/release/threading-multi/libboost_system.so.1.46.1
why are these files in /usr/lib/lib ? and is it a problem ?
and the ls -l /usr/lib/lib | grep boost_system
ls -l /usr/lib/lib | grep boost_system
-rw-r--r-- 1 root root 21574 2011-05-09 15:15 libboost_system.a
lrwxrwxrwx 1 root root 25 2011-05-09 15:15 libboost_system.so -> libboost_system.so.1.46.1
-rwxr-xr-x 1 root root 20053 2011-05-09 15:15 libboost_system.so.1.46.1
atm my makefile looks like
LIBPATH=-I/usr/local/include/cpp-netlib
LIBS=$(LIBPATH) -lboost_system -lboost_filesystem -lboost_thread -lpthread
LD=g++ -g
CPP=g++ -c -g $(LIBS)
P=.
OBJ=$(P)/tmp/main.o $(P)/tmp/CLink.o $(P)/tmp/CFetcher.o
main: $(OBJ); $(LD) $(OBJ) $(LIBS) -o $#
$(P)/tmp/CLink.o: $(P)/src/CLink.cpp $(P)/include/CLink.h; $(CPP) -c $< -o $#
$(P)/tmp/CFetcher.o: $(P)/src/CFetcher.cpp $(P)/include/CFetcher.h; $(CPP) -c $< -o $#
$(P)/tmp/main.o: $(P)/src/main.cpp $(P)/include/CLink.h $(P)/include/CFetcher.h ; $(CPP) -c $< -o $#
all:
touch $(P)/tmp/*.o;
touch main;
rm -f $(P)/tmp/*.o;
rm -f main;
make main;
The Compiler output is lie
g++ -c -g -I/usr/local/include/cpp-netlib -lboost_system -lboost_filesystem -lboost_thread -lpthread -c src/main.cpp -o tmp/main.o
g++ -c -g -I/usr/local/include/cpp-netlib -lboost_system -lboost_filesystem -lboost_thread -lpthread -c src/CLink.cpp -o tmp/CLink.o
g++ -c -g -I/usr/local/include/cpp-netlib -lboost_system -lboost_filesystem -lboost_thread -lpthread -c src/CFetcher.cpp -o tmp/CFetcher.o
g++ -g ./tmp/main.o ./tmp/CLink.o ./tmp/CFetcher.o -I/usr/local/include/cpp-netlib -lboost_system -lboost_filesystem -lboost_thread -lpthread -o main
So for me all looks nice but when i try to run the program
./main
./main: error while loading shared libraries: libboost_system.so.1.46.1: cannot open shared object file: No such file or directory
The -l flags must come after the source files on linker command-line.
Yes, that means you'll have to split the LD definition to LD and LIBS, put all the -L and -l flags in the later and change the link command to:
$(LD) $(OBJ) $(LIBS) -o $#
The library (.so (dynamic) or .a (static)) files have to be the same version as the headers. While there are boost 1.46.1 headers installed in /usr/local/include/boost_1_46_1/, the corresponding library files don't seem to be installed at all. The only installed libraries are version 1.40.0 in /usr/lib, so the linker finds those (/usr/lib would be searched by default even if you didn't include the -L/usr/lib flag), but they don't contain the symbols expected by 1.46.1.
Note that when linking against shared library (using shared libraries is strongly recommended in Linux), the linker looks for the file with .so extension, but that is usually symlink to a file with added version suffix and the linker reads it and records the target name in the binary. That way programs compiled against the .1.40 will continue to work when 1.46 is installed, because the libboost*.so.1.40.0 may (and have to) stay around after the .so is redirected to the 1.46.1 version.
It should be even possible to install like:
/usr/local/lib/boost_1_46_1/libboost_system-mt.so -> /usr/local/lib/libboost_system-mt.so.1.46
/usr/local/lib/libboost_system-mt.so.1.46 -> /usr/local/lib/libboost_system-mt.so.1.46.1
/usr/local/lib/libboost_system-mt.so.1.46.1
and compile using -L/usr/local/lib/boost_1_46_1, though I currently can't find any package that would do it to confirm this. This way you could have development files for multiple versions installed and switch between them using explicit -I and -L flags while dynamic linker would still find the runtime files, for which it only looks in /usr/local/lib, /usr/lib and /lib (it can be configured in /etc/ld.so.conf, but that's the default).
Execute your application with strace. This will show the location were you app is looking for your boost libs. In my case an app was looking in /usr/lib/x86_64-linux-gnu for boost libs where the actual location was /usr/lib/lib. A simple export statement adding the paths for the boost shared libs in my case LD_LIBRARY_PATH=/usr/lib/lib worked a treat.
output from strace
open("/usr/lib/x86_64-linux-gnu/libboost_system.so.1.46.1", O_RDONLY) = -1 ENOENT (No such file or directory)
exit_group(127) = ?