Qt app with dependencies on mac - dependent sdk has #executable_path in otool list... how do I change it? - c++

I am trying to build/run/deploy a qt app on mac. It has, among other dependencies, an sdk that I have placed in a lib folder... and set the path in the pro file. The app builds fine, but I cannot execute it.
Running otool -L myapp shows, for this particular sdk:
#executable_path/../Frameworks/blah.0.dylib
If I could copy the dylib in a folder like "/usr/local/lib/" i would be able to make it work I think... But have no admin rights.
Without admin rights, I cannot search the system to see what location it may have... but oddly, even without admin rights i can ls /Libraries/Frameworks and it only contains Qt frameworks at the moment. ls /Frameworks tells me that /Frameworks doesn't exist. neither does Frameworks (relative to the app dir)
Placing the dylib in the same folder as my app doesn't work (I guess mac is not windows lol). I am looking for alternatives, but also will need to deploy this app so I must do the install_name_tool to convince the linker that the dylib is inside the bundle I am creating.
The problem is, as much as I understand it from the qt-4.8/deployment-mac.html page, that I need the original location of the app - the original id.
mkdir myapp.app/Contents/Libraries
cp lib/blah.0.dylib myapp.app/Contents/Libraries
install_name_tool -id #executable_path/../Libraries/blah.0.dylib myapp.app/Contents/Libraries/blah.0.dylib
install_name_tool -change path/to/blah.0.dylib #executable_path/../Libraries/blah.0.dylib myapp.app/Contents/MacOs/myapp
So, the question is: for the 4th step, what do I use for path/to/blah.0.dylib ? I imagine it is the path the linker thinks it is now... but how do I ask him ? Also... since the previous id has "Frameworks" in its name, can I replace it with "Libraries" ?
Edit: one step forward:
install_name_tool -change myapp.app/Contents/Frameworks/blah.0.dylib #executable_path/../Libraries/blah.0.dylib myapp.app/Contents/MacOs/myapp
the above has the correct address now... but it doesn't work.
Placing blah.0.lib in the Frameworks folder will allow the linker to find it. But install_name_tool doesn't seem able to change that path.
oddly, install_name_tool was able to change some paths for the linker but not others - and once ran with a typo on a name (for a different lib dependency which initially did not have a defined id), I was unable to change it...
How do I remove such a linker path ? How do I change the path once set ?

your app is a package,
your app is a special package called a bundle.
your app bundle is a directory...
YourApp.app/
Contents/
Resources/
<images, plists, core data models, etc.>
MacOS/
yourApp <-- this is the actual executable
Frameworks/ <- optional frameworks directory
blah.dyld goes here
the #executable_path is expanded to what ever the MacOS/yourApp is
the dynamic linker is then looking for your dyld in YourApp.app/Contents/Frameworks/... but I assume it isn't there, so you need to add a build phase to copy it there.

Related

How to rename bazelisk to bazel

I am currently trying, without great success, to build tensorflow from source.
As suggested here: https://www.tensorflow.org/install/source, I tried to do so by installing bazelisk. Unfortunately, I wasn't able to do so as the ./compile cannot find bazel as bazelisk replaces it.
This link: https://github.com/bazelbuild/bazelisk/issues/122 suggested to alias or rename the environment variable to "bazel" in the PATH.
As described in the issue above, aliasing did not work out for the configure.py.
My next step would be to rename it but I, unfortunately, was not able to figure out how the renaming of environment works under Linux.
I did add the following:export PATH=$PATH:$(go env GOPATH)/bin
to my .profile under my /home folder, which, the way I understand it, adds the path to Bazelisk binaries to my environment path but I am not sure how the renaming would work in this situation.
Would it be possible to explain how I could proceed?
Download the bazelisk binary from the releases page and save the file as bazel in a directory somewhere in your $PATH.
For example, if you have export PATH=$PATH:$HOME/bin in your .profile/.bashrc/.bash_profile, and in $HOME/bin, store the bazelisk binary as $HOME/bin/bazel.
You can have 2 more options:
sudo ln -s /usr/local/bin/bazelisk /usr/local/bin/bazel which makes a symlink to bazelisk (personally i prefer it, because its more explicit)
alias bazel='bazelisk' in your ~/.zshrc, ~/.bashrc or ~/.profile. This also works well, but there could be some issues if you want to run vim-bazel and such.

