warnings when trying to statically link cross compiled Fortran 90 code to run on Aarch64-linux - one being "relocation truncated to fit" - hyperlink

I am able to cross compile some Fortran 90 code (large block written by someone else so do not want to convert it) using x86_64 GNU/Linux as the build system and aarch64-linux as the host system and using dynamic linking. However, I want to generate a statically linked binary so added -static to the mpif90 call. When I do this, I get this warning:
/home/me/CROSS-REPOS/glibc-2.35/math/../sysdeps/ieee754/dbl-64/e_log.c:106: warning: too many GOT entries for -fpic, please recompile with -fPIC
When I add this flag as in "mpif90 -static -fPIC" the same error appears. Also tried -mcmodel=large option as in "mpif90 -static -mcmodel=large" to no avail.
Then checked the options for "/home/me/CROSS-JUL2022/lib/gcc/aarch64-linux/12.1.0/../../../../aarch64-linux/bin/ld", I see this one, --long-plt (to generate long PLT entries and to handle large .plt/.got displacements). But trying "mpif90 -static -Wl,--long-plt" says --long-plt is not an option. How to invoke this --long-plt option then?
One other thing, I know static linking will make the binaries a fair amount bigger but do not want to carry libs over to the Android device. Furthermore, some reading is indicating that dynamic linking on the Android device could lead to some security issues. Thanks for any suggestions.

Related

How to get bitcode llvm after linking?

I am trying to get LLVM IR for a file which is linked with some static libararies.
I tried to link using llvm-link . It just copy the .bc files in one file ( not like native linking).
clang -L$(T_LIB_PATH) -lpthread -emit-llvm gives an error: emit-llvm can not be used with linking. When passing -c option, it gives warning that the linking options were not used.
My main goal is to get .bc file with all resolved symbols and references. How can I achieve that with clang version 3.4.?
You may have a look at wllvm. It is a wrapper on the compiler, which enable to build a project and extract the LLVM bitcode of the whole program.
You need to use wllvm and wllvm++ for C and C++, respectively (after setting some environment variables).
Some symbols come from source code via LLVM IR. IR is short for intermediate representation. Those symbols are easy to handle, just stop in the middle of the build process.
Some others come from a library and probably were generated by some other compiler, one that never makes any IR, and in any case the compiler was run by some other people at some other location. You can't go back in time and make those people build IR for you, even if their compiler has the right options. All you can do is obtain the source code for the libraries and build your entire application from source.

Why doesn't -L automatically include -rpath when shared library is used?

I don't get why it is necessary to provide either rpath or set env varible using LD_LIBRARY_PATH when -L already tells where the shared Library path is.
this answer says: -L tells ld where to look for libraries to link against when linking.
But why at the same time the corresponding -rpath is not set automatically? why do we need to do it manually again?
P.S: I guess if you had that feature, then the executable would be useless in some other environment. But if it is so then what ld actually does during linking, or why it is necessary to give -L path if -rpath in some other environment is different.
It's definitely not a "misfeature of the linker".
-L (a much older flag) simply tells the linker to look in that directory for any library that matches any subsequent -l flag, including static libraries/archives (remember, in times of yore, this was the only kind of library). It intentionally remains a link-time only flag; it has no effect after the linker's business is complete.
-rpath is an entirely different beast. Its purpose is to embed in an executable or shared/dynamic library a list of one or more paths to search for dynamic libraries, when the necessary symbols are looked up in shared libraries at runtime (the r in -rpath).
There are many instances where one would want -L but not -rpath; particularly when one specifically wants to link a static library rather than defer to the dynamic linker. It is relatively trivial on most platforms to override a built-in rpath, i.e., with the LD_PRELOAD environmental variable, and some actually consider this a security issue.
Perhaps ake a look at http://sta.li/faq for a compelling case against dynamic linkage.

Cross-compiling FontForge to iOS

I am trying to cross compile FontForge's libs and binaries to armv7 but I seem to be running into several major issues.
Firstly, I am using SDK7.0 on Xcode 5.0.1.
On my first configure, I got several "error: cannot check for X while cross compiling"
Once I bypassed this, I realized the program was looking for Carbon (deprecated in the iOS SDK files for a long time now.)
Once I moved the old SDK files over, a TON of files were giving errors about unknown types (from _types.h, and all of its associated headers) most notable ssize and off_t. Even after tinkering with these, I eventually get an "unsupported architecture" being reported from the sdk.
Here is my configure command:
./configure '--with-programs=yes' '--without-spiro' '--with-x=no' '--enable-static' '--with-cairo=no' '--without-python' '--with-pango=no' '--prefix=/Users/thebertolet/fontforge-ios' '--host=arm-apple-darwin' 'CC=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc' 'CFLAGS=-mthumb -arch armv7 -miphoneos-version-min=5.1 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/ -I/Users/thebertolet/freetype-ios/include/freetype2/ -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/usr/include/libxml2/' 'LDFLAGS=-mthumb -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/ -miphoneos-version-min=5.1'
Also of note: all of the required libs were required and reported to the program. I guess my specific problem is the program trying to locate files that either don't exist or are somewhat unusable to armv7.
Alternatively, does anyone know of a great way (other than fontforge) to break ttc and combine ttf's?
This is very likely to be totally impossible. You can likely use the fontforge internals behind a Cocoa Touch front end, but fontforge is an X11 app in its native form with a custom widget set, and the only X servers for iOS seem to be for remote use of desktop Unix apps. You may have better luck on Android.

