LLVM still and will not support for static link openmp? - linker

every one.
I am curious about did clang can't static link the openmp library when compliling. When i try to build spec2017 intspeed benchmarks, I found when i try to build them staticly, will failed with error cannot find -lomp.
/usr/lib/llvm-10/bin/clang -m64 -z muldefs -pthread -static -DSPEC_LINUX_X64 -DSPEC_OPENMP -fopenmp -Wno -return-type -DUSE_OPENMP -I /usr/lib/lib/libomp_oss/exports/common/include av.o caretx.o deb.o doio.o doop.o dum p.o globals.o gv.o hv.o keywords.o locale.o mg.o numeric.o op.o pad.o perl.o perlapi.o perlio.o perlmain.o perly.o pp.o pp_ctl.o pp_hot.o pp_pack.o pp_sort.o pp_sys.o regcomp.o regexec.o run.o scope.o sv.o taint.o toke.o univers al.o utf8.o util.o reentr.o mro_core.o mathoms.o specrand/specrand.o dist/PathTools/Cwd.o dist/Data-Dumper/Dumper. o ext/Devel-Peek/Peek.o cpan/Digest-MD5/MD5.o cpan/Digest-SHA/SHA.o DynaLoader.o dist/IO/IO.o dist/IO/poll.o cpan/ MIME-Base64/Base64.o Opcode.o dist/Storable/Storable.o ext/Sys-Hostname/Hostname.o cpan/Time-HiRes/HiRes.o ext/XS- Typemap/stdio.o ext/attributes/attributes.o cpan/HTML-Parser/Parser.o ext/mro/mro.o ext/re/re.o ext/re/re_comp.o e xt/re/re_exec.o ext/arybase/arybase.o ext/PerlIO-scalar/scalar.o ext/PerlIO-via/via.o ext/File-Glob/bsd_glob.o ext /File-Glob/Glob.o ext/Hash-Util/Util.o ext/Hash-Util-FieldHash/FieldHash.o ext/Tie-Hash-NamedCapture/NamedCapture. o cpan/Scalar-List-Utils/ListUtil.o -lm -fopenmp -L/usr/lib/lib/libomp_oss/exports/lin_32e/lib -o perlbench_s
/usr/local/bin/ld: cannot find -lomp
So, i searched the llvm lib for omp, only find libomp.so, but no omp realated .a file. Then found the posted mail of wheather need static openmp library, seem like LLVM developers reject this opinion.
https://lists.llvm.org/pipermail/openmp-dev/2016-January/001051.html
Did i miss something, or is there someway can link openmp staticly i not found?
Thanks for your suggestions.
I did build those spec benchmarks use llvm10 and llvm15 with dynamic link on ubuntu20.04, all found the -lomp, build successfully.

Related

version node not found for symbol

