Skip to content

Commit ae67b74

Browse files
committed
Make configure respect (and save) values for CC, CXX, CFLAGS, etc.
I mostly tried to remain backwards compatible with old invocations of the `configure` script; if you do not want to use `CC` et al., you should not have to; you can keep using `--enable-clang` and/or `--enable-ccache`. The overall intention is to capture the following precedences for guessing the C compiler: 1. Value of `CC` at make invocation time. 2. Value of `CC` at configure invocation time. 3. Compiler inferred at configure invocation time (`gcc` or `clang`). The strategy is to check (at `configure` time) if each of the environment variables is set, and if so, save its value in a corresponding `CFG_` variable (e.g. `CFG_CC`). Then, in the makefiles, if `CC` is not set but `CFG_CC` is, then we use the `CFG_CC` setting as `CC`. Also, I fold the potential user-provided `CFLAGS` and `CXXFLAGS` values into all of the per-platform `CFLAGS` and `CXXFLAGS` settings. (This was opposed to adding `$(CFLAGS)` in an ad-hoc manner to various parts of the mk files.) Fix rust-lang#13805. ---- Note that if you try to set the compiler to clang via the `CC` and `CXX` environment variables, you will probably need to also set `CXXFLAGS` to `--enable-libcpp` so that LLVM will be configured properly. ---- Introduce CFG_USING_CLANG, which is distinguished from CFG_ENABLE_CLANG because the former represents "we think we're using clang, choose appropriate warning-control options" while the latter represents "we asked configure (or the host required) that we attempt to use clang, so check that we have an appropriate version of clang." The main reason I added this is that I wanted to allow the user to choose clang via setting the `CC` environment variable, but I did not want that method of selection to get confused with the user passing the `--enable-clang` option. ---- A digression: The `configure` script does not infer the compiler setting if `CC` is set; but if `--enable-clang` was passed, then it *does* still attempt to validate that the clang version is compatible. Supporting this required revising `CLANG_VERSION` check to be robust in face of user-provided `CC` value. In particular, on Travis, the `CC` is set to `gcc` and so the natural thing to do is to attempt to use `gcc` as the compiler, but Travis is also passing `--enable-clang` to configure. So, what is the right answer in the face of these contradictory requests? One approach would be to have `--enable-clang` supersede the setting for `CC` (and instead just call whatever we inferred for `CFG_CLANG`). That sounds maximally inflexible to me (pnkfelix): a developer requesting a `CC` value probably wants it respected, and should be able to set it to something else; it is harder for that developer to hack our configure script to change its inferred path to clang. A second approach would be to blindly use the `CC` value but keep going through the clang version check when `--enable-clang` is turned on. But on Travis (a Linux host), the `gcc` invocation won't print a clang version, so we would not get past the CLANG_VERSION check in that context. A third approach would be to never run the CLANG_VERSION check if `CC` is explicitly set. That is not a terrible idea; but if the user uses `CC` to pass in a path to some other version of clang that they want to test, probably should still send that through the `CLANG_VERSION` check. So in the end I (pnkfelix) took a fourth approach: do the CLANG_VERSION check if `CC` is unset *or* if `CC` is set to a string ending with `clang`. This way setting `CC` to things like `path/to/clang` or `ccache clang` will still go through the CLANG_VERSION check, while setting `CC` to `gcc` or some unknown compiler will skip the CLANG_VERSION check (regardless of whether the user passed --enable-clang to `configure`). ---- Drive-by fixes: * The call that sets `CFG_CLANG_VERSION` was quoting `"$CFG_CC"` in its invocation, but that does not play nicely with someone who sets `$CFG_CC` to e.g. `ccache clang`, since you do not want to intepret that whole string as a command. (On the other hand, a path with spaces might need the quoted invocation. Not sure which one of these corner use-cases is more important to support.) * Fix chk_cc error message to point user at `gcc` not `cc`.
1 parent 84320a4 commit ae67b74

File tree

2 files changed

+176
-118
lines changed

2 files changed

+176
-118
lines changed

configure

+119-31
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,30 @@ opt() {
223223
fi
224224
}
225225