How to make an object file that cannot be dead_stripped?

What is the easiest way to produce a Mach-O object file that does not have the SUBSECTIONS_VIA_SYMBOLS flag set, such that the linker (with -dead_strip) will not later try to cut the text section into pieces and guess which pieces are used?
I can use either a command-line option to llvm/gcc (4.2.1) that will prevent it from emitting .subsections_via_symbols in the first place, or a command-line tool that will remove the flag from an existing object file.
(Writing such a tool myself based on the Mach-O spec is an option, but if possible I'd rather not reinvent the wheel that hard).
Platform: iOS, cross-compiling from OSX with XCode 4.5.
Background: We're supplying a static library that other companies build into apps. When our library encounters a problem it produces a crash report with a stack trace and certain other key information that (if we're lucky) we get to analyze later. Typically the apps as deployed have been stripped of debug information so interpreting stack traces is a problem. If we were making the app ourselves we would just save the DWARF debug data from before stripping and use that to decode the addresses in the incoming crash reports. But we can't depend on the app makers supplying us with such data from their linking steps.
What we're doing instead is to let the crash report include the run-time address of selected function; from that we can deduce the offset between addresses in our linker map and addresses in the crash report. We're linking our entire library incrementally into a single .o before we stuff it into an .a; since it does only one big thing there wouldn't be much to save from removing unused functionality from it when the app is eventually linked. Unfortunately there's a few small pieces of code in the library that are sometimes not used (alternative API entry points for the main functionality, small helper functions for interpreting our error codes and the like), and if the app developer links with -dead_strip, it disturbs the address reconstruction of crash reports that the relative offsets in the final app differ from the linker map from our incremental link operation.
We can't realistically ask all app developers to disable dead-code stripping in their build process, so it seems a better way forward if we could mark our .o as "not dead-strippable" and have the eventual app linking respect that.
I solved it.
The output of an incremental link operation only has MH_SUBSECTIONS_VIA_SYMBOLS set if all the input objects have it set. And an object file produced from assembler input only has it set if there's an explicit directive set. So one can remove the flag by linking with an empty assembler input:
echo > empty.s
$(CC) $(CFLAGS) input.o empty.s -nostdlib -Wl,r -o output.o

force cmake to compile openCV with llvm

Background
My goal is to compile OpenCV for ios with support for the armv7s (the s is the hard part) architecture but have been unable to make any progress. My most recent theory is that the problem is that the cmake files that come with the library use gcc as a compiler which I do not think supports armv7s (if I am wrong please tell me). I am completely new to cmake however and have not been able to change the compiler.
The reason I suspect the compiler is because of the line
set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_BIT)" CACHE string "Build architecture for iOS")
which as far as I know should include armv7s. Changing that line to
set (CMAKE_OSX_ARCHITECTURES "armv6;armv7;armv7s;i386" CACHE string "Build architecture for iOS")
had no effect.
I know there are explanations of how to set the compiler here, here, and here. My problem is that I am trying to change an existing cmake system and don't know what ramifications my changes could have. The code in question can be downloaded here. To build the framework I run the python script in OpenCV-2.4.2/ios
python build_framework.py ~/Desktop
from what I can tell the relevant cmake files are located in OpenCV-2.4.2/ios/cmake. There are only 3 and all are fairly short. My most recent attempt was to change two lines in the toolchains
CMAKE_FORCE_C_COMPILER (gcc gcc)
CMAKE_FORCE_CXX_COMPILER (g++ g++)
to
SET (DEVROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer")
SET (CC "${DEVROOT}/usr/bin/llvm-gcc-4.2")
SET (CXX "${DEVROOT}/usr/bin/llvm-g++-4.2")
CMAKE_FORCE_C_COMPILER (${CC} CLang)
CMAKE_FORCE_CXX_COMPILER (${CXX} CLang)
in an attempt to copy this SO question.
Question
My first and most important question is if this is out of my depth. I have been assuming that changing the compiler/target architecture would be a simple flag set somewhere but I am becoming less convinced that is true. Also, there is an entire directory OpenCV-2.4.2/cmake filled with much larger cmake files that I have been avoiding in the hopes I don't need to worry about their contents. Is this a problem I am going to be able to solve in less than 10 hours?
If you answered yes to the previous question, can you give me any direction? Suggested reading? Am I justified in ignoring the contents of OpenCV-2.4.2/cmake? I have been shooting in the dark for quite a while now without success.
If it turns out this is as simple as I originally hoped, how do I do it?
Update
I never did figure out how to do this, but there is an xcode version of the library here from which the compiling settings can be changed easily.
Set CMAKE_C_COMPILIER and CMAKE_CXX_COMPILIER to what you need.
Edit: this supposes you already had success with building this for armv7.
Edit2: this will just change the compiler.
I see a lot of links in your question, but didn't find original link with information how to cross compile with CMake.
You should not change anything in existing build system.
In general you need to create toolchain file for your target architecture and run cmake with it.
cmake -DCMAKE_TOOLCHAIN_FILE=< your toolchain file > < path to CMakeLists.txt from opencv >

Resources