LD: linking with STL libraries - g++

I was trying to compile a OpenCV's VideoCapture example. When I compile it, I get the following output:
gpp test.c
Info: resolving vtable for cv::VideoCapture by linking to __imp___ZTVN2cv12VideoCaptureE (auto-import)
c:/programs/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/ld.exe: warning: auto-importing has
enable-auto-import specified on the command line.
This should work unless it involves constant data structures referencing symbols from auto-imported DLLs.
(Btw, gpp is an alias to g++ -lhighgui -lcv -lcxcore)
So, I tried to compile with "gpp --enable-auto-import", but g++ didn't recognize this option. So, I tried to compile like this:
gpp -c test.c
ld test.o
And I've got the same error AND many other errors about STL functions, indicating it didn't link with STL:
undefined reference to std::cout
...
And, finally, when I compiled like this:
gpp -c test.c
ld --enable-auto-import test.o
This time, I've only got the STL errors. The VideoCapture error is gone! So I guess I solved this problem. The only thing is: how do I make ld link my program with STL libraries??????
Thanks in advance

The correct solution is build with
g++ test.c -lhighgui -lcv -lcxcore -Wl,--enable-auto-import
Unlike your 'gpp' alias, this puts libraries after objects which reference them (important when linking with archive libraries), and also properly passes --enable-auto-import flag to the linker.
Your current "fix" only works "by accident".

Related

Categories in static lib not regocnized at runtime

