How to obtain the path of a library - g++

I can compile my executable file by follow commands
g++ -c main.cpp
g++ main.o -o my_exe -lmy
I do not need to specify the path of the libmy.a using -L path during link.
The libmy.a can automatically find by system.
Now I want to find the path of libmy.a but I have no idea where it is.
How can I obtain the full path of libmy.a?

Instead of:-
g++ main.o -o my_exe -lmy
link your program with:-
g++ main.o -o my_exe -lmy -Wl,-trace
This will make g++ pass the diagnostic option -trace to the linker. The linker
will print the pathname by which it locates every object file, shared library or static libary that it inputs. Inspect the output and you will find the full pathname of libmy.a

Related

How can I properly configure the g++ include path with mingw64?

I have installed msys2/mingw64 because I need the g++ compiler. Now, I want to compile some c++ oce which requires openblas. I have installed the package using pacman -S mingw-w64-x86_64-openblas. However, compiling the code fails with
fatal error: cblas.h: No such file or directory
Clearly, the include path does not contain the headers from openblas which are located at C:\msys64\mings64\include\openblas. This is easy to fix by passing -I<include path> as an additional argument to g++.
Now, I was wondering whether there is an automated way to include include files/headers of installed packages in the g++ include path. The same problem also holds for libraries.
For example, pacman might be able to atomatically append these paths onto some environment variable which g++ checks.
The standard way to get compilation and linking options for a library on MSYS2 and other Unix-like systems is to run this command:
pkg-config --cflags --libs openblas
If you're just compiling, use --cflags by itself.
If you're just linking, use --libs by itself.
Here's an example Bash command you could use to compile a single-file program:
g++ foo.cpp $(pkg-config --cflags --libs openblas) -o foo

How did Cygwin g++ resolve it?

I am puzzled how a mere g++ -o testpoco testpoco.cpp -lPocoFoundation was able to compile successfully in my Cygwin environment. The complete C++ code is below:
#include <Poco/File.h>
int main (int argc, char *argv[])
{
Poco::File f("/tmp/test.log");
if (f.exists()) {
return 1;
}
return 0;
}
I installed the cygwin Poco development headers and libraries and I verified they are in:
/usr/include/Poco/ (the header files)
/usr/lib/ (the libraries)
But without specifying those include and library path in g++ how did it was able to compile and produce the exe? I checked the output of g++ -v and did not see any routes to Poco.
The compiler has default search paths for include files and for libraries. (Actually the latter applies to the linker, not the compiler, but the g++ command invokes both.)
/usr/include and /usr/lib are in those default search paths.
You specified #include <Poco/File.h>, so the compiler found /usr/include/Poco/File.h.
You specified -lPocoFoundation, so the linker found /usr/lib/libPocoFoundation.dll.a, the file that contains the code implementing the PocoFoundation library under Cygwin.
I checked the output of g++ -v and did not see any routes to Poco
The command g++ -v will just print out some version information about GCC, and how it was configured. Adding the -v option to your real commands used for compiling and/or linking will show the search paths for headers and libraries.
In other words, instead of just g++ -v you should try:
g++ -o testpoco testpoco.cpp -lPocoFoundation -v
This will show the search paths that Keith Thompson refers to in his answer.

cmake how to link static library not named with libxxx.a?

The correct link command is
g++ file1.o file2.o xxx.0 -o target -I./ -I/usr/local/libmylibone/
-L./ -L/usr/local/testlib/ ../lib/special_lib/static_lib.a
-lasn1c++ -lmysqlclient -lnsl -lm -lz -lc -ldl -lpthread -lrt -ljson
Please focus on ../lib/special_lib/static_lib.a, this is a static library and not named with libxxx.a. And I don't know how to write a CMake command to get this correct link command.
I've tried TARGET_LINK_LIBRARIES(../lib/special_lib/static_lib.a) and it will be translated to -l../lib/special_lib/static_lib.a. I've also tried TARGET_LINK_LIBRARIES(static_lib) but got -lstatic_lib and failed.
If you put the absolute path to your library it should work:
TARGET_LINK_LIBRARIES(your_binary /usr/local/lib/static_lib.a)
Second option:
ADD_LIBRARY(staticlib STATIC IMPORTED)
SET_TARGET_PROPERTIES(staticlib PROPERTIES IMPORTED_LOCATION /usr/local/lib/static_lib.a)
TARGET_LINK_LIBRARIES(your_binary staticlib)
The official CMake documentation for importing/exporting targets is here.

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.

C++ linking issue: multiple definition

Unfortunately I cannot post all of the source code here. I can describe the structure though. All header files have #ifndef/#define/#endif guards. The structure is as follows:
node.h - included by tree.h
tree.h - included by tree.cpp and main.cpp
tree.cpp
main.cpp
In node.h in the global namespace, I declare the following free standing function:
bool char_sort_func(Path first, Path second)
{
return (first->label() < second->label());
}
(Note: as shown bellow, a Path is just a shared_ptr) When I try to build, I get a multiple definition error saying that the function is present in both tree.o and main.o:
> make
g++ -c -g -Wall main.cpp -I /usr/include
g++ -c -g -Wall tree.cpp -I /usr/include
g++ -Wall -o tool tree.o main.o -L /usr/lib -l boost_program_options
main.o: In function `char_sort_func(boost::shared_ptr<Edge>, boost::shared_ptr<Edge>)':
node.h:70: multiple definition of `char_sort_func(boost::shared_ptr<Edge>, boost::shared_ptr<Edge>)'
tree.o:node.h:70: first defined here
collect2: ld returned 1 exit status
make: *** [all] Error 1
I tried searching all of the source files to see if that was true, however, I don't see it in any wrong places:
> grep char_sort_func *
Binary file main.o matches
node.h:bool char_sort_func(Path first, Path second)
node.h: std::sort(edges_.begin(), edges_.end(), char_sort_func);
Binary file trie.o matches
Sure enough though, it is in the binary files. How can I restructure my code to prevent this linking issue?
This will happen if you declare normal functions in a .h file, because they will be generated in every file that #includes it. Perhaps you meant to declare it inline or static?