Where is the atomic library and why is it not linking? - c++

I'm compiling an old version of OGRE ON CMake 3.6 to see if I can compile or revive an old piece of software, and Boost is one of the dependencies for OGRE. It's essentially for multi-threading and without it, OGRE 1.9.0 builds completely fine on the macOS 12.0 SDK but fails macOS 10.8 SDK (specified in ZSH as -DCMAKE_OSX_DEPLOYMENT_TARGET but that's another issue for later).
The CMake command: cmake -DOGRE_CONFIG_DOUBLE=ON -DOGRE_BUILD_SAMPLES=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES="x86_64" -DCMAKE_PREFIX_PATH=/usr/local (yes, I'm compiling x86_64 on a arm64 machine running macOS 12.1 & XCode 13.1 if it matters)
When I build OGRE on the 12.0 SDK with Boost support (all is found here), it successfully checks for all libraries. As a note, Boost also has the atomic library but it's only needed as .hpp files and not an actual .a or whatever-lib file format CPP uses. Compiling OGRE goes all well until I see this dreaded message:
Copying OS X content lib/macosx/Ogre.framework/Versions/1.9.0/Resources/ogrelogo.png
28 warnings generated.
21 warnings generated.
[ 44%] Linking CXX shared library ../lib/macosx/Ogre.framework/Ogre
> ld: library not found for -latomic <
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Key questions: What is this atomic library? Is it only on an older SDK? Is it the hpp files? Here is the linker command shortened to where I think is the most important parts
cd /Users/meh/Downloads/project/ogre-1-9-0/OgreMain && /Applications/CMake.app/Contents/bin/cmake -E cmake_link_script CMakeFiles/OgreMain.dir/link.txt --verbose=1
/usr/bin/clang++ -msse -stdlib=libc++ -std=c++11 -Wall -Winit-self -Wno-overloaded-virtual -Wcast-qual -Wwrite-strings -Wextra -Wno-unused-parameter -Wshadow -Wno-missing-field-initializers -Wno-long-long -O3 -DNDEBUG -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk -dynamiclib -Wl,-headerpad_max_install_names -framework AGL -framework IOKit -framework Cocoa -framework Carbon -framework OpenGL -framework CoreVideo -compatibility_version 1.9.0 -current_version 1.9.0 -o ../lib/macosx/Ogre.framework/Versions/1.9.0/Ogre -install_name #executable_path/../Frameworks/Ogre.framework/Versions/1.9.0/Ogre (ALL THOSE OGRE .O FILES) -L/usr/local/lib /usr/local/lib/libboost_thread.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_chrono.a /usr/local/lib/Release/libFreeImage.a /usr/local/lib/Release/libzziplib.a /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/usr/lib/libz.tbd -latomic
I had to play around with the CMake file to not error listed as:
framework AGL
-stdlib=libc++ -std=c++11
I've done research and atomic shows up in C++11 so that shouldn't be a problem? There's some include files under the SDK but definitely none under /usr/local/lib... (I will have to add -L/usr/local/include as a prefix to -latomic later)

Related

Error when Cross-Compiling from WSL Ubuntu to Win32

I'm writing a lot of cross platform C++, and am trying to unify my build process between platforms (primarily targeting Windows and Mac at the moment, potentially mobile in the future.) In addition to our normal CI builds, we are built from source as part of an extremely large C++ project's build and consequently have quite a complex toolchain.
Right now, my code compiles cleanly on Windows using CMake to generate a Visual Studio project and then using clang-cl to compile. Similarly, we are using CMake to generate a ninja project and then clang to compile.
We are a Windows shop, and I would like to leverage WSL to set up cross compilation, which should allow us to use the same ninja project to target both supported platforms and modify in the future.
I am able to successfully compile a simple hello world exe program using clang from my wsl-hosted bash terminal. In order to do this, I had to provide a large amount of options to clang as well as move a significant amount of Win10 SDK libraries to my build environment for clang to build and link against.
Here are the two commands I run to successfully produce helloworld.exe:
Compiling:
clang -target i686-pc-win32 -fms-compatibility-version=19 -fms-extensions -fdelayed-template-parsing -fexceptions -mthread-model posix -fno-threadsafe-statics -Wno-msvc-not-found -DWIN32 -D_WIN32 -D_MT -D_DLL -Xclang -disable-llvm-verifier -Xclang '--dependent-lib=msvcrt' -Xclang '--dependent-lib=ucrt' -Xclang '--dependent-lib=oldnames' -Xclang '--dependent-lib=vcruntime' -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -U__GNUC__ -U__gnu_linux__ -U__GNUC_MINOR__ -U__GNUC_PATCHLEVEL__ -U__GNUC_STDC_INLINE__ -I/mnt/d/source/windeps/LLVM/include -I/mnt/d/source/windeps/MSVC/14.22.27905/include -I/mnt/d/source/windeps/ucrt -I/mnt/d/source/windeps/shared -I/mnt/d/source/windeps/winrt -c hello.cc -o hello.o
Linking:
clang -fuse-ld=lld-link.exe -target i686-pc-win32 -Wl,-machine:x86 -fmsc-version=1923 -o hello.exe hello.o -L/mnt/d/source/windeps/MSVC/14.22.27905/lib/x86/msvcrt.lib -nostdlib -lmsvcrt -Wno-msvc-not-found
Naturally, I have attempted to express this first command via my CMake toolchain:
add_compile_options(
-W
-Wall
-std=c++17
-stdlib=libc++
-fcoroutines-ts
-fms-extensions
-fdelayed-template-parsing
-fexceptions
-fdeclspec
-mthread-model posix
-fno-threadsafe-statics
-Wno-msvc-not-found
-DWIN32
-D_WIN32
-D_MT
-D_DLL
-Xclang
-disable-llvm-verifier
# These are commented out currently, but I have linked them to the proper CMakeList
# -Xclang '--dependent-lib=msvcrt'
# -Xclang '--dependent-lib=ucrt'
# -Xclang '--dependent-lib=oldnames'
# -Xclang '--dependent-lib=vcruntime'
-D_CRT_SECURE_NO_WARNINGS
-D_CRT_NONSTDC_NO_DEPRECATE
-U__GNUC__
-U__gnu_linux__
-U__GNUC_MINOR__
-U__GNUC_PATCHLEVEL__
-U__GNUC_STDC_INLINE__
-I/mnt/d/source/windeps/LLVM/include
-I/mnt/d/source/windeps/MSVC/14.22.27905/include
-I/mnt/d/source/windeps/um
-I/mnt/d/source/windeps/ucrt
-I/mnt/d/source/windeps/shared
-I/mnt/d/source/windeps/winrt
)
This is throwing an error from within the ucrt library when one of our files (event_logger.cpp) does #include <array>.
In file included from src/client/services/src/event_logger.cpp:10:
In file included from /mnt/d/source/windeps/MSVC/14.22.27905/include/array:6:
In file included from /mnt/d/source/windeps/MSVC/14.22.27905/include/algorithm:6:
In file included from /mnt/d/source/windeps/MSVC/14.22.27905/include/xmemory:8:
In file included from /mnt/d/source/windeps/MSVC/14.22.27905/include/limits:8:
In file included from /mnt/d/source/windeps/MSVC/14.22.27905/include/cwchar:8:
In file included from /mnt/d/source/windeps/MSVC/14.22.27905/include/cstdio:8:
In file included from /mnt/d/source/windeps/ucrt/stdio.h:13:
/mnt/d/source/windeps/ucrt/corecrt_wstdio.h:581:9: error: use of undeclared identifier '__crt_va_end'
__crt_va_end(_ArgList);
^
/mnt/d/source/windeps/ucrt/corecrt_wstdio.h:597:9: error: use of undeclared identifier '__crt_va_start_a'
__crt_va_start(_ArgList, _Locale);
^
/mnt/d/source/windeps/MSVC/14.22.27905/include/vadefs.h:156:99: note: expanded from macro '__crt_va_start'
#define __crt_va_start(ap, x) ((void)(__vcrt_assert_va_start_is_not_reference<decltype(x)>(), __crt_va_start_a(ap, x)))
Because of this behavior, I'm suspicious that perhaps we're not using libc++ as indicated by the -stdlib flag. I'm also not sure how to correct this, as this seems to be kind of a newer process and there's not a ton of documentation in the wild yet. Any advice is appreciated.

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

C++ project compiled with modern compiler, but linked against outdated libstdc++

Consider the situation when a C++ project is built and shipped within a Centos 7 virtual machine or container. Default gcc for Centos 7 is 4.8. In order to allow developers to use modern C++, the more recent version of gcc (for example, 6.3) is installed into Centos 7 which runs as a CI server. This provides -std=c++14 support.
[builder#f7279ae9f33f build (master %)]$ /usr/bin/c++ -v 2>&1 | grep version
gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
[builder#f7279ae9f33f build (master %)]$ /opt/rh/devtoolset-6/root/usr/bin/c++ -v 2>&1 | grep version
gcc version 6.3.1 20170216 (Red Hat 6.3.1-3) (GCC)
export CXX=/opt/rh/devtoolset-6/root/usr/bin/c++
make all -j4
...
This is short example of compilation and linkage command:
[ 78%] Building CXX object CMakeFiles/ucsdos.dir/src/merge_operator_string.cpp.o
/opt/rh/devtoolset-6/root/usr/bin/c++ -Ducsdos_EXPORTS -I/home/builder/src/dos/libucsdos/./src -I/home/builder/src/dos/libucsdos/./include -I/home/builder/src/dos/libucsdos/build/schema/cpp -I/home/builder/src/dos/libucsdos/build/schema -isystem /usr/local/include -O2 -g -DNDEBUG -fPIC -frtti -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused -std=gnu++14 -o CMakeFiles/ucsdos.dir/src/merge_operator_string.cpp.o -c /home/builder/src/dos/libucsdos/src/merge_operator_string.cpp
[ 80%] Linking CXX shared library libucsdos.so
/usr/bin/cmake3 -E cmake_link_script CMakeFiles/ucsdos.dir/link.txt --verbose=1
/opt/rh/devtoolset-6/root/usr/bin/c++ -fPIC -O2 -g -DNDEBUG -shared -Wl,-soname,libucsdos.so.0 -o libucsdos.so.0.3.23 CMakeFiles/ucsdos.dir/src/c.cpp.o CMakeFiles/ucsdos.dir/src/crdt_2p_set.cpp.o CMakeFiles/ucsdos.dir/src/crdt_pn_counter.cpp.o CMakeFiles/ucsdos.dir/src/errors.cpp.o CMakeFiles/ucsdos.dir/src/merge_index_document.cpp.o CMakeFiles/ucsdos.dir/src/merge_index_segment.cpp.o CMakeFiles/ucsdos.dir/src/merge_operator_string.cpp.o -Wl,-rpath,/usr/local/lib: schema/libschema.a /usr/lib64/librocksdb.so /usr/lib64/libjemalloc.so /usr/local/lib/libgrpc++_reflection.so /usr/local/lib/libgrpc++.so /usr/local/lib/libgrpc.so -ldl -lgrpc++ /usr/lib64/libprotobuf.so -lpthread /usr/lib64/libprotobuf-lite.so
Anyway, the resulting artifacts appear to be linked with system default version of libstdc++:
[builder#f7279ae9f33f build (master %)]$ ldd libucsdos.so | grep libstdc++.so.6
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f2a4a054000)
It's easy to find out that /lib64/libstdc++.so.6 version is 4.8.5:
[builder#f7279ae9f33f build (master %)]$ yum whatprovides "/lib64/libstdc++.so.6"
libstdc++-4.8.5-28.el7_5.1.x86_64 : GNU Standard C++ Library
Repo : #Updates
Matched from:
Filename : /lib64/libstdc++.so.6
Is this build environment configuration valid?
Anyway, the resulting artifacts appear to be linked with system default version of libstdc++:
Yes. The devtoolset-6-gcc-c++ package provides a custom version of GCC that uses a special linker script instead of a dynamic library for libstdc++.so. That means the binaries it produces do not depend on the newer libstdc++.so.6 and can be run on other CentOS machines that don't have devtoolset installed (i.e. they only have the older libstdc++ library from GCC 4.8).
Is this build environment configuration valid?
Yes. What you're seeing is completely normal, and how it's supposed to work.
The pieces of the newer C++ runtime from GCC 6.4.0 get statically linked into your binary, and at runtime it only depends on the old libstdc++.so which every CentOS system has installed.
That's the whole point of the devtoolset version of GCC.

How to force Bazel to use gcc?

Ubuntu 17.10
GCC Version: 5.4
Bazel Version: 0.9.0
TensorFlow: r1.5
CUDA 8.0 / cuDNN 6 / GTX 1080 Ti
How do I make Bazel use gcc for building TensorFlow from source?
While building, its running into compiler errors like:
error: 'errno' was not declared in this scope
while (nanosleep(&ts, &ts) != 0 && errno == EINTR) {}
Setting --verbose_failures flag, it shows that its not using /usr/bin/gcc-5 or /usr/bin/gcc for compiling
external/local_config_cuda/crosstool/clang/bin/crosstool_wrapper_driver_is_not_gcc -U_FORTIFY_SOURCE '-D_FORTIFY_SOURCE=1' -fstack-protector -fPIE -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -g0 -O2 -DNDEBUG -ffunction-sections -fdata-sections -g0 -DGEMMLOWP_ALLOW_SLOW_SCALAR_FALLBACK '-march=native' '-std=c++11' -g0 -MD -MF
Searching online, I found that the path to gcc and CC, CXX variables must be set in tools/cpp/CROSSTOOL. But where exactly is tools/cpp/CROSSTOOL?? How do I force bazel to use gcc-5?
I know next to nothing about cuda and tensorflow, but tensorflow doesn't use the same C++ toolchain that bazel autoconfigures when compiling with cuda, so the CC env variable trick won't work. The file crosstool_wrapper_driver_is_not_gcc is just a shell wrapper that could in theory still call your gcc (or it will be cuda). I'd run bazel with --subcommands to see the complete invocation of the failing action, then reproduce without bazel, and then go from there.

Qt Creator, Compiler in kit for project is being ignored

I am running macOS High Sierra (10.13.2) and Qt 5.10.0. I would like to use OpenMP with my application.
I have added the following flags to my .pro file
QMAKE_CXXFLAGS += -fopenmp
QMAKE_LFLAGS += -fopenmp
LIBS += -fopenmp
The default compilers on macOS do not contain OpenMP. I installed gcc through homebrew which does support OpenMP.
Under the Build & Run -> Compilers tab of Qt Creator, I added the homebrew g++ and gcc compilers (/usr/local/Cellar/gcc/7.2.0/bin/{gcc-7,g++-7}). I then selected the kit that I am using and changed the compiler to be the homebrew installed compiler that I added under the compilers tab.
If I inspect the Makefile generated by Qt Creator after setting this kit and rebuilding the project, I find the CC and CXX are not using the compiler that I have specified.
Here are their values in the Makefile:
CC = /Library/Developer/CommandLineTools/usr/bin/clang
CXX = /Library/Developer/CommandLineTools/usr/bin/clang++
These should be /usr/local/Cellar/gcc/7.2.0/bin/g++-7 and /usr/local/Cellar/gcc/7.2.0/bin/gcc-7.
The compiler output that I get now is:
18:14:48: Starting: "/usr/bin/make"
/usr/local/Cellar/qt/5.10.0/bin/qmake -o Makefile ../Practice/Practice.pro -spec macx-g++ CONFIG+=debug CONFIG+=x86_64 CONFIG+=qml_debug
/Library/Developer/CommandLineTools/usr/bin/g++ -c -pipe -fopenmp -g -std=gnu++11 -arch x86_64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.13.sdk -mmacosx-version-min=10.10 -Wall -W -fPIC -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I../Practice -I. -I/usr/local/Cellar/qt/5.10.0/lib/QtQuick.framework/Headers -I/usr/local/Cellar/qt/5.10.0/lib/QtGui.framework/Headers -I/usr/local/Cellar/qt/5.10.0/lib/QtQml.framework/Headers -I/usr/local/Cellar/qt/5.10.0/lib/QtNetwork.framework/Headers -I/usr/local/Cellar/qt/5.10.0/lib/QtCore.framework/Headers -I. -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/OpenGL.framework/Headers -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/AGL.framework/Headers -I/usr/local/Cellar/qt/5.10.0/mkspecs/macx-g++ -F/usr/local/Cellar/qt/5.10.0/lib -o main.o ../Practice/main.cpp
clang: error: unsupported option '-fopenmp'
make: *** [main.o] Error 1
18:14:49: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project Practice (kit: Desktop)
When executing step "Make"
Why is the Makefile generated by Qt Creator not using the compiler that I am specifying in the kit that I am using?
Because the mkspec macx-g++ you're using will override CC and CXX settings. As a temporary workaround, try setting them in the pro file directly:
QMAKE_CC = /usr/local/Cellar/gcc/7.2.0/bin/gcc-7
QMAKE_CXX = /usr/local/Cellar/gcc/7.2.0/bin/g++-7
You may want to edit the mkspec (or making a new one) for your kit and set those variables there.
To find the mkspec file (qmake.conf):
INSTALLDIR=`qmake -query QT_INSTALL_CONFIGURATION`
MKSPECNAME=`qmake -query QMAKE_SPEC`
cd $INSTALLDIR/mkspecs/$MKSPECNAME
As to why you have to set the compilers twice: Qt Creator is meant to be a generic c++ IDE, thus able to manage non-Qt projects, which don't use qmake but need a compiler anyway.