Qt Creator: cannot open shared object file after moving library to subdir

I have a project where the library sources were set up the following way:
MyProject
|_MyProject.pro
|_MainStuff
|_MainStuff.pro
|_ManyFiles
|_Tests
|_Tests.pro
|_LotsOfTests
|_MyLibs
| FunLibs.pro
|_FunLib1.h
|_FunLib1.cpp
|_FunLib2.h
|_FunLib2.cpp
This is not ideal, because as the number of FunLibs increases, all of it would be included into a single shared object. With this setup, everything builds and runs just fine. Just to be clear: MyProject.pro is a subdirs template, the MainStuff.pro is an app template, and the FunLibs is a lib template.
The problem stats, when I rearrange the files the following way:
MyProject
|_MainStuff
|_ ManyFiles
|_Tests
|_LotsOfTests
|_MyLibs
|_MyLibs.pro
|_FunLib1
|_FunLib1.pro
|_FunLib1.h
|_FunLib1.cpp
|_FunLib2
|_FunLib2.pro
|_FunLib2.h
|_FunLib2.cpp
Here the MyLibs.pro becomes a subdir tempalte, while the FunLibx.pro files will be lib templates. All configurations have been updated accordingly and the application builds. The problem is that when I now try to launch the application, the following message pops up:
libFunLib1.so.1: cannot open shared object file: No such file or
directory
I don't really understand why doesn't it work now, when it worked with the previous directory structure. This post for example (as many others) recommends to set the LD_LIBRARY_PATH by exporting the dir, but to be honest, I didn't have to do this with the previous setup.
I also have everything set up pretty much as described in the official docs under the "Creating a shared library" part.
Does anybody have an idea what might be the problem? Is there a way to solve this by not exporting the path?
Thanks in advance.
OK, I think I found out what can fix the aforementioned problem. Qt Creator also uses LD_LIBRARY_PATH environment variable for executing compiled programs, but it is somewhat hidden. As it turns out, it is able to use separate sets of env variables for compiling and running applications, and if the env vars for running are not properly defined, the user will get the error message mentioned in the original post, even if the program compiled properly.
To make sure all lib paths are included for running as well, one needs to check out the included paths here:
Projects (mode) --> Run Settings (under Build & Run) --> Run
Environment (expand the Details) --> LD_LIBRARY_PATH (somewhere in the
list)
If that var doesn't include the proper paths, it can be edited after which it is going to get highlighted. After setting this, everything seems to work.

CMake 3 Bootstrapping and g++ problems

