Runtime path and AIX executables - linker

I am aware that one can build in a runtime search path into an executable at compile time. I want to understand how to display that path after the executable has been compiled but within the context of AIX!
Looked in Google but not finding answer.

Related

Is it possible provide relative path to __FILE__ macro if static library is build with GCC and CMake?

I am working on integrating a few static libraries in one application. All libraries are build with GCC and CMake. Unfortunately CMake provide absolute paths to compilation command, what cause macro __FILE__ to be absolute path from build machine. If I am debugging library on other machine I am not able to locate file due to wrong path. In project tree I have access to libraries sources. I would like macro __FILE__ to point to relative path from project root.
Is it possible to achieve this with CMake and GCC?
CMake now uses only absolute path and GCC sets macro __FILE__ according to path received in command, so it seems that it is impossible to solve this.
The answer is: yes, it is possible to resolve this issue. Unfortunately not by providing relative path.
We modify path provided in file by -ffile-prefix-map option. We set all files path absolute to project root. Last step is to inform debugger where project root is. Due to fact that project location is constant to project root it will work on all machines.
Solution we used:
cmake_path(NORMAL_PATH PROJECT_ROOT OUTPUT_VARIABLE PROJECT_ROOT_NORMALIZED)
add_compile_options(-ffile-prefix-map=${PROJECT_ROOT_NORMALIZED}=./)
All credits to starball who posted a comment with the idea and article providing solution.
If link dies, article is named An introduction to deterministic builds with C/C++ and is on Conan (package manager) blog.

Compiling in a dynamic C library (dylib) into a program on OS X

I've written a little C program which uses libusb. Now I want to distribute this program to "normal" (not dev) Mac OS X computers. But when I ported the compiled file to a test machine I got the following error:
dyld: Library not loaded: /opt/local/lib/libusb-0.1.4.dylib
Referenced from: /Users/kitty/myprogram
Reason: image not found
Trace/BPT trap: 5
When I copy the files (works only with all the files)
/opt/local/lib/libusb-0.1.4.dylib /opt/local/lib/libusb-1.0.a
/opt/local/lib/libusb.a
/opt/local/lib/libusb-1.0.0.dylib /opt/local/lib/libusb-1.0.dylib
/opt/local/lib/libusb.dylib
from my machine to the target machine the program works flawlessly.
But I really want to create or compile everything into a single executable. How is this possible?
Using -static while compiling does not work since not all libraries can be compiled into the final app statically (see this SO question here).
So how can I make a single neat little application file?
You can convert a static library to a dynamic library, but I'm not aware of a way to do the reverse as you want it.
If you're building an app with a bundle, you need to put the library you want to distribute inside your bundle, in the Frameworks directory, and link against that.
If you are not building a bundle-based app, just a single binary, you may need to provide instructions for your users on how to install the library on their system (e.g. via Homebrew).
Here's how you do it for bundle-based apps:
Apple has a document about run-path dependent libraries but doesn't actually explain how to set this up for a newbie.
Here's how it should work:
Add the libusb.dylib you want to use to your project.
It should automatically get added to your "Link Binary with Libraries" phase in your project's "Build Phases". If not, add it here.
Add a new "Copy Files" build phase.
In the "Destination" drop-down box, select "Frameworks". This is the
Frameworks directory in your app's final bundle.
Then press the "+" icon in that copy build phase and add your library.
If you had any manual linking options like -L/usr/local/lib and -lusb, remove them.
Clean and build.
When you now look into your app bundle, you'll see that the library is copied to <bundle_path>/Contents/Frameworks/. You can now start the app from wherever you want, the dynamic link loader knows it needs to look at <path_to_binary>/../Frameworks/ to find your library.
But: you may need to rebuild your libusb to have the install_name set to #rpath/../Frameworks/libusb.dylib or use the install_name_tool CLI tool fix that path for your copy of libusb.dylib that you added to your project.

UNIX: Cannot find file or directory after cross-compiling a binary that uses shared object files

I am able to successfully cross-compile a binary file that can run on an ARM system such as Rasberry Pi. Without linking to a third-party library, normal C++ code runs on the device successfully (I.E. cout << "Hello World!" << endl;).
The issue I'm running into is that when I run the executable after it's been linked against a third-party library, I get the standard UNIX error "No such file or directory." when the binary tries to access the shared object file. I have the file it's looking for copied into the usr/lib folder, the usr/local/lib folder, and the folder where the executable is sitting itself.
Also, I went and added a good value to LD_LIBRARY_PATH so the runtime linker can search at these locations. My guess is that the "system" maybe hiding these files from the executable?
And to add more information, I ran the readelf command on the binary and the shared object file and it gives me the proper descriptions of the file. It tells me that the binary file is a 32-bit file and requires this shared object library file that I mentioned it cannot find. Even during link time in the build phase, I add the following linker command -Wl,-rpath, to set the location of where to look for the shared object file. Please note I'm compiling on a Macintosh Machine, and not on the Rasberry Pi itself. Hence cross-compiling.
I have a feeling it's a setting, because the object file is visible/valid in multiple locations. If anyone has experienced this before, please any advice is appreciated. Thanks in advance.
I actually figured out the problem recently.
The problem was that I was using Eclipse. The third party library files I was using were named in the format "libSHAREDFILENAME.so". Eclipse doesn't like that very much when setting up which libraries to use in the IDE. It expects you to strip off the "lib" and the ".so" portion from the file name. So a file named "libSHAREDOBJECT.so" should be referenced as "SHAREDOBJECT" in Eclipse. It doesn't like the "lib" prefix or the ".so" suffix.

