Unresolved sincos during build of LAPACK - android-ndk

Following the instructions here I have built a Fortran enabled NDK toolchain (OSX, NDK-7b) with the goal of building LAPACK/BLAS.
Using android-cmake with the 3.4.0 net lib source it seems that I'm nearly successful. However, the BLAS build fails when linking one of the tests (with an error stating unresolved sincos and sincosf). A little searching reveals that these functions are not available in legacy Android versions. I'm wondering what is the best way to resolve these functions?
Below is and example of a linking error:
cd /Users/marc/software/lapack-3.4.0/Android/BLAS/TESTING && /opt/local/bin/cmake -E cmake_link_script CMakeFiles/xblat2c.dir/link.txt --verbose=1
/opt/local/share/java/android-ndk-macosx/toolchains/arm-linux-androideabi-4.7.0/prebuilt/darwin-x86/bin/arm-linux-androideabi-gfortran -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,--fix-cortex-a8 -Wl,--no-undefined -lstdc++ -lsupc++ CMakeFiles/xblat2c.dir/cblat2.f.o -o ../../bin/xblat2c -rdynamic -L/Users/marc/software/lapack-3.4.0/Android/systemlibs/armeabi-v7a -L/opt/local/share/java/android-ndk-macosx/toolchains/arm-linux-androideabi-4.7.0/prebuilt/darwin-x86/user/libs/armeabi-v7a ../../lib/libblas.a -lm -Wl,-rpath,/Users/marc/software/lapack-3.4.0/Android/systemlibs/armeabi-v7a:/opt/local/share/java/android-ndk-macosx/toolchains/arm-linux-androideabi-4.7.0/prebuilt/darwin-x86/user/libs/armeabi-v7a
/opt/local/share/java/android-ndk-macosx/toolchains/arm-linux-androideabi-
4.7.0/prebuilt/darwin-x86/lib/gcc/arm-linux-androideabi/4.7.0/../../../../arm-linux-androideabi/lib/libgfortran.a(c99_functions.o): In function cexpf':
/opt/local/share/java/android-ndk-macosx/src/build/../gcc/gcc-4.7.0/libgfortran/intrinsics/c99_functions.c:910: undefined reference tosincosf'

GCC needs to know at compile time whether sincos is available or not. It does so based on the target. In case of the target triplet arm-linux-androideabi, it looks at gcc/config/linux.h and finds there:
/* Whether we have sincos that follows the GNU extension. */
#undef TARGET_HAS_SINCOS
#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC)
The reason for the inclusion of Bionic is that Android 2.3 added support for sincosf/sincos/sincosl [1]. Thus, you can either update Bionic or you patch GCC to assume that no sincos is available; cf. also [2].
[1] http://source-android.frandroid.com/bionic/libc/docs/CHANGES.TXT
[2] https://bugs.launchpad.net/linaro-android/+bug/908125

Related

Is it possible to compile a standalone Fortran executable in Linux?

For example, consider that I wrote a Fortran program in one computer and want to run it on another computer which may not have required libraries and/or has a different compiler (or even better, no Fortran compiler at all). Is it possible to create an executable with all its dependencies?
I am using gfortran (7.2.1) in Fedora 26 and sometimes use LAPACK routines in my code.
Using -static option with the program
program main
write (*,*) 'Hello'
end
I get the output
gfortran -static a.f90
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
There is no error with gfortran -static-libgfortran a.f90
In Fedora, gcc does not ship by default with static libraries.
You need to install the package glibc-static for the -static option to work, as hinted in this related question.
Note that -static-libgfortran will only do static linking of the libgfortran library and that you must have static versions of your dependencies as well.
The best option is to use Alpine Linux that uses musl libc. I highly recommend using the docker image (only 5 Mb).

How do I link libraries from multiple locations (corresponding to multiple GCC versions)?

