I want to get C++17 features working in Bazel. My macbook is using clang as its default C++ compiler and does not appear to be supporting c++17, so I've compiled g++ locally (which does support c++17).
I have the following files in a directory:
WORKSPACE
<empty>
BUILD
cc_binary(
name = "main",
srcs = ["main.cc"],
)
main.cc
#include <iostream>
#include <any>
int main() {
std::any val1 = 1;
std::cout << "val1 = " << std::any_cast<int>(val1) << std::endl;
}
I'm working on a Macbook Pro using
- macos = 10.12
- xcode = 9.1
- bazel = 0.8.1-homebrew
- clang++ = Apple LLVM version 9.0.0 (clang-900.0.38) [in /usr/bin/clang++]
- g++ = 7.2.0 built from source [in /usr/local/wmh/gcc-7.2/bin/g++]
Some observations follow...
clang doesn't yet handle -std=c++17
% /usr/bin/clang++ -std=c++17 -o main main.cc
error: invalid value 'c++17' in '-std=c++17'
supposedly we use -std=c++1z for LLVM 4.0, but it doesn't appear to understand std::any (and /usr/include has no files defining 'any')
% /usr/bin/clang++ -std=c++1z -o main main.cc
main.cc:2:10: fatal error: 'any' file not found
#include <any>
^~~~~
1 error generated.
% find /usr/include -name '*any*'
/usr/include/apr-1/apr_anylock.h
g++ does the right thing.
% /usr/local/wmh/gcc-7.2/bin/g++ -std=c++17 -o main main.cc
% ./main
val1 = 1
bazel out-of-the-box will use clang. Below, I'm setting CC explicitly just to ensure the generated CROSSTOOL is for clang
% bazel clean --expunge
% export CC=/usr/bin/clang++
% blaze build --cxxopt=-std=c++1z --verbose_failures :main
... snip ...
main.cc:2:10: fatal error: 'any' file not found
#include <any>
^~~~~
1 error generated.
... snip ...
Let's save the CROSSTOOL file for comparision purposes:
% cp $(find $(bazel info execution_root) -name CROSSTOOL) /tmp/CT.clang
% export CC=/usr/local/wmh/gcc-7.2/bin/g++
% blaze build --cxxopt=-std=c++17 --verbose_failures --sandbox_debug :main
...........
Loading: 0 packages loaded
Analyzing: target //:main (4 packages loaded)
Analyzing: target //:main (4 packages loaded)
Analyzing: target //:main (7 packages loaded)
Analyzing: target //:main (9 packages loaded)
INFO: Analysed target //:main (9 packages loaded).
bazel: Entering directory `/private/var/tmp/_bazel_wmh/e02603ea880b3ada6404b60673612989/execroot/__main__/'
[0 / 5] Creating source manifest for //:main
ERROR: /Users/wmh/src/tests/cc/c++17/BUILD:1:1: C++ compilation of rule '//:main' failed (Exit 1): sandbox-exec failed: error executing command
(cd /private/var/tmp/_bazel_wmh/e02603ea880b3ada6404b60673612989/execroot/__main__ && \
APPLE_SDK_PLATFORM=MacOSX \
APPLE_SDK_VERSION_OVERRIDE=10.13 \
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer \
PATH=/usr/bin:/sw/bin:/opt/local/bin:/usr/texbin:/Applications/Emacs.app/Contents/MacOS/bin:/usr/local/texlive/2016/bin/universal-darwin:/opt/X11/bin:/usr/local/symlinks:/usr/local/scripts:/usr/local/bin:/usr/local/sbin:/sbin:/usr/sbin:/bin:. \
SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk \
TMPDIR=/private/var/tmp/_bazel_wmh/e02603ea880b3ada6404b60673612989/bazel-sandbox/3461531722433772538/execroot/__main__/tmp \
XCODE_VERSION_OVERRIDE=9.1.0 \
/usr/bin/sandbox-exec -f /private/var/tmp/_bazel_wmh/e02603ea880b3ada6404b60673612989/bazel-sandbox/3461531722433772538/sandbox.sb /private/var/tmp/_bazel_wmh/e02603ea880b3ada6404b60673612989/execroot/__main__/_bin/process-wrapper '--timeout=0' '--kill_delay=15' external/local_config_cc/wrapped_clang '-D_FORTIFY_SOURCE=1' -fstack-protector -fcolor-diagnostics -Wall -Wthread-safety -Wself-assign -fno-omit-frame-pointer -O0 -DDEBUG '-std=c++11' '-std=c++17' -iquote . -iquote bazel-out/darwin-fastbuild/genfiles -iquote external/bazel_tools -iquote bazel-out/darwin-fastbuild/genfiles/external/bazel_tools -isystem external/bazel_tools/tools/cpp/gcc3 -MD -MF bazel-out/darwin-fastbuild/bin/_objs/main/main.d '-frandom-seed=bazel-out/darwin-fastbuild/bin/_objs/main/main.o' '-isysroot __BAZEL_XCODE_SDKROOT__' -no-canonical-prefixes -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -c main.cc -o bazel-out/darwin-fastbuild/bin/_objs/main/main.o) error: invalid value 'c++17' in '-std=c++17'
bazel: Leaving directory `/private/var/tmp/_bazel_wmh/e02603ea880b3ada6404b60673612989/execroot/__main__/'
Target //:main failed to build
INFO: Elapsed time: 8.678s, Critical Path: 0.11s
FAILED: Build did NOT complete successfully
The "invalid value 'c++17' in '-std=c++17'" error looks an awful lot like it is still using clang. The fact that the code is invoking external/local_config_cc/wrapped_clang isn't promising either ... and in looking at that file it does indeed appear to be invoking clang. However, when I compare the new CROSSTOOL file with the old one, there are lots of diffs (so something different happened when I changed the value of CC) but the diffs are ONLY for cxx_builtin_include_directory variables (I would expect some other variable to change to indicate that we are using g++ instead of clang, no?).
% cp $(find $(bazel info execution_root) -name CROSSTOOL) /tmp/CT.gcc
% diff /tmp/CT.clang /tmp/CT.gcc
60c60,63
< cxx_builtin_include_directory: "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1"
---
> cxx_builtin_include_directory: "/usr/local/wmh/gcc-7.2/include/c++/7.2.0"
> cxx_builtin_include_directory: "/usr/local/wmh/gcc-7.2/include/c++/7.2.0/x86_64-apple-darwin16.7.0"
> cxx_builtin_include_directory: "/usr/local/wmh/gcc-7.2/include/c++/7.2.0/backward"
> cxx_builtin_include_directory: "/usr/local/wmh/gcc-7.2/lib/gcc/x86_64-apple-darwin16.7.0/7.2.0/include"
62,63c65,66
< cxx_builtin_include_directory: "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include"
< cxx_builtin_include_directory: "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"
---
> cxx_builtin_include_directory: "/usr/local/wmh/gcc-7.2/include"
> cxx_builtin_include_directory: "/usr/local/wmh/gcc-7.2/lib/gcc/x86_64-apple-darwin16.7.0/7.2.0/include-fixed"
... lots more diffs snipped...
Note that in using a much older version (0.3.2) of bazel before upgrading to 0.8.1, I was seeing a different error at this point ... the compilation of the file worked fine (and was thus definitely using the g++ binary) but was failing because it "could not find ld". The newer version of bazel appears to be a regression ... at least 0.3.2 would use g++ instead of clang.
Questions:
- Any thoughts on how I proceed from here to get bazel to work with a locally compiled g++?
- Alternatively, how can I get c++17 working with clang 9.0.0?
- Alternatively, how can I get c++17 working with bazel, regardless of which compiler it uses ;-)
P.S. I've attached the CROSSTOOL file generated when CC is set to my locally built g++, in case there are some simple changes that could be made to it that would get things using g++ instead of clang.
Thanks!
Wade