226+
envopt() {
227+
local NAME=$1
228+
local V="CFG_${NAME}"
229+
eval VV=\$$V
230+
231+
# If configure didn't set a value already, then check environment.
232+
#
233+
# (It is recommended that the configure script always check the
234+
# environment before setting any values to envopt variables; see
235+
# e.g. how CFG_CC is handled, where it first checks `-z "$CC"`,
236+
# and issues msg if it ends up employing that provided value.)
237+
if [ -z "$VV" ]
238+
then
239+
eval $V=\$$NAME
240+
eval VV=\$$V
241+
fi
242+
243+
# If script or environment provided a value, save it.
244+
if [ ! -z "$VV" ]
245+
then
246+
putvar $V
247+
fi
248+
}
249+
226250
msg "looking for configure programs"
227251
need_cmd cmp
228252
need_cmd mkdir
@@ -621,7 +645,7 @@ then
621645
if !((chk_cc gcc clang && chk_cc g++ clang) ||
622646
(chk_cc gcc gcc &&( chk_cc g++ g++ || chk g++ gcc))) then
623647
err "the gcc and g++ in your path point to different compilers.
624-
Check which versions are in your path with cc --version and g++ --version.
648+
Check which versions are in your path with gcc --version and g++ --version.
625649
To resolve this problem, either fix your PATH or run configure with --enable-clang"
626650
fi
627651

@@ -646,41 +670,101 @@ then
646670
esac
647671
fi
648672

649-
if [ ! -z "$CFG_ENABLE_CLANG" ]
673+
# Even when the user overrides the choice of CC, still try to detect
674+
# clang to disable some clang-specific warnings. We here draw a
675+
# distinction between:
676+
#
677+
# CFG_ENABLE_CLANG : passed --enable-clang, or host "requires" clang,
678+
# CFG_USING_CLANG : compiler (clang / gcc / $CC) looks like clang.
679+
#
680+
# This distinction is important because there are some safeguards we
681+
# would prefer to skip when merely CFG_USING_CLANG is set; but when
682+
# CFG_ENABLE_CLANG is set, that indicates that we are opting into
683+
# running such safeguards.
684+
685+
if [ ! -z "$CC" ]
650686
then
651-
if [ -z "$CFG_CLANG" ]
687+
msg "skipping compiler inference steps; using provided CC=$CC"
688+
CFG_CC="$CC"
689+
690+
CFG_OSX_CC_VERSION=$("$CFG_CC" --version 2>&1 | grep "clang")
691+
if [ $? -eq 0 ]
652692
then
653-
err "clang requested but not found"
693+
step_msg "note, user-provided CC looks like clang; CC=$CC."
694+
CFG_USING_CLANG=1
695+
putvar CFG_USING_CLANG
654696
fi
655-
CFG_CLANG_VERSION=$("$CFG_CLANG" \
656-
--version \
657-
| grep version \
658-
| sed 's/.*\(version .*\)/\1/; s/.*based on \(LLVM .*\))/\1/' \
659-
| cut -d ' ' -f 2)
660-
661-
case $CFG_CLANG_VERSION in
662-
(3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 3.4* | 3.5* )
663-
step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
664-
CFG_C_COMPILER="clang"
665-
;;
666-
(*)
667-
err "bad CLANG version: $CFG_CLANG_VERSION, need >=3.0svn"
668-
;;
669-
esac
670697
else
671-
CFG_C_COMPILER="gcc"
698+
if [ ! -z "$CFG_ENABLE_CLANG" ]
699+
then
700+
if [ -z "$CFG_CLANG" ]
701+
then
702+
err "clang requested but not found"
703+
fi
704+
CFG_CC="$CFG_CLANG"
705+
CFG_USING_CLANG=1
706+
putvar CFG_USING_CLANG
707+
else
708+
CFG_CC="gcc"
709+
fi
710+
fi
711+
712+
if [ ! -z "$CFG_ENABLE_CLANG" ]
713+
then
714+
if [ -z "$CC" ] || [[ $CC == *clang ]]
715+
then
716+
CFG_CLANG_VERSION=$($CFG_CC \
717+
--version \
718+
| grep version \
719+
| sed 's/.*\(version .*\)/\1/; s/.*based on \(LLVM .*\))/\1/' \
720+
| cut -d ' ' -f 2)
721+
722+
case $CFG_CLANG_VERSION in
723+
(3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 3.4* | 3.5* )
724+
step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
725+
if [ -z "$CC" ]
726+
then
727+
CFG_CC="clang"
728+
fi
729+
;;
730+
(*)
731+
err "bad CLANG version: $CFG_CLANG_VERSION, need >=3.0svn"
732+
;;
733+
esac
734+
else
735+
msg "skipping CFG_ENABLE_CLANG version check; provided CC=$CC"
736+
fi
672737
fi
673738