I am currently trying to use Oracle Linux 6 OS on a SPARC S7 server to run the NPB benchmarks (with OpenMP multithreading support). The OS comes preloaded with gcc 4.4.7, which is missing the Niagara 7 optimizations. I downloaded devtoolset-3 from the Oracle Yum Repository, which has gcc 4.9.2 installed in /opt/rh/devtoolset-3/root/usr/bin. However, when I compile the NPB benchmark using the newer gcc, it automatically links to libraries associated with the older gcc 4.4.7 (located in /usr/lib). This caused my program to segfault during execution. I believe that it is because libgomp 4.4.7 is incompatible with libgomp 4.9.2. I have tried several ways of linking to the libraries in the gcc 4.9.2 folder (which is /opt/rh/devtoolset-3/root/usr/lib/gcc); none of the methods work:
-Xlinker -rpath=lib_location
-Wl -Bstatic
-L lib_location
The closest I got was when using -Wl -Bstatic ~/libgomp.a or -static -L ~/libgomp.a. It fails to find libraries such as libm that reside in the default gcc lib folder (usr/lib).
The actual command used to link is:
/opt/rh/devtoolset-3/root/usr/bin/gcc -O3 -fopenmp -mcmodel=medmid -static -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2 -o ../bin/bt.W.x bt.o initialize.o exact_solution.o exact_rhs.o set_constants.o adi.o rhs.o x_solve.o y_solve.o solve_subs.o z_solve.o add.o error.o verify.o ../common/print_results.o ../common/c_timers.o ../common/wtime.o -lm -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2/lib/
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lm
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lrt
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lpthread
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lc
Is there a way I can link just the libgomp library from gcc 4.9.2 while linking the remaining libraries from gcc 4.4.7?
The devtoolset compilers are all using the system libgcc, libstdc++, version 4.4.7, and can therefore not compile e.g. c++11.
I guess the gcc53-c++-5.3.0-1.el6.x86_64.rpm will do. Comes with the internal */gcc53/lib64{libgcc_s.so**, libgomp.so**, libstdc++} (version 5.3.0) ... Provides /usr/bin/{ gcc53, g++53 }
The package was created a year ago ... well tested, as extra compiler. Download link : https://drive.google.com/file/d/0B7S255p3kFXNbTBneHgwSzBodFE/view?usp=sharing
If you're going to do the -Wl,-Bstatic thing, make sure to follow it immediately by -Wl,-Bdynamic to reset to normal after your added library argument. By default, not all system libraries have static versions installed, which is why you get e.g. cannot find -lc.
So you can try this as a modification of your workaround:
-Wl,-Bstatic ~/libgomp.a -Wl,-Bdynamic
Not pretty, and this question deserves a much better answer (this is still pretty much a hack), but it should get the job done for now.

musl fails to link libc.a into shared library