I am working on a Linux Redhat server. I am trying to Bootstrap my CMake 3 download files as per How to download, compile, and install CMake on Linux.
I changed 2 lines in the bootstrap file so that I would be using the appropriate GCC/G++ versions:
# Toolchain compiler name table.
cmake_toolchain_Clang_CC='clang'
cmake_toolchain_Clang_CXX='clang++'
# cmake_toolchain_GNU_CC='gcc'
cmake_toolchain_GNU_CC='/inf/projdig/users/{username}/gcc_install/bin/gcc'
#cmake_toolchain_GNU_CXX='g++'
cmake_toolchain_GNU_CXX='/inf/projdig/users/{username}/gcc_install/bin/g++'
cmake_toolchain_PGI_CC='pgcc'
cmake_toolchain_PGI_CXX='pgCC'
cmake_toolchain_PathScale_CC='pathcc'
cmake_toolchain_PathScale_CXX='pathCC'
cmake_toolchain_XL_CC='xlc'
cmake_toolchain_XL_CXX='xlC'
But, it seems like bootstrap is still referencing some compiler-related files in the root directories even though I want it to only reference these:
/inf/projdig/users/{username}/gcc_install/bin/gcc and
/inf/projdig/users/{username}/gcc_install/bin/g++
Please see this error:
What should I change in the Bootstrap file so that nothing in /usr/... is referenced, and only
/inf/projdig/users/{username}/gcc_install/bin/gcc and
/inf/projdig/users/{username}/gcc_install/bin/g++
are referenced?
UPDATE
Okay, I did manage to fix some problems by specifying
-L/{path to correct libstdc++} compiler option.
However, at the very end of the bootstrap script, this line doesn't work:
I can't just fix it by adding a -L compiler option because this does not invoke a compiler. It's invoking CMake. This command above produces the same error (ie. it searches /usr/lib64 for the libraries, which is the path I don't want it to look through). How can I let CMake look at a different path for libraries? What option should I specify after .../cmake ?

Linux - SO file not found

I have a program which requires liblog4cpp installed to run.
Now, I want the program to run on another machine without liblog4cpp. So I just find the log4cpp.so and move it to the same directory of my program. But at running error reported:
error while loading shared libraries: liblog4cpp.so.4: cannot open
shared object file: No such file or directory
Am I doing it right? How can I tell the program to find the SO file just beside it?
In addition to what others are suggesting, consider adding the file to the dynamic linker's cache. You can do it like this:
ldconfig -l /path/to/lib/liblog4.so.4
To add it to the loader's cache use the following command: ldconfig
Then in order to verify that it was correctly added, run this:
ldconfig -v | grep liblog
Check your LD_LIBRARY_PATH environment variable... One of the directories on the path should point to the location of your log4cpp.so file; also the linux command ldd is handy for determining which shared object libraries are being used in your executable. The syntax is ldd <executable>.
assuming that the path where the .so file/s is available is /path you can also avoid to export an environment variable and just use
LD_LIBRARY_PATH=/path ./myProgram
beware the fact that if you do:
export LD_LIBRARY_PATH=/path
you are resetting LD_LIBRARY_PATH to a single value /path and losing anything you added before to this environment variable. If you want to add a value without losing the previous ones
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path
export LD_LIBRARY_PATH to the path of the library. This env variable works much like the PATH variable. It can contain multiple paths separated by :.
In the rc script from where you are launching your program, you should set the LD_LIBRARAY_PATH before launching the application. Remember, the .so are the shared libraries, it is required at the run time to link. Thus, it should be available in the standard path like /usr/lib before launching.
In case it is not copied in the standard path like /usr/lib then specify the path by using the following.
export LD_LIBRARY_PATH=<new_path_of_so>:$(LD_LIBRARY_PATH)
Ideally, I would have placed this .so in the standard path like /usr/lib. If it is installed in the standard path, then there is no need to set the above path. Remember, to make your program better, put the new path in ldconfig.conf.
You can debug such errors by using the following.
$strace <binary_name>
to know the so dependencies
$ldd <binary_name>
For further, check the below link.
http://www.tune2wizard.com/sharedobject-crash/
After adding shared objects (or shared libraries lib*.so*, or such symbolic links) to system directories like /usr/lib or /lib known to the dynamic linker ld-linux.so(8) (or ld.so) you need to run ldconfig(8)
You could also add them to /usr/local/lib/ but then be sure that /etc/ld.so.conf (or some file /etc/ld.so.conf.d/*.conf) .mentions that directory (and run ldconfig after changing it)

boost thread link fails in Netbeans 7.1 debugging/testing session

I am developing an app on Netbeans, while I can run it. I can not debug or reun the test files. When I try to do so, I get:
./build/Debug/GNU-Linux-x86/tests/TestFiles/f1: error while loading shared libraries: libboost_thread.so.1.49.0: cannot open shared object file: No such file or directory
It tried including the library or the specific file with the debugging or testing session, but I continue to get that. Could there be an inconsistency with Netbeans?
Any ideas would be greatly appreciated!
I assume your OS is Linux. It follows from your email that you have access to the copy of the libboost_thread.so.1.49.0 file. Let DIR be directory where this library exists.
If you do not have superuser on this computer, use method A. If you have superuser, use method A or method B.
Method A. Good for non-superuser or for superuser.
Let DIR be directory in which library libboost_thread.so.1.49.0 exists.
I assume you can start NetBeans from shell command line, not from GUI icon.
Quit NetBeans. Execute following command in bash:
export LD_LIBRARY_PATH=DIR:$LD_LIBRARY_PATH
start netbeans from command line
Eventually, you will want to put the export command into your ~/.bashrc file.
Method B. Good only for superuser.
If you have superuser, use one the following methods to place the missing library into /usr/lib or /lib:
(1) install boost from rpm or apt or whatever packaging your linux system has, or
(2) install boost from sources with --prefix=/usr, or
(3) copy the mentioned library to /usr/lib. If you have to use #3, be careful about symlinks. Copy using "cp -a" and copy all files beginning libboost_thread.so*, like
cp -a DIR/libboost_thread.so* /usr/lib