compiler-rt CMake build ignores CMAKE_CXX_FLAGS

Hello,

It looks like compiler-rt CMake scripts don't take CMAKE_CXX_FLAGS
into account. This is because clang_compile and clang_link_shared
functions call the newly-built compiler directly, and they don't add
those flags.

Using CMAKE_CXX_FLAGS is necessary on systems where the C++11-enabled
libstdc++ is installed not in the default location. For example, the
CentOS buildbot uses:

-DCMAKE_CXX_FLAGS=--gcc-toolchain=/opt/centos/devtoolset-1.1/root/usr

I tried adding ${CMAKE_CXX_FLAGS} to the compiler invocation in
clang_compile (with and without quotes), but in both cases the
resulting command is not correct, all of CMAKE_CXX_FLAGS is treated as
a single option, for example:

[6/67] Generating gtest-all.cc.x86_64.o
FAILED: cd /home/llvmbb/clang/build-cmake-r+a/projects/compiler-rt/lib/tsan/tests/unit
&& /home/llvmbb/clang/build-cmake-r+a/./bin/clang -fPIC -fno-builtin
-fno-exceptions -fomit-frame-pointer -funwind-tables
-fno-stack-protector -fvisibility=hidden -fno-function-sections -O3
-gline-tables-only -Wno-gnu -Wno-variadic-macros -Wno-c99-extensions
-Wno-non-virtual-dtor -fPIE -fno-rtti -DGTEST_NO_LLVM_RAW_OSTREAM=1
-I/home/llvmbb/clang/llvm/utils/unittest/googletest/include
-I/home/llvmbb/clang/llvm/utils/unittest/googletest
-I/home/llvmbb/clang/llvm/projects/compiler-rt/lib
-I/home/llvmbb/clang/llvm/projects/compiler-rt/lib/tsan/rtl -std=c++11
-DGTEST_HAS_RTTI=0
--gcc-toolchain=/opt/centos/devtoolset-1.1/root/usr\ -fPIC\
-fvisibility-inlines-hidden\ -Wall\ -W\ -Wno-unused-parameter\
-Wwrite-strings\ -Wmissing-field-initializers\ -pedantic\
-Wno-long-long\ -Wcovered-switch-default\ -Wnon-virtual-dtor\
-std=c++11\ -fcolor-diagnostics\ -ffunction-sections\ -fdata-sections\
-Wall\ -std=c++11 -m64 -c -o gtest-all.cc.x86_64.o
/home/llvmbb/clang/llvm/utils/unittest/googletest/src/gtest-all.cc

Note the backslases in the command.

Could maintainers of the compiler-rt CMake scripts help me with this?

Dmitri

Hi Dmitri,

Hello,

It looks like compiler-rt CMake scripts don't take CMAKE_CXX_FLAGS
into account. This is because clang_compile and clang_link_shared
functions call the newly-built compiler directly, and they don't add
those flags.

Indeed.

Using CMAKE_CXX_FLAGS is necessary on systems where the C++11-enabled
libstdc++ is installed not in the default location. For example, the
CentOS buildbot uses:

-DCMAKE_CXX_FLAGS=--gcc-toolchain=/opt/centos/devtoolset-1.1/root/usr

I tried adding ${CMAKE_CXX_FLAGS} to the compiler invocation in
clang_compile (with and without quotes), but in both cases the
resulting command is not correct, all of CMAKE_CXX_FLAGS is treated as
a single option, for example:

Yes, recently I discovered the same problem and also though of adding
CMAKE_CXX_FLAGS
to manual clang invocations. I think it just needs to be done.

[6/67] Generating gtest-all.cc.x86_64.o
FAILED: cd
/home/llvmbb/clang/build-cmake-r+a/projects/compiler-rt/lib/tsan/tests/unit
&& /home/llvmbb/clang/build-cmake-r+a/./bin/clang -fPIC -fno-builtin
-fno-exceptions -fomit-frame-pointer -funwind-tables
-fno-stack-protector -fvisibility=hidden -fno-function-sections -O3
-gline-tables-only -Wno-gnu -Wno-variadic-macros -Wno-c99-extensions
-Wno-non-virtual-dtor -fPIE -fno-rtti -DGTEST_NO_LLVM_RAW_OSTREAM=1
-I/home/llvmbb/clang/llvm/utils/unittest/googletest/include
-I/home/llvmbb/clang/llvm/utils/unittest/googletest
-I/home/llvmbb/clang/llvm/projects/compiler-rt/lib
-I/home/llvmbb/clang/llvm/projects/compiler-rt/lib/tsan/rtl -std=c++11
-DGTEST_HAS_RTTI=0
--gcc-toolchain=/opt/centos/devtoolset-1.1/root/usr\ -fPIC\
-fvisibility-inlines-hidden\ -Wall\ -W\ -Wno-unused-parameter\
-Wwrite-strings\ -Wmissing-field-initializers\ -pedantic\
-Wno-long-long\ -Wcovered-switch-default\ -Wnon-virtual-dtor\
-std=c++11\ -fcolor-diagnostics\ -ffunction-sections\ -fdata-sections\
-Wall\ -std=c++11 -m64 -c -o gtest-all.cc.x86_64.o
/home/llvmbb/clang/llvm/utils/unittest/googletest/src/gtest-all.cc

Note the backslases in the command.

Yep, because CMAKE_CXX_FLAGS is a string, and its contents is automatically
escaped when we use it in COMMAND in CMake rules. I guess we'll have to
manually
turn CMAKE_CXX_FLAGS into a CMake semicolon-separated list.

Could maintainers of the compiler-rt CMake scripts help me with this?

Thanks for the detailed description of your use case.
I will try to address this problem tomorrow.

Submitted r204593.

Thank you! It did fix compiling the tests on the buildbot, but I am
surprised that linking succeeded. Maybe that is because we are not
using any C++11 features that require symbols from the newer
libstdc++. But it would be future-proof to change clang_link_shared()
to use CMAKE_CXX_FLAGS as well.

Dmitri

> Submitted r204593.

Thank you! It did fix compiling the tests on the buildbot, but I am
surprised that linking succeeded. Maybe that is because we are not
using any C++11 features that require symbols from the newer
libstdc++. But it would be future-proof to change clang_link_shared()
to use CMAKE_CXX_FLAGS as well.

Is there really a logic in Clang that would choose between old and newer
libstdc++ versions
depending on the value of -std= flag?

I hope to get rid of clang_compile and clang_link_shared horridness soon by
switching
to LLVM_BUILD_EXTERNAL_COMPILER_RT=ON that would use just-built Clang to
configure/build compiler-rt.

So, your use case might be interesting. Can you build with
-DLLVM_BUILD_EXTERNAL_COMPILER_RT=ON and
check if "make check-compiler-rt" works for you? If not, then we'd have to
propagate *some* CMAKE_CXX_FLAGS
to configuration step of compiler-rt project, but we won't need most of the
extra flags stuffed into CMAKE_CXX_FLAGS
by LLVM/Clang CMake files. It might be a problem (sigh).

We might want to add CMAKE_TARGET_CXX_FLAGS in that case. Blindly
propagating flags would be wrong, because compiler-rt build could be
targetting a completely different platform.