Improved Covered Default Switch detection

If cmake happens to detect GCC for the C compiler and Clang for the C++ compiler, then a manual override of either the C compiler or SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG is required. This has been happening on my Darwin build environments:

– The C compiler identification is GNU 4.2.1
– The CXX compiler identification is Clang 4.1.0

Without the manual overrides, all C sources fail to compile with:

[ 4%] Building C object lib/Support/CMakeFiles/LLVMSupport.dir/regcomp.c.o
cd /Users/jabbey/src/llvmCommit/build/lib/Support && /usr/bin/gcc -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -fPIC -I/Users/jabbey/src/llvmCommit/build/lib/Support -I/Users/jabbey/src/llvmCommit/lib/Support -I/Users/jabbey/src/llvmCommit/build/include -I/Users/jabbey/src/llvmCommit/include -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic -Wno-long-long -Wcovered-switch-default -fno-exceptions -o CMakeFiles/LLVMSupport.dir/regcomp.c.o -c /Users/jabbey/src/llvmCommit/lib/Support/regcomp.c
cc1: error: unrecognized command line option "-Wcovered-switch-default"

The problem stems from HandleLLVMOptions.cmake where a single check of the warning option is performed using check_cxx_compiler_flag, and then upon success add_llvm_definitions appends to the flag to a list consumed by both C and CXX compilers.

Attached is a patch which updates HandleLLVMOptions.cmake to:

  • Test C and CXX compiler separately for -Wcovered-switch-default
  • Split SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG into a C and CXX variant
  • Replace set( ${variable} “${variable} arg”) with list( append $variable “arg” )
  • Check cmake_minimum_required of at least CMake 2.4 (where list append was introduced).

Ok to commit?

Joe

improved-covered-default-switch-detection.patch (3.09 KB)

ATT00001.htm (227 Bytes)

How did you end up in this situation? Something has gone very wrong
if the build system finds clang++ but not clang.

-Eli

I don’t think I’ve done anything terribly unique.

  1. Install Xcode

  2. Installing command-line tools

jabbeymbp:llvmCommit jabbey$ ls -l /usr/bin/gcc /usr/bin/g++ /usr/bin/c++ /usr/bin/cc
lrwxr-xr-x 1 root wheel 7 Nov 20 01:16 /usr/bin/c++ → clang++
lrwxr-xr-x 1 root wheel 5 Nov 20 01:16 /usr/bin/cc → clang
lrwxr-xr-x 1 root wheel 12 Nov 20 01:17 /usr/bin/g++ → llvm-g+±4.2
lrwxr-xr-x 1 root wheel 12 Nov 20 01:17 /usr/bin/gcc → llvm-gcc-4.2
jabbeymbp:llvmCommit jabbey$ xcode-select --print-path
/Applications/Xcode.app/Contents/Developer

jabbeymbp:llvmCommit jabbey$ cmake --version
cmake version 2.8.8

Is this not as expected?

Joe

Additionally:

jabbeymbp:llvmCommit jabbey$ xcodebuild -version
Xcode 4.5.2
Build version 4G2008a

Joe

Is this not as expected?

I don't think so. Unless you ask for something different, CMake should
use c++ (->clang++) for C++ and cc (->clang) for C as defaults. Doing
otherwise looks like a bug. Unless OSX has a tradition of broken or
inferior cc which makes gcc preferable.

BTW, what I mentioned on my other message was on Linux.

Interesting. Can you apply my patch and test to see if it works with your builds?

Joe

It's too late here, sorry, but your patch seems plain correct.

The unrelated set(... -> list(APPEND changes shouldn't be mixed with the
fix proper, IMO. Same for the cmake_minimum_required command. LLVM
already requires cmake version 2.8 on the top CMakeLists.txt.

BTW, you want

set(FOO "${FOO} something")

instead of

list(APPEND FOO something)

because those variables are strings, not lists. Using the `list' version
may cause unwanted semicolons in the command line.

Thanks for the extra info. I understood that list append was "faster", and wasn't aware of spurious semicolons.

I'll start a new thread with the reduced patch.

:slight_smile:

Joe

If cmake happens to detect GCC for the C compiler and Clang for the C++
compiler, then a manual override of either the C compiler or
SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG is required. This has been happening
on my Darwin build environments:

-- The C compiler identification is GNU 4.2.1
-- The CXX compiler identification is Clang 4.1.0

How/why has this been happening, exactly? Seems kind of surprising for
any platform (or user, for that matter) to mismatch between the C and
C++ compiler.

That being said, I'm not sure we should prohibit this configuration,
I'm just not sure how much I'd really want to tweak the build system
to accommodate it given that there is a workaround.

I think I can answer that. For some reason, cmake starts with 'c++' when detecting the C++ compiler, but prefers 'gcc' to plain 'cc' when detecting the C compiler. On most systems, this isn't a problem, because 'c++' (if present) is usually symlinked to 'g++'. On recent Xcode setups, however, 'cc' and 'c++' are symlinked to clang--but 'gcc' is still llvm-gcc! Hence, when cmake goes to detect the compilers, it picks up llvm-gcc for C and clang for C++. (Seriously, when is Apple finally going to drop llvm-gcc and just symlink gcc to clang?)

IMO, this looks like a cmake bug. It shouldn't be preferring 'gcc' to 'cc'. You'll have to take it up with them, though; I have no idea why they look for gcc first. Maybe a look through their VCS logs will help.

Chip

I think this should be fixed in CMake 2.8.10 (although I haven't tried it myself), see

http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-July/052252.html

This was indeed a cmake bug, fixed here:
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=27b74445

See also this thread:
http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-July/052252.html