I am building an executable ("tool") on Linux. Using include $(GNUSTEP_MAKEFILES)/tool.make.
It's linked to a static lib that has also be build with GNUstep. The lib
contains Categories.
The executable builds fine but has errors at runtime not recognizing
methods defined in the static lib's Category:
Uncaught exception NSInvalidArgumentException, reason:
ClassNameOfClassTheCategoryExtends(instance) does not recognize
nameOfMethodInCategory
I am trying to fix that by passing -ObjC to the linker flags (also
tried -all_load) in the executable's GNUmakefile:
ADDITIONAL_LDFLAGS = -ObjC -all_load
But that seems to be ignored by clang. Here is the relevant output of
make install messages=yes debug=yes
clang: warning: argument unused during compilation: '-ObjC'
[-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-all_load'
[-Wunused-command-line-argument]
It looks like ADDITIONAL_LDFLAGS are used compiling, not linking.
Using this leads to the same result:
LDFLAGS := $(LDFLAGS) -ObjC
The excecutables GNUmakefileincludes the following:
include $(GNUSTEP_MAKEFILES)/common.make
# My make
include $(GNUSTEP_MAKEFILES)/tool.make
The resulting command line output is:
$ make install messages=yes debug=yes
This is gnustep-make 2.9.0. Type 'gmake print-gnustep-make-help' for help.
Running in gnustep-make version 2 strict mode.
Making all for tool NameOfExcecutable...
clang -ObjC -fuse-ld=/usr/bin/ld.gold -pthread -fexceptions -rdynamic -fobjc-runtime=gnustep-2.0 -fblocks -o obj/NameOfExcecutable \
./obj/NameOfExcecutable.obj/main.m.o ./obj/NameOfExcecutable.obj/MyClass.m.o ./obj/NameOfExcecutable.obj/StreamRunLoop.m.o ./obj/NameOfExcecutable.obj/Connector.m.o ./obj/NameOfExcecutable.obj/HTTPClient.m.o \
-L/home/user/GNUstep/Library/Libraries -L/usr/GNUstep/Local/Library/Libraries -L/usr/GNUstep/System/Library/Libraries -lgnustep-base -ldispatch -l/path/to/libOwnLib1.a -l/path/to/libOwnLib2.a -l/path/to/libOwnHavingTheCategories.a -l/path/to/libOwnLib4.a -l/path/to/libOwnLib5.a -luuid -lz -lpthread -ldl -lpthread -lobjc -lm
clang: warning: argument unused during compilation: '-ObjC' [-Wunused-command-line-argument]
Question:
What am I doing wrong
or
How can I work around the issue?
After digging into the issue of the linker not knowing the -ObjC flag (which we are used to use in Xcode) it looks like:
only ld.ld64 is aware of this flag
ld.ld64 is a (too genericly named) "linker for macOS" (from LLDB.org)
thus is not available for Linux linkers
To workaround we first stopped using GNUstep makefiles to
disable all GNUstep magic understand what is going on and wrote our own makefiles.
The actual fix to force link/load all .o files was to explicitly pass --whole-archive to the linker:
-Wl,-whole-archive path/to/static/lib/containing/categories/libOwnLib1.a -Wl,-no-whole-archive

Can't compile Fortran modules: Undefined symbol _main

I've been trying lately to use libraries in Fotran, but I kept on getting this error message
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
which I cound't find any specific solution to it. In this case, I was working with some libraries that I built myself (this problem happened with static and shared libraries) from simples modules I wrote for purposses of tests.
I decided to try only the modules then, and I kept getting the same error message regardes of the module I used. I would like to know if someone can help me on telling if I am using incorrect syntax. Here is the module
module modulo1
IMPLICIT NONE
real, parameter:: pi=3.1415
end module modulo1
This is the main
program teste
use modulo1
IMPLICIT NONE
real :: r = 2
write (*,*) 'Área: ', pi*r**2
end program teste
These were the commands I used for compiling
gfortran -c modulo1.f90
gfortran -c teste.f90
gfortran -o teste.o modulo1.o
Your compilation is broken. The command
gfortran -o teste.o modulo1.o
tells gfortran to create an executable called teste.o from the object file called modulo1.o. Since that module file doesn't contain a program the compiler can't find an entry point for the executable it is trying to build. The argument to the -o option is the name of the executable to build.
You probably ought to replace that statement with something like
gfortran -o test teste.o modulo1.o
which will build an executable called test.
In the longer run learn how to use make or another build system.

pthread library inclusion at (linking?) step

I'm trying to compile a program provided to me. I noticed in the Makefile it runs the command
g++ -o test [...] -lpthread
I noticed the pthread library file is in /lib/libpthread.so.0 , but when I try to make the target, it gives me this error:
/usr/bin/ld: cannot find -lpthread
collect2: ld returned 1 exit status
how do I fix this?
In order to use -lpthread, you need a libpthread.a library archive and this is for static linking. libpthread.so.0 is a shared object which means it is used for dynamic linking. See GCC Link Options

Unable to compile sharable .o files with g++

When i compile with the following command:
g++ -fPIC -o obj/buffer.o buffer.cpp
I get the following error:
/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../x86_64-linux-gnu/crt1.o:
In function _start': (.text+0x20): undefined reference tomain'
I am thought with the -fPIC flag, I didn't need a main function. I get this error with all of the cpp files. I do have a main.cpp that has the shared library functions in it. You can get the source code at the following:
git clone https://github.com/nterry/39DLL-4-Linux.git
Any ideas? I know that I can use the ld binary to put all of the o files in the an so once they're done, I just need help in building them all into shareable .o files
I think that I answered my question. I added a -c to the command and it seems to have worked. Here is the command I used:
g++ -fPIC -c -o obj/list.o list.cpp
That is one of several cpp files, and all seemed to work.

Lapack undefined reference

I am new to g++ and lapack, and attempting to use them. I encountered a problem when I tried to compile the following naive code
#include <lapackpp.h>
int main()
{
LaGenMatDouble A;
return 0;
}
If I run the command
$g++ -L/usr/local/lib -llapackpp test2.cpp
where test2.cpp is the name of the cpp file, the terminal would give an error:
test2.cpp:1:22: fatal error: lapackpp.h: No such file or directory
But if I run the command:
$g++ -I/usr/local/include/lapackpp -L/usr/local/lib -llapackpp test2.cpp
the terminal would give an error:
/tmp/ccUi11DG.o: In function `main':
test2.cpp:(.text+0x12): undefined reference to `LaGenMatDouble::LaGenMatDouble()'
test2.cpp:(.text+0x23): undefined reference to `LaGenMatDouble::~LaGenMatDouble()'
collect2: ld returned 1 exit status
BTW, if I run the command
$pkg-config lapackpp --libs
the result is
-L/usr/local/lib -llapackpp
Could you please help me solve this? Thanks in advance!
Lapack requires fortran libraries, so that's where the -lgfortran comes from. Moreover, it appears the exact way to provide that library for the compiler depends on the Linux distriburion. From the documentation:
Requirements
This package requires the packages "blas", "lapack" (without the "++"), and a Fortran compiler. On most Linuxes these are available as pre-compiled binaries under the name "blas" and "lapack". For SuSE 10.x, the Fortran compiler is available as package "gfortran". For SuSE 9.x, the Fortran compiler is available as package "gcc-g77".
Not sure why pkg-config lapackpp --libs does not list -lgfortran
The -I/usr/local/include/lapackpp specifes the lapackpp-related header files. Without it the compiler cannot find lapackpp.h when you try to include it (#include <lapackpp.h>) -- see the compiler error in your question
I finally solved the problem but would still wonder why it has to be so.
The only command that can link cpp file to lapackpp library is:
g++ foo.cpp -o foo -lgfortran -llapackpp -I/usr/local/include/lapackpp
It would not work without -lgfortran, or with -I/usr/local/include/lapackpp replaced by -L/usr/local/lib.
Does anyone have an answer?