boost::filesystem3::path::parent_path() on Ubuntu - c++

As an input the function gets the file path anmd name parameter
const QString& buildSourcePathAndName
It needs to extract the path onlyfor futher processing.
I used the below code to do that .
boost::filesystem::path p(string(buildSourcePathAndName.toLatin1().data()));
m_pSourceCodePath = p.parent_path().string();
On windows it works OK.But on linux (ubuntu) I can`t compile it,getting the error.
undefined reference to `boost::filesystem3::path::parent_path() const'
I`ve read about this error - proposes to change boost lib version.I can`t do that in our system.
What could be the possible solution for this issue?
(I don`t want to implement the code which extracts the path,but rathe use some existing functions)

On Windows, boost libraries use pragmas to automatically add the libraries to the linker command line. When building for linux you need to add the libraries explicitly in whatever build system you use (adding -lboost_filesystem at the end of the linker command line as suggested by ForEveR and hmjd)

Related

Run-time linker issue: "error while loading shared libraries"

I am working on a C++ project consisting of multiple similar programs. Each use a variety of headers and binaries, around 80. I managed to compile each program, and successfully run each but one of them, one named VerifyServer. When I try to run this, I get the below error:
./VerifyServer: error while loading shared libraries: libboost_system.so.1.57.0: cannot open shared object file: No such file or directory
However, here's the weird thing:
I was getting a very similar error when I tried running the other programs as well, but then I added
-Wl,-rpath=$(BOOST_LIB_HEADER_PATH)/stage/lib
to each of my compiler arguments, and it worked. I managed to run each programm, and even the file indicated in the error message of VerifyServer changed. Note that the variable BOOST_LIB_HEADER_PATH is correctly assigned to the path of my boost libraries.
Since my run time linker was failing to find this binary to correctly link it with my program, I tried checking which dependencies it was unable to find, so when I ran
ldd VerifyServer | grep boost (I use grep for simplicity)
I get this message:
libboost_thread.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_thread.so.1.57.0 (0x00007f34c9b36000)
libboost_serialization.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_serialization.so.1.57.0 (0x00007f34c9ad1000)
libboost_system.so.1.57.0 => not found
So, by now I assume that the system binary is not in the same directory as the others. When I manually check, I see that oddly enough, it is right there! So I decide to do the same thing on one of the programs that run without any problems, and I use
ldd IdentityProviderServer | grep boost
and I get the following message:
libboost_thread.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_thread.so.1.57.0 (0x00007f97b6094000)
libboost_serialization.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_serialization.so.1.57.0 (0x00007f97b602f000)
libboost_system.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_system.so.1.57.0 (0x00007f97b602a000)
libboost_filesystem.so.1.57.0 => /path/to/boost_1_57_0/stage/lib/libboost_filesystem.so.1.57.0 (0x00007f97b600d000)
When I see that the system binary can be found in the same location as others, I just get confused. I don't know what the issue is here. Is there something I am missing about how the linker works?
Please note that I have to use the version 1.57.0 of boost here. I cannot update it to the current version, and I doubt my issue has anything to do with the version of boost.
This may be due to the linker unable to find transient dependencies. If you are directly linking against EG: libboost_thread, then the applications runtime linker will use the -rpath path that you defined when compiling.
HOWEVER, the libboost_thread may require ITS OWN library, libboost_system. The question is, should the libboost_thread library's runtime linker use your applications -rpath? or ignore it and use its own system search paths?? You must explicitly tell the runtime linker what it should do. Note, the default runtime linker search behavior changes depending on your compiler version. Google, RUNPATH vs RPATH and -Wl,--disable-new-dtags
I have answered this issue in another similar question: CMake project fails to find shared library
Although that user is using CMake to build their application, the underlying problem may be occurring here too.

"symbol lookup error:" when executing from different directory, otherwise working as intended when executed from build directory

I have a weird problem on Ubuntu Linux 18.04 that appeared after having run pytest a couple of times. The project is mostly c++, but it also generates pybind11 bindings and generates library files via CMake.
My goal is to force a program to output its files into a specific directory within the project folder, i.e. not in the same directory where the executable file is. I used to achieve that by running this command:
user#computer_name:~/Dev/project$ (cd /home/user/Dev/project/unittests/test_output && "/home/user/Dev/project/./executable" -pdbin /home/user/Dev/project/unittests/test_data/3v8x.pdb -mtzin /home/user/Dev/project/unittests/test_data/3v8x_phases.mtz && cd /home/user/Dev/project)
This command used to work as intended, until today, when I ran some instances of pytest. While pytest is able to complete all tests successfully, my aforementioned command does not work anymore and gives me this error:
user#computer_name:~/Dev/project$ /home/user/Dev/project/./executable: symbol lookup error: /home/user/Dev/project/./executable: undefined symbol: _ZN7library7Class11functionEv
However, when I try to execute the executable in the build directory, like this:
user#computer_name:~/Dev/project$ ./executable
There is no error whatsoever and if I try to give the program its input, the program works as intended without any errors. However, it outputs the files in the build directory - the place where I don't want the output to go.
For further confirmation, I tried to execute the program from another directory again without giving it any input:
user#computer_name:~/Dev/project/unittests$ .././executable
to be greeted yet again with this error:
.././project: symbol lookup error: .././project: undefined symbol: _ZN7library7class11functionEv
So far I've tried to rebuild entire project, generate new Makefiles etc.
I also confirmed that there are no issues with the program itself. Any ideas on how to fix this issue or alternative ways to direct output to different folder without having to pass specific output arguments to the program itself?
If you want executable to pick up the libexecutable.so next to it, you have two options:
Configure LD_LIBRARY_PATH to contain /home/user/Dev/project.
This will make the dynamic linker search there before any other configured directories.
Either do this globally or in a wrapper script.
Compile executable with an rpath. This will make library lookups by executable look in the rpath first. If you pass the -Wl,-rpath,'$ORIGIN'/.. flag (note the single quotes around $ORIGIN!), the dynamic linker will always find libexecutable.so next to executable first.

Where can i find library "version.lib" in order to successfully call GetFileVersionInfoSize()?

I'm developing a project on DevC++ which uses MinGW64. On Windows 7 (i don't know if this can be related to my issue).
I had a problem compiling a C++ program where I call the function GetFileVersionInfoSize(), which is:
main.cpp:(.text+0x51): undefined reference to `GetFileVersionInfoSizeA'
After two days of researching, I understood that I have to include in the parameters of the linker the "version.lib" file, which is missing in my computer, I searched it everywhere.
I can't even find a download mirror on the web, so I'm asking, does anybody know where I can find version.lib? Maybe somewhere hidden in my PC or in the web? Maybe with a new installation of MinGW64? I don't know, since my installation of MinGW64 came with DevC++.
Thanks for reading.
Thank all you guys for the suggestions you gave me
In this answer there is how to find Version.lib in this case.
The following is about accomplishing using GetFileVersionInfoSize(), GetFileVersionInfo() and VerQueryValue() to get the Product Name of an executable file, which is why I needed Version.lib, actually being called libversion.a on my machine.
LAST-EDIT: I managed to achieve what I wanted, this is the code that works in my case:
// filename contains the path of the .exe we want to get Product Name
int version_info_size = GetFileVersionInfoSize(filename, NULL);
if(version_info_size > 0) {
BYTE *version_info_buffer = new BYTE[version_info_size];
if(GetFileVersionInfo(filename, 0, version_info_size, version_info_buffer)) {
char *product_name = NULL;
UINT pLenFileInfo = 0;
if(VerQueryValue(version_info_buffer, TEXT("\\StringFileInfo\\040904e4\\ProductName"),
(LPVOID*)&product_name, &pLenFileInfo)) cout << product_name;
}
}
Notice that if you want to compare product_name with another value, you have to do something like string product_name_str = product_name and compare that string variable, otherwise the comparison will always return false. Or maybe just do (string)product_name, I should try.
040904e4 is the lang-code hex translation that I needed in order to do this, I found it thanks to the code in this answer.
Since it's a environment built for GCC, library names will follow Nix conventions:
Start with lib: libversion
Extension can be either .so or .a (depending on the library being dynamic or static)
Typically (depending on default MinGW installation), it should reside in ${MINGW_INSTALL_DIR}/x86_64-w64-mingw32/lib/libversion.a. One installation example is: f:\Install\Qt\Qt\Tools\mingw730_64\x86_64-w64-mingw32\lib\libversion.a.
According to [Archive.Web - MinGW]: HOWTO Specify the Location of Libraries for use with MinGW (Determining MinGW's Default Library Search Path section), it can be retrieved by:
[cfati#cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow]> x86_64-w64-mingw32-ld.exe --verbose | grep SEARCH_DIR | tr -s ' ;' \\012
SEARCH_DIR("=/usr/x86_64-w64-mingw32/lib")
SEARCH_DIR("=/usr/local/lib")
SEARCH_DIR("=/lib")
SEARCH_DIR("=/usr/lib")
But since it's a system library, you shouldn't care about its path, MinGW should find it automatically, all you have to do is pass it to the linker (using the standard ways).

Qt-creator and ncurses: initscr() not found

I am on Xubuntu x64 and I want to use ncurses in my software. This software is being build with Qt Creator 4.8. I have no problems including the ncurses.h file, but when I want to use functions of ncurses (initscr() and endwin()) I get the following errors:
Undefined reference to 'endwin'
Undefined reference to 'initscr'
What steps should I take to fix this problem?
I have installed the following ncurses related packages:
libncurses5:amd64
libncurses5:i386
libncurses5-dbg
libncurses5-dev
libncursesw5:amd64
libncursesw5:i386
libncursesw5-dbg
libncursesw5-dev
ncurses-base
ncurses-bin
ncurses-examples
I found out (finally)
The right way to do it: rightclick your project->add library -> system library
Here you need the path to the *.so file (so not *.so.5 or something), which was in my case
/usr/lib/x86_64-linux-gnu/libncurses.so
Then add it and tadaaa: done.
and I also found this guide may be it works, to me none has worked yet
http://www.lucidarme.me/?p=3961
"In the .pro file of the project, add the following line to specify to the compiler it has to use the ncurses library:
LIBS += -lncurses
To avoid the following error message : “Error opening terminal: unknown.”, add a variable in the run environment of Qt. Project -> Run -> Run environment -> add. Add a variable named TERM and set it of xterm."
UPD: my problem solved by checking the "Run in terminal" option in Projects->Run.

cannot not find library files in eclipse cdt

properties/C/C++ Build/Settings
GCC C++ Linker/Libraries
Under libraries(-I) I have
libbost_system
libbost_filesystem
...
and under Library search path(-L) I have
/home/etobkru/boost_1_43_0/boostBinaries/lib
but when I compile I get
g++ -L/home/etobkru/boost_1_43_0/boostBinaries/lib/ -o"searchDirs" ./main.o -llibboost_system -llibboost_filesystem -llibboost_regex
/usr/lib/gcc/i586-suse-linux/4.1.2/../../../../i586-suse-linux/bin/ld: cannot find -llibboost_system
I have tried with libbost_system.so and libbost_system.a but i get the same error. What am I doing wrong and why cant eclipse find the files. Because they are there?
You don't need the "lib" part in the name. Just link with
-lboost_system -lboost_filesystem -lboost_regex
I think this is similar to /usr/bin/ld: cannot find -llibeststring.a
Did you try -lboost_system? The -l option doesn't expect the leading lib or the trailing .a or .so.
I know it's a little after the fact, but you can try -l:libbost_system.so and it will look for a library with exactly that name.
Actually after much frustration I decided to read the man page for ld!
l namespec
--library=namespec
Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of times. If namespec is of the form :filename, ld will search the library path for a file called filename, otherwise it will search the library path for a file called libnamespec.a.
since my specific library was something along the lines of myfoobar.dll nothing worked until I realized I wanted ld to use the actual filename. As others have posted with screenshots how to add the library to the linker all I needed to do was change 'myfoobar' in the field to ':myfoobar.dll' and it worked fine.
You should use the ':' to get really specific on the filename to search for and stay away from the default file name formatting that is expected without it. Hope this eases frustration.
Krusty,