Clang: What exactly does the "-stdlib" flag do? - c++

[Mac OS 10.13.2, Xcode9.2]
Clang has a flag -stdlib which, according to both clang++ -cc1 --help (same as clang -cc1 --help) and the LLVM documentation page, allows specification of the C++ standard library to use.
1) How does this flag impact on compilation? I.e. does it change the order of library include paths etc.
2) How does this flag impact linking? I.e. is it just a short-cut/alternative for supplying -lc++?
I am really interested in understanding the details of this flag because I can't find any documentation describing it's precise behaviour and it is causing havoc with our build system since the Xcode9 upgrade. Inclusion of -stdlib=libc++ in our Makefile causes the compilation to fail due to headers problems, yet, when -stdlib=libc++ is omitted, our projects compile fine (presumably because libc++ is the Mac OS default Standard C++ library). The project link against libc++ due to other linker flags -lc++ and -lsupc++.
Some background info about our use-case
We are using Clang to cross-compile to a -march=i686 -target i686-linux-elf target. Prior to the Xcode9 update, our build system was working fine. Since the upgrade we're getting compiler errors, such as:
/usr/local/our-target/sysroot/usr/local/include/c++/v1/stdlib.h:111:82: error: use of undeclared identifier 'labs'; did you mean 'abs'?
inline _LIBCPP_INLINE_VISIBILITY long abs( long __x) _NOEXCEPT {return labs(__x);}
I've now been able to fix this problem by changing the header include paths. Namely I have removed a path reference to the folder that is parent to both the libc++ AND gcc4.8.5 includes.
# -I${STAGING.nao}/usr/local/include/c++ \
-I${STAGING.nao}/usr/local/include/c++/v1
I am still very interested in understanding the details of what the flag does.

Related

Linker error when enabling Link Time Optimization in NDK

