CMake: How can I force cmake to static link openmp? - c++

I know the way to use cmake to link openmp in a cross-platform way
find_package(OpenMP REQUIRED)
link_libraries(OpenMP::OpenMP_CXX)
But I don't know how to force cmake to static link openmp, in fact, all of cmake official variable about openmp library is all dynamic.
Anyway, The non-cross-platform way to do so is:
clang++ -std=c++2a test.cpp -Iinclude -march=native -O3 -c
clang++ test.o -o test.x /usr/local/lib/libomp.a -pthread
or if you use gcc
g++-10 -std=c++2a test.cpp -Iinclude -march=native -O3 -c
g++-10 test.o -o test.x /usr/local/opt/gcc/lib/gcc/10/libgomp.a -pthread
By the way, is it a cmake defect or is there any other way to accomplish it

Not an answer but too much to fit into a comment.
I don't know anything about OpenMP other than cmake does support it:
https://cmake.org/cmake/help/latest/module/FindOpenMP.html?highlight=openmp.
I don't see any of the documentation referring to static/shared. Maybe you are correct and it only support shared libs.
Double check by asking the official make discourse:
https://discourse.cmake.org/
You could also try reading the official FindOpenMP.cmake module since this is all open source.
EDIT:
If you are correct cmake is lacking this functionality consider contributing and adding it :)

Related

Compilation failing on EnableABIBreakingChecks

I recently installed LLVM v8.0.0 (on RHEL 7.4). I am going through the LLVM Kaleidoscope tutorial to learn how to use the system, but am running into an issue linking.
Per the tutorial (end of chapter 2), I run:
clang++ -g -O3 kld.cpp `llvm-config --cxxflags` -o kld
It compiles, but the linker fails on:
/tmp/kld-f7264f.o:(.data+0x0): undefined reference to `llvm::EnableABIBreakingChecks'
clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
I suspected this may have been an issue with llvm-config, so I also tried using the --ldflags and --system-libs flags, but no luck.
llvm-config --cxxflags gives (reformatted for readability)
-I~/project/llvm-src/include -I~/project/llvm-build/include
-fPIC -fvisibility-inlines-hidden
-std=c++11
-Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual
-Wno-missing-field-initializers -pedantic -Wno-long-long
-Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment
-g
-fno-exceptions -fno-rtti
-D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
Where ~/... is just the path to my home directory (edited for privacy; the actual output is a fullpath). I am working on a shared system that requires I install new software locally.
The tutorial code never references ABI explicitly, so I assume this must be some kind of compiler-flags issue. greping for the missing symbol in non-binary files gives an extern declaration in include/llvm/Config/abi-breaking.h and the real declaration in lib/Support/Error.cpp:
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
int EnableABIBreakingChecks;
#else
int DisableABIBreakingChecks;
#endif
I thought I would try re-compiling, then, with -DLLVM_ENABLE_ABI_BREAKING_CHECKS. That also does that work.
I'm not really clear what the ABI breaking checks are doing in the first place, and this may be way over my C++ comfort level. But how can I silence this error, if I don't need the referenced functionality; or fix it, if i do?
Thanks.
Turns out the answer was hidden in abi-breaking.h:
/* Allow selectively disabling link-time mismatch checking so that header-only
ADT content from LLVM can be used without linking libSupport. */
#if !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
I'm not sure if I'll need libSupport down the line, but compiling with LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1 works for the time being.
Add linkage with LLVMSupport library will also solve this problem.
With this CMake snippet:
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
add_executable(main main.cpp)
target_link_libraries(main LLVMSupport)
Based on the discussion in llvm irc channel.
Try the following command to compile : clang++ -O3 -c $(llvm-config --cxxflags) source_file.cpp -o obj_code.
Then try linking with this command : clang++ obj_code $(llvm-config --ldflags --libs) -lpthread.
I think linking part doesn't mentioned in the kaleidoscope section. The above solution worked for me.
I don't know the influence and reason why it works. But when I add -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING, the errors disappear.
clang++ xxx -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
ref:
https://www.coder.work/article/6278120
https://blog.csdn.net/qq_37887537/article/details/112790961

Undefined reference to boost::system::detail::system_category_instance that gets fixed when switching from C++14 to C++11

I am trying to build my C++ application that uses boost 1.68.0. On trying to build it using cmake followed by make, I get the following linking errors,
/usr/local/bin/g++ -Wall -Wextra -g3 -std=c++14 -Wl,-rpath=/usr/local/lib -L/usr/local/lib CMakeFiles/Supervisor.dir/HeartbeatManager.cpp.o CMakeFiles/Supervisor.dir/JobReceiver.cpp.o CMakeFiles/Supervisor.dir/ResultSender.cpp.o CMakeFiles/Supervisor.dir/Supervisor.cpp.o CMakeFiles/Supervisor.dir/Process.cpp.o -o Supervisor -rdynamic -lpthread -lboost_system-mt
CMakeFiles/Supervisor.dir/HeartbeatManager.cpp.o: In function `boost::system::system_category()':
/usr/local/include/boost/system/error_code.hpp:473: undefined reference to `boost::system::detail::system_category_instance'
On switching the -std=c++14 flag with -std=c++11, the error disappears. I got the idea from this answer. I do not know why that fixes it. Now in my project I cannot use -std=c++11 flag instead of the -std=c++14 flag.
You'll have to recompile boost specifying cxxstd=14.

Armadillo issue in ubuntu

I have been writing a c++ program in Ubuntu and window8 using armadillo. Under Windows8 the program compiles without problems.
The program is just using the linear systems solver.
Under Ubuntu the compiler says
"reference to `wrapper_dgels_' not defined"
The compiler line I use is:
mpic++ -O2 -std=c++11 -Wall -fexceptions -O2 -larmadillo -llapack -lblas program.o
However, right before the error I see:
g++ module_of_the_error.o
Which is something I haven't set.
I am using code blocks in Ubuntu, and I compiled armadillo with all the libraries that cmake asked. (BLAS< LAPACK, OpenBLAS, HDF5, ARPACK, etc)
I have no clue what might be causing the problem, since the exact same code compiles in visual studio.I have tried the compiler line modifications suggested but it does not seem to work.
Any help is appreciated.
This is one trap I fell into myself one time. You will not like the likely cause of your error.
The order of the arguments to the linker matters.
Instead of
mpic++ -O2 -std=c++11 -Wall -fexceptions -O2 -larmadillo -llapack -lblas program.o
try:
mpic++ -O2 -std=c++11 -Wall -fexceptions -O2 program.o -larmadillo -llapack -lblas
I.e., put the object files to be linked into the executable before the libraries.
By the way, at this stage you are only linking files that have already been compiled. It is not necessary to repeat command line options that are only relevant for compiling. So this will be equivalent:
mpic++ program.o -larmadillo -llapack -lblas
Moreover, depending on how you installed Armadillo, you are adding either one or two superfluous libraries in that line. One of the following should be enough:
mpic++ program.o -larmadillo
or
mpic++ program.o -llapack -lblas
EDIT: as the answer by rerx states, the problem is probably just a simple ordering of the switches/arguments supplied to g++. All the -l switches need to be after the -o switch. Or in other words, put the -o switch before any -l switches. For example:
g++ prog.cpp -o prog -O3 -larmadillo
original answer:
Looks like your compiler can't find the Armadillo run-time library. The proper solution is to specify the path for armadillo run-time library using the -L switch. For example, g++ -O2 blah.cpp -o blah -L /usr/local/lib/ -larmadillo
Another possible solution is to define ARMA_DONT_USE_WRAPPER before including the armadillo header, and then directly link with LAPACK and BLAS. For example:
#define ARMA_DONT_USE_WRAPPER
#include <armadillo>
More details are available at the Armadillo frequently asked questions page.