674739
if [ ! -z "$CFG_ENABLE_CCACHE" ]
675740
then
676-
if [ -z "$CFG_CCACHE" ]
741+
if [ -z "$CC" ]
677742
then
678-
err "ccache requested but not found"
743+
if [ -z "$CFG_CCACHE" ]
744+
then
745+
err "ccache requested but not found"
746+
fi
747+
748+
CFG_CC="ccache $CFG_CC"
679749
fi
750+
fi
680751

681-
CFG_C_COMPILER="ccache $CFG_C_COMPILER"
752+
if [ -z "$CC" -a -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ]
753+
then
754+
err "either clang or gcc is required"
682755
fi
683756

757+
# All safeguards based on $CFG_ENABLE_CLANG should occur before this
758+
# point in the script; after this point, script logic should inspect
759+
# $CFG_USING_CLANG rather than $CFG_ENABLE_CLANG.
760+
761+
# Set CFG_{CC,CXX,CPP,CFLAGS,CXXFLAGS}
762+
envopt CC
763+
envopt CXX
764+
envopt CPP
765+
envopt CFLAGS
766+
envopt CXXFLAGS
767+
684768
# a little post-processing of various config values
685769
CFG_PREFIX=${CFG_PREFIX%/}
686770
CFG_MANDIR=${CFG_MANDIR%/}
@@ -742,11 +826,6 @@ do
742826
esac
743827
done
744828

745-
if [ -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ]
746-
then
747-
err "either clang or gcc is required"
748-
fi
749-
750829
if [ ! -z "$CFG_PERF" ]
751830
then
752831
HAVE_PERF_LOGFD=`$CFG_PERF stat --log-fd 2>&1 | grep 'unknown option'`
@@ -961,7 +1040,7 @@ do
9611040
;;
9621041
esac
9631042

964-
case "$CFG_C_COMPILER" in
1043+
case "$CFG_CC" in
9651044
("ccache clang")
9661045
LLVM_CXX_32="ccache clang++ -m32 -Qunused-arguments"
9671046
LLVM_CC_32="ccache clang -m32 -Qunused-arguments"
@@ -991,6 +1070,16 @@ do
9911070

9921071
LLVM_CXX_64="g++"
9931072
LLVM_CC_64="gcc"
1073+
;;
1074+
1075+
(*)
1076+
msg "inferring LLVM_CXX/CC from CXX/CC = $CXX/$CC"
1077+
LLVM_CXX_32="$CXX -m32"
1078+
LLVM_CC_32="$CC -m32"
1079+
1080+
LLVM_CXX_64="$CXX"
1081+
LLVM_CC_64="$CC"
1082+
;;
9941083
esac
9951084

9961085
LLVM_CFLAGS_32="-m32"
@@ -1073,7 +1162,6 @@ putvar CFG_PREFIX
10731162
putvar CFG_BUILD
10741163
putvar CFG_HOST
10751164
putvar CFG_TARGET
1076-
putvar CFG_C_COMPILER
10771165
putvar CFG_LIBDIR
10781166
putvar CFG_LIBDIR_RELATIVE
10791167
putvar CFG_DISABLE_MANAGE_SUBMODULES
@@ -1084,7 +1172,7 @@ putvar CFG_DISABLE_INJECT_STD_VERSION
10841172

10851173
# Avoid spurious warnings from clang by feeding it original source on
10861174
# ccache-miss rather than preprocessed input.
1087-
if [ ! -z "$CFG_ENABLE_CCACHE" ] && [ ! -z "$CFG_ENABLE_CLANG" ]
1175+
if [ ! -z "$CFG_ENABLE_CCACHE" ] && [ ! -z "$CFG_USING_CLANG" ]
10881176
then
10891177
CFG_CCACHE_CPP2=1
10901178
putvar CFG_CCACHE_CPP2

0 commit comments

Comments
 (0)