I've build a shared library on my desktop that uses statically linked gstreamer and gstreamer plugins (base, good, rtsp-server).
Now I'm trying to compile the library using yocto but its giving me a linker error:
version node not found for symbol _IO_do_write##GLIBC_2.17
failed to set dynamic section sizes: Bad value
The solutions I found on stack overflow did not seem to help me.
use compiler with --disable-symvers
link libc libs in different orders (-ldl -lm -lc -lpthread -ltinfo -lrt)
link libc libs statically/shared
What I find particularly odd is that the linker is looking for GLIBC_2.17 while yocto uses 2.27 and my system is using 2.24. I don't know if this matters or if it is normal (the function did not change since 2.17?).
NM -C shows the symbol in libc.a:
nm -C recipe-sysroot/usr/lib/libc.a | grep IO_do_write
U _IO_do_write
U _IO_do_write
0000000000001ba8 W _IO_do_write
So I would thinks that lib is linked incorrectly?
The linker command is a long one because of all the shared libs so I shortend it a bit (removed boost and custom libs):
aarch64-poky-linux-g++ -fPIC --sysroot=recipe-sysroot -O2 -pipe -g -feliminate-unused-debug-types -fdebug-prefix-map=recipe-root/git-r0 -fdebug-prefix-map=recipe-sysroot= -fdebug-prefix-map=recipe-sysroot-native= -fvisibility-inlines-hidden --sysroot=recipe-sysroot -Wl,-allow-multiple-definition -Wall -Wextra -Wpedantic -Wsuggest-override -Wswitch-default -Wduplicated-cond -Wshadow -Werror -ftemplate-depth=1024 -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -lc -Wl,--no-as-needed -Wl,--no-undefined -pthread -ldl -shared -Wl,-soname,rtsp_streamer.so -o rtsp_streamer.so ... custom static libs .and boost static libs ... -lpthread recipe-sysroot/usr/lib/gstreamer-1.0/libgstrtsp.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstrtp.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstrtpmanager.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstcoreelements.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstadder.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstapp.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstaudioconvert.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstaudiorate.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstaudioresample.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstaudiotestsrc.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstgio.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstpango.a recipe-sysroot/usr/lib/gstreamer-1.0/libgsttypefindfunctions.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideoconvert.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideorate.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideoscale.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideotestsrc.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvolume.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstautodetect.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideofilter.a recipe-sysroot/usr/lib/libBrokenLocale.a recipe-sysroot/usr/lib/libBrokenLocale_pic.a recipe-sysroot/usr/lib/libanl.a recipe-sysroot/usr/lib/libanl_pic.a recipe-sysroot/usr/lib/libatomic.a recipe-sysroot/usr/lib/libatomic_ops.a recipe-sysroot/usr/lib/libatomic_ops_gpl.a ... more boost static libs ... recipe-sysroot/usr/lib/libc.a recipe-sysroot/usr/lib/libc_nonshared.a recipe-sysroot/usr/lib/libc_pic.a recipe-sysroot/usr/lib/libcidn_pic.a recipe-sysroot/usr/lib/libcrypt.a recipe-sysroot/usr/lib/libcrypt_pic.a recipe-sysroot/usr/lib/libcrypto.a recipe-sysroot/usr/lib/libdl.a recipe-sysroot/usr/lib/libdl_pic.a recipe-sysroot/usr/lib/libg.a recipe-sysroot/usr/lib/libgomp.a recipe-sysroot/usr/lib/libgstallocators-1.0.a recipe-sysroot/usr/lib/libgstaudio-1.0.a recipe-sysroot/usr/lib/libgstbase-1.0.a recipe-sysroot/usr/lib/libgstcheck-1.0.a recipe-sysroot/usr/lib/libgstcontroller-1.0.a recipe-sysroot/usr/lib/libgstfft-1.0.a recipe-sysroot/usr/lib/libgstpbutils-1.0.a recipe-sysroot/usr/lib/libgstreamer-1.0.a recipe-sysroot/usr/lib/libgstriff-1.0.a recipe-sysroot/usr/lib/libgstrtp-1.0.a recipe-sysroot/usr/lib/libgstrtsp-1.0.a recipe-sysroot/usr/lib/libgstrtspserver-1.0.a recipe-sysroot/usr/lib/libgstapp-1.0.a recipe-sysroot/usr/lib/libgstnet-1.0.a recipe-sysroot/usr/lib/libgstsdp-1.0.a recipe-sysroot/usr/lib/libgsttag-1.0.a recipe-sysroot/usr/lib/libgstvideo-1.0.a recipe-sysroot/usr/lib/libhistory.a recipe-sysroot/usr/lib/libitm.a recipe-sysroot/usr/lib/liblicensing.a recipe-sysroot/usr/lib/libm.a recipe-sysroot/usr/lib/libm_pic.a recipe-sysroot/usr/lib/libmcheck.a recipe-sysroot/usr/lib/libncurses++.a recipe-sysroot/usr/lib/libncurses++w.a recipe-sysroot/usr/lib/libnsl.a recipe-sysroot/usr/lib/libnsl_pic.a recipe-sysroot/usr/lib/libnss_compat_pic.a recipe-sysroot/usr/lib/libnss_db_pic.a recipe-sysroot/usr/lib/libnss_dns_pic.a recipe-sysroot/usr/lib/libnss_files_pic.a recipe-sysroot/usr/lib/libnss_hesiod_pic.a recipe-sysroot/usr/lib/libnss_nis_pic.a recipe-sysroot/usr/lib/libnss_nisplus_pic.a recipe-sysroot/usr/lib/libprotobuf-lite.a recipe-sysroot/usr/lib/libprotobuf.a recipe-sysroot/usr/lib/libprotoc.a recipe-sysroot/usr/lib/libpthread.a recipe-sysroot/usr/lib/libpthread_nonshared.a recipe-sysroot/usr/lib/libreadline.a recipe-sysroot/usr/lib/libresolv.a recipe-sysroot/usr/lib/libresolv_pic.a recipe-sysroot/usr/lib/librpcsvc.a recipe-sysroot/usr/lib/librt.a recipe-sysroot/usr/lib/librt_pic.a recipe-sysroot/usr/lib/libsqlite3.a recipe-sysroot/usr/lib/libssl.a recipe-sysroot/usr/lib/libssp.a recipe-sysroot/usr/lib/libssp_nonshared.a recipe-sysroot/usr/lib/libstdc++.a recipe-sysroot/usr/lib/libstdc++fs.a recipe-sysroot/usr/lib/libsupc++.a recipe-sysroot/usr/lib/libthread_db_pic.a recipe-sysroot/usr/lib/libutil.a recipe-sysroot/usr/lib/libutil_pic.a recipe-sysroot/usr/lib/libz.a recipe-sysroot/usr/lib/librt.a recipe-sysroot/usr/lib/libpthread.a recipe-sysroot/usr/lib/libm.a recipe-sysroot/usr/lib/libc.a
Does anybody know what is wrong? If more info is needed please ask. Thanks in advance!
Does anybody know what is wrong?
I suspect that you are not linking against GLIBC-2.27 from Yocto, but against some other GLIBC, though it is hard to see how that could happen.
Your first step should be to find out which libc.so.6 is actually being used. You can do so by adding -Wl,-t flag to your link line. Also add -Wl,-y,_IO_do_write while you are at it.
After you know which libc.so.6 is being used, run readelf -Ws /path/to/libc.so.6 | grep _IO_do_write to see what (if any) versioned symbols are defined in it.
I don't know if this matters or if it is normal (the function did not change since 2.17)?
Yes: that is normal -- the function didn't change its ABI since GLIBC-2.17, so that's the version that is attached to it.
I figured out what went wrong. The shared library is build using a CMAKE project and our own written FindGSTREAMER.cmake. To find gstreamer, among other things, a glob is used to find all the static libs. Because on my desktop I have gstreamer installed in its seperate location this works. With Yocto however this causes every static lib in the recipe-sysroot/usr/lib directory to be linked. Including every libc library (.a, _pic.a and .so). Apparently this causes the linker unable to resolve the symbols.
Correctly filtering the libraries needed by gstreamer fixed the problem.

