bazelbuild / bazel

a fast, scalable, multi-language and extensible build system
https://bazel.build
Apache License 2.0
23.23k stars 4.07k forks source link

cpp toolchain: stop passing -std=c++0x per default #18181

Open davido opened 1 year ago

davido commented 1 year ago

Description of the bug:

After upgrading gcc version to 13 there are issues with different Bazel projects.

Consider this output:

  $ g++ -x c++ -std=c++0x -dM -E - </dev/null | grep __cplusplus
#define __cplusplus 201103L

However, without passing -std=c++0x option, the default is c++17:

  $ g++ -x c++ -dM -E - </dev/null | grep __cplusplus
#define __cplusplus 201703L

Now, trying to build abseil-cpp, this breakge is reported:

 ./absl/base/policy_checks.h:79:2: error: #error "C++ versions less than C++14 are not supported."
   79 | #error "C++ versions less than C++14 are not supported."
      |  ^~~~~

Where the Bazel command produced by Bazel@HEAD is:

  $ /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer '-std=c++0x' -MD -MF bazel-out/k8-fastbuild/bin/absl/base/_objs/atomic_hook_test_helper/atomic_hook_test_helper.pic.d '-frandom-seed=bazel-out/k8-fastbuild/bin/absl/base/_objs/atomic_hook_test_helper/atomic_hook_test_helper.pic.o' -fPIC -iquote . -iquote bazel-out/k8-fastbuild/bin -Wall -Wextra -Wcast-qual -Wconversion-null -Wformat-security -Wmissing-declarations -Woverlength-strings -Wpointer-arith -Wundef -Wunused-local-typedefs -Wunused-result -Wvarargs -Wvla -Wwrite-strings -DNOMINMAX -fno-canonical-system-headers -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -c absl/base/internal/atomic_hook_test_helper.cc -o bazel-out/k8-fastbuild/bin/absl/base/_objs/atomic_hook_test_helper/atomic_hook_test_helper.pic.o

Removing '-std=c++0x' makes this command work.

The code in ./absl/base/policy_checks.h:79:

// -----------------------------------------------------------------------------
// C++ Version Check
// -----------------------------------------------------------------------------

// Enforce C++14 as the minimum.
#if defined(_MSVC_LANG)
#if _MSVC_LANG < 201402L
#error "C++ versions less than C++14 are not supported."
#endif  // _MSVC_LANG < 201402L
#elif defined(__cplusplus)
#if __cplusplus < 201402L
#error "C++ versions less than C++14 are not supported."
#endif  // __cplusplus < 201402L
#endif

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