How can I link the source path of a compiled library to a different location in Eclipse?

I've installed the msp430-gcc compiler and associated tools to do some open-source msp430 development at home using Eclipse. I'm developing on a slightly older Macbook Pro running OS X Lion and installed the tools using MacPorts. I'm running Eclipse 3.7.2 with the CDT and GCC Cross Compiler Support plug-ins. I have a simple empty main() written that compiles and links just fine.
The ELF parser lets me view the contents of the ELF binary just fine with the exception of one component; when I try to view the contents of the startup code in crt0.S, it gives me a blank file. When I click on the crt0.S component of the ELF, the filename bar at the bottom of the Eclipse window shows "/opt/local/var/macports/build/_Volumes_work_mports_dports_cross_msp430-gcc/msp430-gcc/work/gcc-4.6.3/gcc/config/msp430/crt0.S". This makes sense because of my MacPorts install of msp430-gcc. crt0.S is archived into /opt/local/lib/gcc/msp430/4.6.3/libcrt0.a on my machine.
What I want to be able to do is tell Eclipse to look elsewhere for the source files for the libraries that are automatically linked when I build with the msp430-gcc toolchain. This would presumably include everything in /opt/local/lib/gcc/msp430/4.6.3/. I started by downloading the source for mspgcc-20120406 (the version in my MacPorts install) and applying the gcc patchfile to an empty directory tree. This created the gcc/config/msp430 directory, including the crt0.S and crt0ivtbl.S files.
What I have had no luck accomplishing is telling Eclipse to look in ~/Developer/mspgcc-20120406/gcc-4.6.3/config/msp430/ instead of the path that's in the already-built libcrt0.a. I tried playing around with the Project Preferences->Paths and Symbols->Source Location window, but didn't have much luck. I searched through this website and on Google and the closest thing I came up with was this question but it doesn't "smell" like the right answer.
I would like to avoid solutions that involve moving the library source into my project. I'd rather have a solution that will work for multiple projects.
All help is greatly appreciated! Thanks in advance.
Try and check if the Eclipse linked resource could help you declare that external directory from within your Eclipse project here.
Linked resources are files and folders that are stored in locations in the file system outside of the project's location. These special resources can be used to add files and folders to your project that for some reason must be stored in a certain place outside of your project. For example, a linked folder can be used to store build output separately from your source files.
I find interesting how you can define that linked resource:
Linked resource target paths can be either defined as absolute paths, or relative to a path variable.
Since you can define it relative to (for instance) your Eclipse project location PROJECT_LOC, you can then setup your resource in a way which won't change between two environments.

Linking with -R and -rpath switches on Windows

I,m using gcc compiler(MinGW) on Windows XP.I created a .dll library libdir.dll than I tried to build a program that is using that library.
I don't want to put that .dll file into System or System32 folder nor to set path to it in PATH variable, what i want is to give that information to the program itself.
I know there is a -R and -rpath switches available so i was gonna link it with one of them.
First -rpath:
gcc -L/path/to/lib -Wl,-rpath,/path/to/lib main.o -ldir -o prog
Than -R:
gcc -L/path/to/lib -Wl,-R,/path/to/lib main.o -ldir -o prog
This links successfully into prog but when i start the program Windows prints message that it cannot find libdir.dll.
So my question is what went wrong, why path to libdir.dll is not known in runtime even when I'm using appropriate switches?
Let's say i have prog1 and prog2 each containing their own copy of libdir.dll and both of them start to run at the same time loading code in the library.What happens in memory is there a two copies loaded or linker figures out that there is a copy and uses that for both programs?
Second question is about how libraries are loaded(any OS).Does linkers always load entire library or just parts needed?For example if program references function foo() which is in the library, does linker maps into memory only that function or entire library first?
There are only two real alternatives: put the DLL in the same folder as the EXE or put it in the working directory for the EXE. The latter being not much of an option since you'd have to create a shortcut to make the default working directory different from the directory that contains the EXE.
Not putting the DLL in the same directory as the EXE only makes sense if you want to share the DLL with other applications. To avoid the inevitable DLL hell this causes, you'd need to store the DLL in the side-by-side cache. The tooling you need to create the manifest and embed it in the EXE and the installer you'd need to deploy the DLL to the target machine are probably hard to come by with your tool chain. It is very rarely done anyway.
Part of this question is a duplicate of this one: Is there a Windows/MSVC equivalent to the -rpath linker flag?
The summary of the answer is that there is no direct equivalent of RPATH on Windows.
Since you precluded placing your DLLs in the default library search path (which on Windows includes the system directories you listed and the directories in the PATH environment variable), you are left with these options:
using batch files
placing all the DLLs and executables in the same directory
making OS-level calls in your program for adding to the DLL search path

Resources