Openmp decreases the running time in my Rcpp code, but not in my Rccp package [duplicate]

I am developing an R package on Mac OSX with some low level C/C++ code and openMP support. The C++ code is written using Rcpp package. My global ''Makevars'' file is placed under ~/.R/ folder. The file looks like following.
CC=clang-omp
CXX=clang-omp++
PKG_CFLAGS=Wall -pedantic
PKG_CFLAGS= -fopenmp
PKG_CXXFLAGS= -fopenmp
PKG_LIBS= -fopenmp -lgomp
Everything works great under this configuration!
However, now I want to build package-specific Makevars file for its own compilation to make the package portable. What I tried was simply move the global Makevars file into my R pakcage src folder. However, the compiler complained about that it cannot find the openMP header file omp.h:
** libs
clang++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/bigmemory/include" -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/BH/include" -fopenmp -fPIC -Wall -mtune=core2 -g -O2 -c RcppExports.cpp -o RcppExports.o
RcppExports.cpp:12:10: fatal error: 'omp.h' file not found
#include <omp.h>
^
1 error generated.
make: *** [RcppExports.o] Error 1
clang++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/bigmemory/include" -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/BH/include" -fopenmp -fPIC -Wall -mtune=core2 -g -O2 -c RcppExports.cpp -o RcppExports.o
RcppExports.cpp:12:10: fatal error: 'omp.h' file not found
#include <omp.h>
^
1 error generated.
make: *** [RcppExports.o] Error 1
As you can see, the compilers become clang and clang++, but not what specified in the Makevars files: CC=clang-omp and CXX=clang-omp++.
Question 1: So how could I fix this issue and build a Makevars file within the R package?
Another thing is that, I noticed from Writing R extensions that,
For example, a package with C code written for OpenMP should have in src/Makevars the lines
PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS)
Question 2: What is the difference between, for example, macro $(SHLIB_OPENMP_CFLAGS) and flag -fopenmp? which one under which circumstance should I use? I tried to replace the flags with the macros, but still cannot fix the issue.
Regarding question, my favourite approach is to copy from working packages. Here is eg the part from (recommended / Core) package mgcv:
PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) $(SHLIB_OPENMP_CFLAGS)
PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
I use the same snippet in the smaller winsorize package (on GitHub) by myself and Andreas.
Regarding question 2: The first form is more general and would allow other OpenMP implementations. It uses what R found to be useable when it was configured.
It sounds like you need the package Makevars as Dirk describes; for your local environment, have ~/.R/Makevars setting your C and C++ compilers to your OpenMP enabled versions using CC and CXX.
Your package (if destined for CRAN, and indeed any Mac R users who haven't battled to install an OpenMP version of clang) will need to work without OpenMP, so your code and compiler flags probably shouldn't assume its presence.

Specify OpenMP to GCC

For OpenMP, when my code is using the functions in its API (for example, omp_get_thread_num()) without using its directives (such as those #pragma omp ...),
why directly specifying libgomp.a to
gcc instead of using -fopenmp
doesn't work, such as
gcc hello.c /usr/lib/gcc/i686-linux-gnu/4.4/libgomp.a -o hello
Update: I just found that linking to libgomp.a does not work, but linking to libgomp.so works. Does it mean OpenMP can not be static linked?
Why -fopenmp only works without
specifying the library files
gcc hello.c -fopenmp -o hello
Update: In other words, when using -fopenmp, why explicit linking to libgomp.so is not required?
Why does this also compile:
gcc hello.c -L/usr/lib/gcc/i686-linux-gnu/4.4/ -lgomp -o hello
Will this ignore OpenMP directives
in the code if there is any?
Thanks and regards!
In general, keep in mind that the directives and the functions are different things; the former are controlled by -fopenmp and the latter are controlled by linking to the OpenMP library.
(Updated to incorporate comments) Try using the -fopenmp and -static options to statically link OpenMP. Because this implies -lgomp -lrt, the following command won't compile correctly unless you also specify the location of librt.a.
gcc hello.c /usr/lib/gcc/i686-linux-gnu/4.4/libgomp.a -o hello
(Updated to incorporate comments) I imagine that the following command is compiling correctly because the OpenMP library is already in your library path and your system's dynamic linker is automatically linking with libgomp.so.
gcc hello.c -fopenmp -o hello
The following command is probably compiling properly because it is linking to the shared object for OpenMP (libgomp.so). Note that the -static option is not used.
gcc hello.c -L/usr/lib/gcc/i686-linux-gnu/4.4/ -lgomp -o hello
If you don't specify the -fopenmp option, OpenMP directives should be ignored.

cmake: altering the linker command

This probably very easy when you know how, but I don't :)
I'm trying to build some code that takes uses opengl/glut. I'm using the cygwin version of cmake opengl etc. The only reference I see to opengl/gult is in the CMakeLists.txt:
find_package(OpenGL REQUIRED)
find_package(GLU REQUIRED)
find_package(GLUT REQUIRED)
Everything works fine up till the linking stage, which ends with:
CMakeFiles/glview.dir/glview.c.o: In function `DrawGLScene': /cygdrive/C/code/libfreenect/examples/glview.c:88: undefined reference to `__imp__glutSwapBuffers#0'
CMakeFiles/glview.dir/glview.c.o: In function `keyPressed': /cygdrive/C/code/libfreenect/examples/glview.c:96: undefined reference to `__imp
etc.
After a git of googling I figured out this because cmake is feading the linker a -lglut flag, when it should be feading it a -lgut32 flag. By manually executing the linking command, I can get the program to build:
/usr/bin/gcc.exe -Wall -O3 -g -Wl,--enable-auto-import CMakeFiles/glview.dir/glview.c.o -o glview.exe -Wl,--out-implib,libglview.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -L/cygdrive/C/code/libfreenect/lib ../lib/libfreenect.a -lGL -lGLU -lglut32 -lm -lpthread -lusb-1.0
But I can't figure out how to get cmake to generate this command for me so no manual steps are needed. Any ideas what I should be doing?
Cheers,
Rob
this is how to add libraries to link to:
target_link_libraries( ${TargetName} gut32 )
find_package only assures the package is found, no more.

Can I mix static and shared-object libraries when linking?

I have a C project that produces ten executables, all of which I would like to be linked in statically. The problem I am facing is that one of these executables uses a 3rd-party library of which only the shared-object version is available.
If I pass the -static flag to gcc, ld will error saying it can't find the library in question (I presume it's looking for the .a version) and the executable will not be built. Ideally, I would like to be able to tell 'ld' to statically link as much as it can and fail over to the shared object library if a static library cannot be found.
In the interium I tried something like gcc -static -lib1 -lib2 -shared -lib3rdparty foo.c -o foo.exe in hopes that 'ld' would statically link in lib1 and lib2 but only have a run-time dependence on lib3rdparty. Unfortunatly, this did not work as I intended; instead the -shared flag overwrote the -static flag and everything was compiled as shared-objects.
Is statically linking an all-or-nothing deal, or is there some way I can mix and match?
Looking at this thread you can see that it can be done. The guys at GNU suggest
gcc foo.c -Wl,-Bstatic -lbar -lbaz -lqux -Wl,-Bdynamic -lcorge -o foo.exe

Resources