clang: warning: -lgtest: 'linker' input unused

I'm developing applications in C++11 and my compiler is CLang++ 3.3. I'm also using Netbeans 7.3 IDE on Linux Mint 14.
All of my tests are done with GoogleTest (gtest-1.6.0) and almost everything is working fine except the warning mentioned in the title of this post.
Here's the command line executed by netbeans as an example:
clang++ -pedantic-errors -lgtest -pthread -c -g -Wall -std=c++11 -pedantic-errors -lgtest -pthread -MMD -MP -MF build/Debug/CLang-Linux-x86/_ext/1802678175/main.o.d -o build/Debug/CLang-Linux-x86/_ext/1802678175/main.o ../GIT_CryptoCode/src/main.cpp
I don't know why, but the command contains twice some attributes which gives the same warning twice of course. This is what I did in the project properties :
If I remove the Additional options, gtest is not working and the command line becomes something like this : clang++ -c -g -Wall -std=c++11 .... What should I do to not get some attributes to be duplicates ?
Well, even with cmake, I got the warning with Clang (which appears once this time :)). I also tested with GCC 4.7 and I didn't get any warning. Here's the command line I use in a cmake file for GCC :
set (CMAKE_CXX_FLAGS "-Winline -Wall -Werror -pedantic-errors -pthread -std=c++11")
Thus, Clang seems to be the problem. Is anyone know where this warning come from and how to remove it ? Is this a Clang bug ?
Thanks for your help.
I want to thank #Fraser for his help that helps me to find out the way to remove the warnings. Basically, instead of writing -pedantic-errors -lgtest -pthread in the Additional options of the C++ compiler section which gives a duplicate warning, these attributes should be in the Linker section of the project.
So, the Additional Options in the C++ compiler section are left empty. Now, I can use the -Werror attribute without any problem.
Also, in the cmake file, the line
target_link_libraries(${Project_Name} ${GTEST_BOTH_LIBRARIES})
links the gtest library to the project. Thus, no need of -lgtest in
set (CMAKE_CXX_FLAGS "-Winline -Wall -Werror -pedantic-errors -pthread -std=c++11")
both, for GCC and Clang.

How to link libstdc++ statically with clang++

I'm trying to learn C++ deeper by reading source of STL as well as debugging it, so I want to link libstdc++ statically to my program, and it works fine using g++. However, how can I achieve the same thing with clang++ in llvm?
In another way, the question is, what is the clang++ equivalent of -static-libgcc?
Makefile I'm using
CXX=g++
CC=g++
LDFLAGS=-g -O0 -static-libgcc
CFLAGS=-O0 -Wall
CXXFLAGS=$(CFLAGS)
The flag you're looking for, in both GCC and Clang, is: -static-libstdc++