When I add the flag -flto to my NDK C++ project the linker emits the following error: "Optimization level must be between 0 and 3", even though my optimization level is explicitly set to 3 via -O3.
Does anyone know how to solve this?
The compiler flags are passed via Gradle which, as I understand it, should pass the flags to both the Clang compiler and linker. When I remove the -flto flag everything works fine.
Notes:
I'm using NDK 19.2 (latest version at the time I write this).
I also get the warning "clang++.exe: warning: argument unused during compilation: '-Wa,--noexecstack' [-Wunused-command-line-argument]" which I do not have if I compile without link time optimizations.
Two parts to the answer:
The error is caused by https://github.com/android-ndk/ndk/issues/721. Clang's LTO plugin just doesn't accept -Os or -Oz. This is a bug.
Okay, I might be really stupid, I suppose between 0 and 3 means 1 or 2 :)
It's actually because you can't use the generic cppFlags to set optimization levels. That corresponds to CMAKE_CXX_FLAGS, and you need to set these in CMAKE_CXX_FLAGS_DEBUG and CMAKE_CXX_FLAGS_RELEASE (and/or the C flavors of those). CMake has its own defaults in those variables and the command line is built as ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}, so your -O3 is being overridden by the default.
I also encounter this linking error but I fixed through a different way.
I had cross-compile a library for android with architectures of both arm64 and armv7. It's all OK for arm64 but encounter the linking error for armv7. And I found it can be fixed by commented out the following statements in my CMakeLists.txt:
if (${CMAKE_MAJOR_VERSION} GREATER_EQUAL 3 AND ${CMAKE_MINOR_VERSION} GREATER_EQUAL 9)
cmake_policy(SET CMP0069 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
include(CheckIPOSupported)
check_ipo_supported(RESULT ipo_supported OUTPUT ipo_supported_output)
if (ipo_supported)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif ()
endif ()
The above CMake statements are related to the IPO setting and it seems cause the linking error when cross-compiling for android armv7.
I don't know why the IPO should not enabled for android armv7.

Cannot use -std=c++11 and -l/-L options at the same time in Eclipse Neon.3

I am trying to work through this tutorial on OpenCL, on a Windows 10 dev system which has integrated Intel HD graphics. I have installed Intel's OpenCL SDK. I have added the include directory from the SDK install into Properties > C/C++ General > Paths and Symbols > Includes. I am using MinGW as my compiler for Eclipse
In response to a number of linker errors that popped up when I first tried to compile the project, I set up the linker in eclipse to point to opencl.lib as outlined in this answer.
That took care of the linker errors, but there's an offending line from the tutorial which makes it impossible for the tutorial boiler-plate to compile:
87 cl_int result = program.build({ device }, "");
Set up as I am, this gives me the following warning and error:
..\src\main.cpp:93:32: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
..\src\main.cpp:93:45: error: no matching function for call to 'cl::Program::build(<brace-enclosed initializer list>, const char [1])'
If I'm reading this correctly (I haven't used C++ since before C++11 was a thing), the compiler is first warning me that it doesn't properly recognize what {device} is supposed to be (a vector of devices which has only one entry in it, initialized earlier in the code). Then, since it doesn't recognize {device}, the compiler errors out because it can't find a signature for cl::Program::build with arguments that match whatever-the-heck it's interpreting {device} to be.
Following the warning's advice, I followed the instructions given in this answer to add the -std=c++11 option for the compiler. However, when I do that the linker errors come back. Trying to compile with these options results in about thirty errors which all basically say they can't find any reference for the CL calls in the library files. For example:
C:/Program Files (x86)/Intel/OpenCL SDK/6.3/include/CL/cl.hpp:1753: undefined reference to `clGetPlatformInfo#20'
How do I make the compiler behave? I think I remember reading somewhere that the order of compiler options in the command line matters withe regards to linking, could that be messing up my compile since I added the -std=c++11 option?
I (sort of) figured out why the compiler was unhappy--the library I was linking was the x64 library for OpenCL installed in [base Intel dir]\OpenCL SDK\6.3\lib\x64, but (I think?) my compiler is not set up to create x64 apps. When I link to the .lib file in OpenCL SDK\6.3\lib\x86 my linker errors disappeared.

Error compiling Boost.Log

I am trying to compile the boost log library and I keep getting this error from the dump_avx2.cpp file
error: always_inline function '_mm256_set1_epi32' requires target feature 'sse4.2', but would be inlined into function 'dump_data_avx2' that is compiled without support for 'sse4.2'
boost/boost/libs/log/src/dump_avx2.cpp:71:31: note: expanded from macro 'BOOST_LOG_AUX_MM_CONSTANTS'
const __m256i mm_char_0 = _mm256_set1_epi32(0x30303030);\
^
I get a lot of errors that are very similar to the one above, all of them have the same error message but different locations in the file where they occur, for reference I am on the commit hash 68701167a1020b0b4c47b76e31d3a3da9e2faf3f for the Boost.Log submodule as fetched from the github repo (https://github.com/boostorg/boost)
Does anyone know how I can go about resolving this issue? I am building with a C++14 compiler and this is what I get when I type g++ --version
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Thanks!
Note I should clarify that in this context it is required that I compile this library separately.
Note There seem to be two related source files dump_ssse3.cpp and the mentioned dump_avx2.cpp file, do I have to compile only one of them? I cannot make out what to do from the Jamfile in the build folder :(
That looks like a bug in clang (LLVM). First, the intrinsic belongs to AVX2, not SSE4.2. Second, the whole dump_avx2.cpp file is compiled with -mavx2, so the required extensions are enabled. You can see the compiler switches in the error message from b2. And no, both dump_ssse3.cpp and dump_avx2.cpp should be compiled. The library does runtime detection of the available instructions in the CPU and selects the proper implementation.

MacPorts clang not using its own headers

I'm trying to get emscripten to work on OS X 10.8, see this post for some related issues there. Apparently the clang++ version shipped with Xcode is too old, so I got a recent clang 3.7.0 using MacPorts. I even told CMake to use that compiler (passing -DCMAKE_CXX_COMPILER=clang++-mp-3.7 on the command line), but it still fails:
[ 33%] Building CXX object CMakeFiles/optimizer.dir/parser.cpp.o
/opt/local/bin/clang++-mp-3.7 -std=c++11 -fno-exceptions -fno-rtti -O3 -DNDEBUG
-o CMakeFiles/optimizer.dir/parser.cpp.o
-c …/emsdk/emscripten/master/tools/optimizer/parser.cpp
In file included from …/emsdk/emscripten/master/tools/optimizer/parser.cpp:2:
In file included from …/emsdk/emscripten/master/tools/optimizer/parser.h:12:
…/emsdk/emscripten/master/tools/optimizer/istring.h:3:10: fatal error:
'unordered_set' file not found
#include <unordered_set>
^
1 error generated.
I can reproduce that issue by launching the compiler from the command line. In parallel build mode, sometimes it's instead complaining about <cstdint> for optimizer.cpp instead. Both these headers exist in /opt/local/libexec/llvm-3.7/include/c++/v1/.
What's the canonical way to use the macports-installed version of clang++ including its headers? Do I have to use -I and work out the full path, or is there something shorter?
Can I safely do so without also switching the runtime library to the one shipped with MacPorts' clang? If not, can I somehow encode the full path of the runtime library into the created binary, either for that single library or using the -rpath argument to ld or some equivalent alternative?
Update: I get unresolved symbols when I try to link stuff after specifying the include directory manually, and I don't know how to solve that. The libcxx package from MacPorts is empty except for a readme file.
I've solved the original problem by adding CXXFLAGS=--stdlib=libc++ to the environment. Then even the system version of clang will do everything I need. That flag works magic for MacPorts' version of clang as well: specifying that I get a successful build, and I can even verify (using the -E compiler switch) that it's using the headers I mentioned before. I'm still not certain whether there is anything to ensure that the headers match the system's version of libc++, though.

Compile with Intel 12.1.3 using gcc4.7 std library

I'm having the same problem described in this post except I'm using Intel version 12.1.3. (g++'s header <functional> is protected with #ifdef __GXX_EXPERIMENTAL_CXX0X__ which is not defined when icpc is used.)
Instead of using boost::functional, I wanted to install gcc4.7 and use it's std libraries.
In Ubuntu 11.10 I have gcc4.6.1 but I also installed gcc4.7 from the gcc-snapshot package.
Intel has the options -gcc-name, -gxx-name, and -cxxlib.
So originally I compiled with:
-std=c++0x -gcc-name=/usr/lib/gcc-snapshot/bin/gcc -gxx-name=/usr/lib/gcc-snapshot/bin/g++ -cxxlib=/usr/lib/gcc-snapshot/
but I get the error:
icpc: error #10282: file
'/usr/lib/gcc-snapshot/bin/usr/lib/gcc-snapshot/bin/g++' not found,
generated based on '-cxxlib=/usr/lib/gcc-snapshot/'
So then I compiled with:
-std=c++0x -gcc-name=./gcc -gxx-name=./g++ -cxxlib=/usr/lib/gcc-snapshot/.
But I still get the warnings and errors:
Warning #2928: the __GXX_EXPERIMENTAL_CXX0X__ macro is disabled when using GNU version 4.6 with the c++0x option
error: namespace "std" has no member "function"
The warning clearly says it's still using version 4.6. Does anybody know how to get Intel to use the correct libraries?
I've found that if you compile with gcc (or g++) with flags -v -Q you get a list of flags and defines. It might help you see what gcc does so maybe you can use the same -D/-U in icpc. also g++ -E will preprocess without compiling: you can get useful path information from that.