I have a C99 shared library that I want to link in a few statically static libraries (via --whole-archive). Note: All the static libs are built with -fPIC
I also would like to build a universal linux binary and thus have decided to use musl. When I try to link in the static libc.a from musl I get the following error:
# Building shared library tgt/Linux-x86_64/mylib/lib/mylib.so
/root/mylib/./tgt/Linux-x86_64/libmusl/bin/musl-gcc -Wl,-whole-archive -L./tgt/Linux-x86_64/libmusl/lib -L./tgt/Linux-x86_64/libz/lib -L./tgt/Linux-x86_64/libssl/lib -L./tgt/Linux-x86_64/libsasl/lib -L./tgt/Linux-x86_64/librdkafka/lib -L./tgt/Linux-x86_64/libcurl/lib -L./tgt/Linux-x86_64/libgjalloc/lib -L./tgt/Linux-x86_64/libavro/lib -L./tgt/Linux-x86_64/libunwind/lib -l:libc.a -l:libpthread.a -l:libz.a -l:libssl.a -l:libcrypto.a -l:libsasl2.a -l:libm.a -l:librt.a -l:libcrypt.a -l:libunwind-x86_64.a -l:librdkafka.a -l:libcurl.a -l:libgjalloc.a -l:libavro.a -Wl,-no-whole-archive -shared -fPIC -o tgt/Linux-x86_64/mylib/lib/mylib.so ./tgt/Linux-x86_64/mylib/obj/myfile.o ./tgt/Linux-x86_64/mylib/obj/myotherfile.o ./tgt/Linux-x86_64/mylib/obj/cJSON.o
/usr/bin/ld: ./tgt/Linux-x86_64/libmusl/lib/libc.a(exit.lo): relocation R_X86_64_PC32 against undefined hidden symbol `__fini_array_start' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
make: *** [tgt/Linux-x86_64/mylib/lib/mylib.so] Error 1
My musl build looks like:
cd mystatic_libs_build_dir/musl; \
./configure CFLAGS='-fPIC' \
--enable-shared \
--enable-static \
--prefix=/root/mylib/tgt/Linux-x86_64/libmusl; \
make; make install;
# libmusl is available
exit.lo will be written in assembler which is why your CFLAGS='-fPIC' is not having the effect you intend. This is either 1. a bug in 'musl' or 2. intentional and they do not support statically linking into .so's.
I would assume that it is unintentional and file a bug against 'musl'
You could also edit the asm yourself if you need a fix quickly.
Finally you might be able to configure musl to build with no asm?
Slightly off topic, but other options for a universal binary are:
Simply linking against glibc on the oldest version of Linux that you support.
Rather than struggling with a dependency on 'musl', simply use the Linux kernel api's directly.
Recompile musl as long as your own code with CFLAGS="-fPIC -Wa,-mrelax-relocations=no" (your binutils version must be >=2.27).

error Compile shared libraries with -fPIC

While I run snmpd daemon on powerpc board(a.p.) I am getting this error:
R_PPC_REL24: Compile shared libraries with -fPIC!
/usr/local/sbin/snmpd: symbol 'strlen': can't handle reloc type 0xa in lib
/lib/libnetsnmpmibs.so.15'
sh: you need to specify whom to kill
I googled and found that the -fPIC flag should be there while compiling and its place should be right after gcc, so I changed my Makefie accordingly. Here is a snippet of my makefile:
$(Q)cd $(PROJECT_BUILD_DIR)/$(NET_SNMP_PKG) && ./configure --target=$(TARGET_TRIPLET) \
--host=$(HOST_TRIPLET) \
--build=$(BUILD_TRIPLET) \
--with-cc="$(CR_COMPLR)gcc -fPIC" \`
--with-cflags="-Os -I$(RFS)/lib -I$(NMS_DIR)/include" \`
--with-linkcc="$(CR_COMPLR)gcc -fPIC" \`
As you can see I embedded -fPIC right after gcc, but I am still getting an error. I have cross compiled for powerpc platform and I am using latest buildroot-2011.11 and gcc 4.3.6 and uClibc version 0.9.32. What may be the cause of error?
P.S. When I do nm libnetsnmpmibs.so.15 | grep strlen then I get output as U strlen. Does this mean it is undefined?
I got the problem. actually the main thing is to compile with -fPIC only.
In my case I was compiling snmp libraries with -fPIC correctly but some of the functions were dependent on libraries of other packages (nms). As I am working on firmware development there are more than 20 packages involved. So I compiled nms libraries with -fPIC and error is resolved.

How to compile OpenCV with ICC?

I am trying to compile OpenCV with icc on Linux, in order to profile the execution with intel tools.
I installed the last version of icc with default options. I tried both "user" (icc is installed in my home) and "sudo" (icc is intalled in /opt) installs. The version of icc is 11.1 20090630
I also thought to source iccvars.sh, adding needed paths to PATH and LD_LIBRARY_PATH
I also tried several versions of OpenCV:
- the main one: pre1.1. configure does not recognize icc at all
- the 'latest_tested_snapshot' and the 'trunk' versions: icc is well recognized by configure (--enable-openmp produce -openmp option, and not -fopenmp)
When I make, everything seems all right until the middle of the compilation. Then come a lot of warnings (maybe a hundred) always about 'operator'. Here an example:
../include/opencv/cxcore.hpp(335): warning #597: "cv::Size_<_Tp>::operator cv::Size_<float>() const [with
_Tp=float]" will not be called for implicit or explicit conversions
operator Size_<float>() const;
^
detected during instantiation of class "cv::Size_<_Tp> [with _Tp=float]" at line 394
And finnally the error:
/bin/bash ../../../libtool --tag=CXX --mode=compile icpc -DHAVE_CONFIG_H -I. -I../../.. -I../../../include/opencv -I. -DCV_NO_BACKWARD_COMPATIBILITY -fPIC -I/usr/include/python2.6 -g -O2 -MT _highgui_la-pyhelpers.lo -MD -MP -MF .deps/_highgui_la-pyhelpers.Tpo -c -o _highgui_la-pyhelpers.lo `test -f 'pyhelpers.cpp' || echo './'`pyhelpers.cpp
_ml.cpp(36134): error: argument of type "uchar={unsigned char} *" is incompatible with parameter of type "int *"
result = (int)(arg1)->get_ord_var_data(arg2,arg3,arg4,arg5,(float const **)arg6,(uchar const **)arg7);
^
_ml.cpp(36134): error: argument of type "const uchar={unsigned char} **" is incompatible with parameter of type "const int **"
result = (int)(arg1)->get_ord_var_data(arg2,arg3,arg4,arg5,(float const **)arg6,(uchar const **)arg7);
^
compilation aborted for _ml.cpp (code 2)
make[4]: *** [_ml_la-_ml.lo] Erreur 1
I anyone succeded to compile OpenCV with icc, let me know!
Ok, I finally compiled OpenCV with ICC. OpenCV is close to Intel, as Intel is highly involved in this project. Since version 1.1, OpenCV is supposed to natively support icc compiler. When you specify CC=icc in configure, there are some subtle changes as the -fopenmp (gcc style) in transformed into -openmp (icc style). However, between the release of OpenCV 1.1 (which is the latest stable) and now, icc has evolved. I think it used to compile with previous version of icc.
It comile with the latest tested version on svn:
https://opencvlibrary.svn.sourceforge.net/svnroot/opencvlibrary/tags/latest_tested_snapshot/opencv/
As the svn evolve, it could change, but at this time (27 august) it works. The warnings are still here (don't be affraid, there are a lot). Here my configure bash line:
./configure --prefix=/home/user/opencv/icc CC=icc CXX=icpc --enable-openmp --disable-apps --disable-optimization --disable-sse
I disabled optimizations and sse instructions, as it generates some conflicts with icc.
Your issue may result from using a different version from ICC used to create that library. You must ask the library provider which version to use.

Resources