Bump gcc version to 13 and build abseil-cpp@HEAD (https://github.com/abseil/abseil-cpp) with Bazel@HEAD.

My environment:

  $ gcc --version
cc (SUSE Linux) 13.0.1 20230412 (experimental) [revision d339e9802f758e051b0a1ef6db732ff846cbf4e3]
[...]

Which operating system are you running Bazel on?

Linux

What is the output of bazel info release?

All released Bazel versions are affected including Bazel@HEAD.

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What's the output of git remote get-url origin; git rev-parse master; git rev-parse HEAD ?

No response

Have you found anything relevant by searching the web?

There are a number of reports:

https://github.com/abseil/abseil-cpp/issues/1431 https://github.com/protocolbuffers/protobuf/issues/12393 https://stackoverflow.com/questions/75850778/error-c-versions-less-than-c14-are-not-supported-in-bazel-how-to-resolve

Any other information, logs, or outputs that you want to share?

There is a workaround, bump -std-option in .bazelrc:

build --cxxopt=-std=c++14
build --host_cxxopt=-std=c++14
aaronmondal commented 1 year ago

It might be viable to bump this to C++ 17 instead of 14, as most non-ancient compilers support C++17 apart from a few exceptions that likely aren't relevant to Bazel's dependencies.

The Google style guide also encourages this.

davido commented 1 year ago

It might be viable to bump this to C++ 17 instead of 14, as most non-ancient compilers support C++17 apart from a few exceptions that likely aren't relevant to Bazel's dependencies.

Let's do it in two steps and bump C++ standard to C++14 per default first.

Bazel CI still depends on outdated toolchains, see https://github.com/bazelbuild/continuous-integration/issues/1593.

jsharpe commented 1 year ago

It might be viable to bump this to C++ 17 instead of 14, as most non-ancient compilers support C++17 apart from a few exceptions that likely aren't relevant to Bazel's dependencies.

Let's do it in two steps and bump C++ standard to C++14 per default first.

Bazel CI still depends on outdated toolchains, see bazelbuild/continuous-integration#1593.

Can we instead make the standard a feature on the toolchain so that the user has control over which c++ standard they want to use?

iancha1992 commented 1 year ago

A fix for this issue has been included in Bazel 6.4.0 RC4. Please test out the release candidate and report any issues as soon as possible. Thanks!

werkt commented 1 year ago

The MacOS c++ toolchain config for released bazel 6.4.0 still has c++11 as the version (better than c++0x, but still incompatible with abseil acquired with recent protobuf), if the goal was to standardize on c++14 as the global bazel default for supplied toolchains.

chetgnegy commented 1 year ago

I'm hitting this as well trying to build absl on MacOS. Are there any workarounds?

werkt commented 1 year ago

Recent bazels have https://github.com/bazelbuild/bazel/commit/d56dc18e1978102e35fbcf92c5d63f9f9eef37cd, which no longer tries to use xcode if it is available (regardless of the USE_XCODE... env var), and defers entirely to the unix toolchain. I might see about getting it in for a 6.5. 7 should have this as well when it is cut.

chetgnegy commented 1 year ago

Happy to hear a quick and optimistic response. So is it expected that I'll hit this issue on 6.3.2? What should I update to? I mostly care about stability, I believe I have all the features I need from bazel otherwise.

chetgnegy commented 1 year ago

All I want to do is build the google standard libraries using the google standard build tool on a major operating system using a c++ standard that is less than 12 years old. It is not reasonable that I've been stuck on this for days. Please help.

Here's what I've tried. The recommended way to download bazel according to your own documentation is to use bazelisk. https://bazel.build/install

I downloaded that and am trying to use it to download bazel 7.0.0, which according to your mailing list can be done using something like this: USE_BAZEL_VERSION=last_rc https://groups.google.com/g/bazel-discuss/c/RKRJEcLbOJc

However, I get this error message, indicating that that syntax does not work. 2023/11/16 23:43:22 could not download Bazel: could not resolve the version 'USE_BAZEL_VERSION=last_rc' to an actual version number: Invalid version 'USE_BAZEL_VERSION=last_rc' I've also tried "7.0.0", "7.0.0rc2", and "7.0.0-pre.20231018.3", all of which do not work.

My .bazelrc is specifying c++17 as follows: build --action_env=BAZEL_CXXOPTS="-std=c++17"

Bazel is ignoring my bazelrc file's specification for these external builds and I don't know why unless absl or bazel is specifically choosing to use a flag that is not longer supported. I've tried several other ways of specifying the build version including the workarounds in the original post above, but it's still using c++11. If you look through the subcommands, it seems like it's trying to use both the c++11 flag AND the c++17 flag.

(cd /private/var/tmp/_bazel_chetgnegy/a30584fc3eff3894500e295b9f28c635/execroot/__main__ && \
  exec env - \
    APPLE_SDK_PLATFORM=MacOSX \
    APPLE_SDK_VERSION_OVERRIDE=14.0 \
    BAZEL_CXXOPTS='-std=c++17' \
    PATH='/Users/chetgnegy/Library/Caches/bazelisk/downloads/sha256/eef2661dabc3de09c9c8f839f7789b29763ea9987659e432b3c4e6246b3fe5df/bin:/Library/Frameworks/Python.framework/Versions/3.11/bin:/Users/chetgnegy/anaconda3/bin:/Users/chetgnegy/anaconda3/condabin:/Library/Frameworks/Python.framework/Versions/3.11/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/Library/Apple/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Users/chetgnegy/Neptune/Source:/Users/chetgnegy/.rvm/bin' \
    XCODE_VERSION_OVERRIDE=15.0.1.15A507 \
    ZERO_AR_DATE=1 \
  external/local_config_cc/wrapped_clang_pp '-D_FORTIFY_SOURCE=1' -fstack-protector -fcolor-diagnostics -Wall -Wthread-safety -Wself-assign -fno-omit-frame-pointer -g '-std=c++11' 'DEBUG_PREFIX_MAP_PWD=.' -iquote external/com_googlesource_code_re2 -iquote bazel-out/darwin-dbg/bin/external/com_googlesource_code_re2 -iquote external/com_google_absl -iquote bazel-out/darwin-dbg/bin/external/com_google_absl -MD -MF bazel-out/darwin-dbg/bin/external/com_googlesource_code_re2/_objs/re2/dfa.d '-DBAZEL_CURRENT_REPOSITORY="com_googlesource_code_re2"' '-frandom-seed=bazel-out/darwin-dbg/bin/external/com_googlesource_code_re2/_objs/re2/dfa.o' -isysroot __BAZEL_XCODE_SDKROOT__ -F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks -F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks -no-canonical-prefixes -pthread -Wno-sign-compare '-std=c++17' -pthread -no-canonical-prefixes -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -target x86_64-apple-macosx14.0 -c external/com_googlesource_code_re2/re2/dfa.cc -o bazel-out/darwin-dbg/bin/external/com_googlesource_code_re2/_objs/re2/dfa.o)
meteorcloudy commented 1 year ago

However, I get this error message, indicating that that syntax does not work.

USE_BAZEL_VERSION=last_rc should be set as an env var, if you use .bazelversion file, it should just be last_rc.

build --action_env=BAZEL_CXXOPTS="-std=c++17"

This is not how you pass -std=c++17, please check an example here: https://github.com/bazelbuild/bazel/blob/cc2fa9a74a1d09788189dd596ceffbf3f1037d0f/.bazelrc#L52-L57

chetgnegy commented 1 year ago

Thank you for the tip. If that method is no longer supported, there's a lot of stack overflow to update. https://stackoverflow.com/questions/40260242/how-to-set-c-standard-version-when-build-with-bazel

I don't think you were suggesting that the build flag change would fix the issue, so here's more debugging.

.bazelversion containing last_rc gives me this: 2023/11/17 00:53:49 could not download Bazel: failed to download bazel: failed to download bazel: HTTP GET https://github.com/bazelbuild/bazel/releases/download/7.0.0rc3/bazel-7.0.0rc3-darwin-x86_64 failed with error 404

In other news, I downloaded 7.0.0-pre.20231018.3 and built it myself and now I hit this error.
Error in fail: Compiling objc_library targets requires the Apple CC toolchain which can be found here: https://github.com/bazelbuild/apple_support#toolchain-setup Even if I add the lines to my .bazelrc that are suggested in the toolchain setup link, I hit this error.

It's different, so while it seems like perhaps the issue in this bug is indeed fixed closer to HEAD, it looks like the fix described by werkt@ above: "Recent bazels have https://github.com/bazelbuild/bazel/commit/d56dc18e1978102e35fbcf92c5d63f9f9eef37cd, which no longer tries to use xcode if it is available (regardless of the USE_XCODE... env var), and defers entirely to the unix toolchain." So if we're using the unix toolchain, it can't build apple targets? I get this is a prerelease, but if that's true that's a huge issue. I can't be stuck between a build system that doesn't support absl and a build system that doesn't support Apple. It took me ages to migrate everything to bazel. I need bazel to work.

I guess I should try some old version of absl that still supports c++11?

chetgnegy commented 11 months ago

If nobody can give me a workaround, can we reopen this?

trybka commented 11 months ago

cc: @keith

I think I'm missing something--if you use the Apple CC Toolchain (per the instructions), and then build with --config=macos does that work?

Can you provide explicit instructions for reproing with 7.0.0.something? Assume I have a mac and have not yet run a bazelisk install or checked out Absl. What I am ideally looking for is:

What version of macOS I need to run. What things I should have checked out (absl-cpp?). What bazel/bazelisk build command to run (I cannot find that in any of the above comments).

chetgnegy commented 11 months ago

I'll start by trying to clarify that where I started being stuck and where I became stuck are different, and that where I became stuck wasn't relevant to the original bug. Now that I'm reading your post I've realized this got a bit derailed, and I'm sorry for that, but I guess this is as good of a place as any to try and clarify.

Where I started:

Problem: absl wasn't building with bazel 6.4.0 on Sonoma 14.1.1 mac. I believe it should as this is a major bazel release and absl is a major google lib. You can reproduce this problem using the following repo (note the hidden .bazeliskrc and .bazelrc files). I believe all you need to do is install bazelisk using homebrew as I have. bazel build Test. Of course the bazelisk bit is unrelated, but it's handy for switching between released versions. You can delete the .bazeliskrc file and just use bazel 6.4.0 as usual.

It produces the error.

In file included from test.cc:1:
In file included from external/com_google_absl/absl/types/span.h:63:
In file included from external/com_google_absl/absl/base/attributes.h:37:
In file included from external/com_google_absl/absl/base/config.h:86:
external/com_google_absl/absl/base/policy_checks.h:79:2: error: "C++ versions less than C++14 are not supported."
#error "C++ versions less than C++14 are not supported."

Up until that point, this is relevant to the opened bug. In trying to fix that issue that I started uncovering different problems, and confusingly posted about them here as it was a continuance of the same conversation.

Where I am now:

Because it was suggested to me that this problem was fixed in prereleased versions of bazel, I tried updating. As far as I can tell, bazelisk doesn't support these versions, so I downloaded bazel-7.0.0-pre.20231018, built it using bazel 6.4.0, brew unlink bazelisk-ed it, and copied the newly built bazel 7 binary as follows: cp bazel-bin/src/bazel /usr/local/bin/bazel. From this point on, everything uses bazel-7.0.0-pre.20231018.

The error above is fixed if I use that same repo from above, noting that the .bazeliskrc file is now ignored by my self-built version of bazel.

In this adventure to clarify my problem, I believe that I've resolved my issue, as I can now build the new (empty) target in this updated repo using bazel build AppleLib. I had to go through the steps at https://github.com/bazelbuild/apple_support#toolchain-setup thoroughly.

I guess the problem I'm having is that bazel is just evolving faster than I can keep up with as an independent developer. It was my expectation that common libs like absl would work as long as I'm using one of the LTS bazel releases. When that didn't work, I got pushed into a prerelease because I was simply stuck in a hard place by my build system. I don't know what a MODULE file is, if or when --config=macos needs to be used, or what other changes I'm going to encounter. The "notes" included with these prereleases don't say anything about breaking changes. While I know I can Google documentation when I have a question, it's a lot of research and testing to do when I don't know if that's going to fix my problem. I can't build the things I want to build if I keep going on week-long tangents due to a change in my build system. Thanks to everyone involved in this bug for their help, but please consider the impact that instability in bazel has on your users. It really consumes a lot of time.

So now that I understand things, I believe we can close this bug again.

chetgnegy commented 11 months ago

Although all that said, I think I'm still having a relevant issue to this bug. I'm clearly specifying to use c++ 17 in my build. Over specifying, probably... but I'm still seeing libs that are being built with c++14-- however BOTH c++14 and c++17 flags are making it into the command. This for a non-absl target, one that isn't external to my repo.

.bazelrc

build --action_env=BAZEL_CXXOPTS="-std=c++17"

build:linux --cxxopt=-std=c++17
build:linux --host_cxxopt=-std=c++17
build:macos --cxxopt=-std=c++17
build:macos --host_cxxopt=-std=c++17

Using the --subcommands flag.

(cd /private/var/tmp/_bazel_chetgnegy/a30584fc3eff3894500e295b9f28c635/execroot/_main && \
  exec env - \
    APPLE_SDK_PLATFORM=MacOSX \
    APPLE_SDK_VERSION_OVERRIDE=14.0 \
    BAZEL_CXXOPTS='-std=c++17' \
    PATH='/Library/Frameworks/Python.framework/Versions/3.11/bin:/Users/chetgnegy/anaconda3/bin:/Users/chetgnegy/anaconda3/condabin:/Library/Frameworks/Python.framework/Versions/3.11/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/Applications/VMware Fusion.app/Contents/Public:<my path>/.rvm/bin' \
    XCODE_VERSION_OVERRIDE=15.0.1.15A507 \
    ZERO_AR_DATE=1 \
  external/apple_support~1.11.1~apple_cc_configure_extension~local_config_apple_cc/wrapped_clang_pp '-D_FORTIFY_SOURCE=1' -fstack-protector -fcolor-diagnostics -Wall -Wthread-safety -Wself-assign -fno-omit-frame-pointer -g0 -O2 -DNDEBUG '-DNS_BLOCK_ASSERTIONS=1' '-std=c++14' '-fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.' '-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR' -iquote . -iquote bazel-out/darwin_x86_64-opt/bin -iquote external/com_github_gflags_gflags -iquote bazel-out/darwin_x86_64-opt/bin/external/com_github_gflags_gflags -iquote external/com_github_glog_glog -iquote bazel-out/darwin_x86_64-opt/bin/external/com_github_glog_glog -iquote external/eigen_archive -iquote bazel-out/darwin_x86_64-opt/bin/external/eigen_archive -Ibazel-out/darwin_x86_64-opt/bin/external/com_github_gflags_gflags/_virtual_includes/gflags -Ibazel-out/darwin_x86_64-opt/bin/external/com_github_glog_glog/_virtual_includes/glog -isystem external/eigen_archive -isystem bazel-out/darwin_x86_64-opt/bin/external/eigen_archive -MD -MF bazel-out/darwin_x86_64-opt/bin/<MY OBJECT PATH> -DEIGEN_MPL2_ONLY '-DBAZEL_CURRENT_REPOSITORY=""' '-frandom-seed=bazel-out/darwin_x86_64-opt/bin/<MY OBJECT PATH>' -isysroot __BAZEL_XCODE_SDKROOT__ -F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks -F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks -no-canonical-prefixes -pthread -Wno-sign-compare -fvisibility-inlines-hidden '-std=c++17' -no-canonical-prefixes -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -target x86_64-apple-macosx14.0 -c <MY TARGET> -o bazel-out/darwin_x86_64-opt/bin/<MY OBJECT PATH>)
# Configuration: f19b206758f706ed5fdf210e9e5ff364093afb88af91e8e75c0b8d5564bbe1a6
keith commented 11 months ago

The reason your original repro fails is because these .bazelrc lines:

build:macos --cxxopt=-std=c++17
build:macos --host_cxxopt=-std=c++17

Are not being used because you also have to set:

build --enable_platform_specific_config

Because it's not enabled by default, once I do that it works. The reason it's fixed in 7.x is because the C++ default was bumped to 14 (it was meant to be bumped everywhere in 6.4.x in https://github.com/bazelbuild/bazel/pull/19794/ but it looks like this one missed the macOS specific toolchain used when you have Xcode installed). The reason your BAZEL_CXXOPTS doesn't work is because the Xcode specific toolchain doesn't respect that variable.

IMO the real solution for absl is to encode this in their BUILD files somewhere, although then I suppose they'd have to worry about allowing overrides of that version for folks who intentionally build absl with a newer C++ standard.

chetgnegy commented 11 months ago

I extrapolated that commenting out that --enable_platform_specific_config line would fix my current problem as well, but it seems to still use both c++14 and c++17 flags (in that order), presumably ignoring the later one. Here's an excerpt from my bazelrc file if you have suggestions for me in my new non-absl-related problem.

build --action_env=BAZEL_CXXOPTS="-std=c++17"
build:macos --cxxopt=-std=c++17
build:macos --host_cxxopt=-std=c++17

build --enable_platform_specific_config
build:macos --apple_crosstool_top=@local_config_apple_cc//:toolchain
build:macos --crosstool_top=@local_config_apple_cc//:toolchain
build:macos --host_crosstool_top=@local_config_apple_cc//:toolchain
keith commented 11 months ago

The later one wins, you can see this with clang by passing -### to see the underlying invocation, only 1 will be there:

clang -### -std=c++14 -std=c++17 /tmp/main.c
...
 "/Applications/Xcode-15.0.0-RC1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" ... "-std=c++17" ...

It's still possible that some libs are setting copts = ["-std=c++14"], directly in the BUILD rule, which will override your .bazelrc flags, but theoretically in that case it should be fine. What is the specific issue now? I think most folks ignore that first flag from the toolchain since it has no effect

chetgnegy commented 11 months ago

Libs that require c++17 symbols are not building for me, even though I'm specifying to use c++17 in the build rule.

The actual error I get is: error: no member named 'byte' in namespace 'std' which implies that it's not using c++17. It comes from a third party library, which implies that I'm not just missing a header include somewhere.

keith commented 11 months ago

Is that error in the case of the subcommands you posted above? Maybe it's worth passing --cxxopt=-v to see the final compiler invocation to check those flags, since that one looks good if so

chetgnegy commented 11 months ago

I get different specific errors every time because it's compiling different files on different threads. All of them seem to point to not using c++17, some explicitly check for that and produce an error.

Are you just testing if the flag gets passed, or are you hoping the log is more verbose?

(cd /private/var/tmp/_bazel_chetgnegy/a30584fc3eff3894500e295b9f28c635/execroot/_main && \
  exec env - \
    APPLE_SDK_PLATFORM=MacOSX \
    APPLE_SDK_VERSION_OVERRIDE=14.0 \
    BAZEL_CXXOPTS='-std=c++17' \
    PATH='/Library/Frameworks/Python.framework/Versions/3.11/bin:/Users/chetgnegy/anaconda3/bin:/Users/chetgnegy/anaconda3/condabin:/Library/Frameworks/Python.framework/Versions/3.11/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/Applications/VMware Fusion.app/Contents/Public:/Users/chetgnegy/Neptune/Source:/Users/chetgnegy/.rvm/bin' \
    XCODE_VERSION_OVERRIDE=15.0.1.15A507 \
    ZERO_AR_DATE=1 \
  external/apple_support~1.11.1~apple_cc_configure_extension~local_config_apple_cc/wrapped_clang_pp '-D_FORTIFY_SOURCE=1' -fstack-protector -fcolor-diagnostics -Wall -Wthread-safety -Wself-assign -fno-omit-frame-pointer -g0 -O2 -DNDEBUG '-DNS_BLOCK_ASSERTIONS=1' '-std=c++14' '-fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.' '-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR' -iquote external/com_google_absl -iquote bazel-out/darwin_x86_64-opt/bin/external/com_google_absl -MD -MF bazel-out/darwin_x86_64-opt/bin/external/com_google_absl/absl/strings/_objs/str_format_internal/parser.d '-DBAZEL_CURRENT_REPOSITORY="com_google_absl"' '-frandom-seed=bazel-out/darwin_x86_64-opt/bin/external/com_google_absl/absl/strings/_objs/str_format_internal/parser.o' -isysroot __BAZEL_XCODE_SDKROOT__ -F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks -F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks -no-canonical-prefixes -pthread -Wno-sign-compare -fvisibility-inlines-hidden -v -Wall -Wextra -Wcast-qual -Wconversion -Wfloat-overflow-conversion -Wfloat-zero-conversion -Wfor-loop-analysis -Wformat-security -Wgnu-redeclared-enum -Winfinite-recursion -Winvalid-constexpr -Wliteral-conversion -Wmissing-declarations -Woverlength-strings -Wpointer-arith -Wself-assign -Wshadow-all -Wshorten-64-to-32 -Wsign-conversion -Wstring-conversion -Wtautological-overlap-compare -Wtautological-unsigned-zero-compare -Wundef -Wuninitialized -Wunreachable-code -Wunused-comparison -Wunused-local-typedefs -Wunused-result -Wvla -Wwrite-strings -Wno-float-conversion -Wno-implicit-float-conversion -Wno-implicit-int-float-conversion -Wno-unknown-warning-option -DNOMINMAX -no-canonical-prefixes -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -target x86_64-apple-macosx14.0 -c external/com_google_absl/absl/strings/internal/str_format/parser.cc -o bazel-out/darwin_x86_64-opt/bin/external/com_google_absl/absl/strings/_objs/str_format_internal/parser.o)
# Configuration: e560d235d22728ab8aa6cb694bc27afcaea031198e55cf265ab156e40d0976a8
# Execution platform: @local_config_platform//:host
keith commented 11 months ago

With -v you should see more of a log, but this one doesn't have -std=c++17

chetgnegy commented 11 months ago

OK, thanks. So what are my options?

keith commented 11 months ago

can you provide a repro with that case?

chetgnegy commented 11 months ago

Somewhat to my own surprise, I actually can! TestRepo.zip

This includes a pull of the JUCE repo, which by anyone's standards makes this not a minimum example, but I think you don't have to understand anything about JUCE except for ThirdParty/Juce/JUCE/modules/juce_core/system/juce_CompilerSupport.h in the lines surrounding 91. It relies on the __cplusplus macro, which I think comes from the compiler directly (I don't really know)

If you do bazel build WorkingTest, it builds without issue. WorkingTest uses the code from https://en.cppreference.com/w/cpp/types/byte, which requires c++17. If you do bazel build Test, it doesn't work. It fails to build JUCE for many reasons, the first of which being the one above. I specify nothing in my build files about c++xx, that's all in my bazelrc.

keith commented 11 months ago

juce.bzl defines an objc_library target with objective-c++ files, which do not inherit the --cxxopts. you can pass --objccopt=-std=c++17 if you only have objective-c++ files, or you can use this workaround to target just the objc++ files (and not the pure objc files) https://github.com/bazelbuild/bazel/issues/12716#issuecomment-1113754835

chetgnegy commented 11 months ago

I see. That does seem to fix that issue.

So is it correct that I should have all three of these, and not the BAZEL_CXXOPTS line? Is there a way to use a variable in a bazelrc file so that I only need to specify c++17 once?

build:macos --cxxopt=-std=c++17
build:macos --host_cxxopt=-std=c++17
build:macos --objccopt=-std=c++17
keith commented 11 months ago

yes that looks good (if you end up needing the host_ version of objccopt you'd have to use host_per_file_copt)

There's no flag that implies all of them, theoretically we could make that env var work in the Xcode specific toolchain, I doubt there was a good reason it didn't, but even so I don't think that would cover the objc case unless the issue i linked above was fixed

chetgnegy commented 11 months ago

Thanks so much for all the help!

chetgnegy commented 11 months ago

Last note, I have to do this to get around https://github.com/bazelbuild/bazel/issues/5318, which seems a little jank, but at least I'm not blocked on it.

# build:macos --objccopt=-std=c++17
build --per_file_copt=.*\.mm\$@-std=c++17
adam3141 commented 10 months ago

For such a basic requirement, why can't we specify, as a feature, to use a particular standard C++ version.

I have come across a number of things in trying to get C++20 into my builds.

I am using Bazel version 7.0.0 executing in Linux - WSL with a very minimal C++ program

#include <iostream>
int main() {}

My .bazelrc file is this

build:linux --cxxopt=-std=c++20
build:linux --host_cxxopt=-std=c++20

However, despite the example @meteorcloudy gave, I don't get C++20

Result of bazel build -s //projects/minexample

/usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer '-std=c++14' -MD -MF bazel-out/k8-fastbuild/bin/projects/minexample/_objs/minexample/main.pic.d '-frandom-seed=bazel-out/k8-fastbuild/bin/projects/minexample/_objs/minexample/main.pic.o' -fPIC -iquote . -iquote bazel-out/k8-fastbuild/bin -iquote external/bazel_tools -iquote bazel-out/k8-fastbuild/bin/external/bazel_tools -fno-canonical-system-headers -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -c projects/minexample/main.cpp -o bazel-out/k8-fastbuild/bin/projects/minexample/_objs/minexample/main.pic.o

However, if I modify the .bazelrc file to now ``` build --cxxopt=-std=c++20 ``` I now get `-std=c++20` appended to the gcc command, but I note the `-std=c++14` still exists. If I use the `build --action_env=BAZEL_CXXOPTS="-std=c++20"` the gcc command no longer includes `-std=c++14` but is infact replaced by `-std=c++20` so on some level, Bazel is smart enough to understand that when the option to use the C++20 standard exists in the environment variable, it doesn't include the C++14 standard option however, specifying as a build option, it uses both. So a few questions: 1. Why does build:linux not work? 2. Why is there different behaviours for the same `-std=c++20` option passed into Bazel via the different mechanisms (env variable vs cmd line)? 3. Is there anyway I can augment the C++ toolchain to add a particular feature so that I can pass in --feature="use-cpp20" for example? 4. Will there be any official features in upcoming Bazel releases to specify particular C++ features, similar to how CMake implements these? Thanks

keith commented 10 months ago
  1. If you're not massing --enable_platform_specific_config yourself this is not enabled by default
  2. You could but you'd have to create your own toolchain which probably isn't worth the overhead