Skip to content

Commit

Permalink
Make configure respect (and save) values for CC, CXX, CFLAGS, etc.
Browse files Browse the repository at this point in the history
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 #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`.
  • Loading branch information
pnkfelix committed May 20, 2014
1 parent 84320a4 commit ae67b74
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 118 deletions.
150 changes: 119 additions & 31 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,30 @@ opt() {
fi
}

envopt() {
local NAME=$1
local V="CFG_${NAME}"
eval VV=\$$V

# If configure didn't set a value already, then check environment.
#
# (It is recommended that the configure script always check the
# environment before setting any values to envopt variables; see
# e.g. how CFG_CC is handled, where it first checks `-z "$CC"`,
# and issues msg if it ends up employing that provided value.)
if [ -z "$VV" ]
then
eval $V=\$$NAME
eval VV=\$$V
fi

# If script or environment provided a value, save it.
if [ ! -z "$VV" ]
then
putvar $V
fi
}

msg "looking for configure programs"
need_cmd cmp
need_cmd mkdir
Expand Down Expand Up @@ -621,7 +645,7 @@ then
if !((chk_cc gcc clang && chk_cc g++ clang) ||
(chk_cc gcc gcc &&( chk_cc g++ g++ || chk g++ gcc))) then
err "the gcc and g++ in your path point to different compilers.
Check which versions are in your path with cc --version and g++ --version.
Check which versions are in your path with gcc --version and g++ --version.
To resolve this problem, either fix your PATH or run configure with --enable-clang"
fi

Expand All @@ -646,41 +670,101 @@ then
esac
fi

if [ ! -z "$CFG_ENABLE_CLANG" ]
# Even when the user overrides the choice of CC, still try to detect
# clang to disable some clang-specific warnings. We here draw a
# distinction between:
#
# CFG_ENABLE_CLANG : passed --enable-clang, or host "requires" clang,
# CFG_USING_CLANG : compiler (clang / gcc / $CC) looks like clang.
#
# This distinction is important because there are some safeguards we
# would prefer to skip when merely CFG_USING_CLANG is set; but when
# CFG_ENABLE_CLANG is set, that indicates that we are opting into
# running such safeguards.

if [ ! -z "$CC" ]
then
if [ -z "$CFG_CLANG" ]
msg "skipping compiler inference steps; using provided CC=$CC"
CFG_CC="$CC"

CFG_OSX_CC_VERSION=$("$CFG_CC" --version 2>&1 | grep "clang")
if [ $? -eq 0 ]
then
err "clang requested but not found"
step_msg "note, user-provided CC looks like clang; CC=$CC."
CFG_USING_CLANG=1
putvar CFG_USING_CLANG
fi
CFG_CLANG_VERSION=$("$CFG_CLANG" \
--version \
| grep version \
| sed 's/.*\(version .*\)/\1/; s/.*based on \(LLVM .*\))/\1/' \
| cut -d ' ' -f 2)

case $CFG_CLANG_VERSION in
(3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 3.4* | 3.5* )
step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
CFG_C_COMPILER="clang"
;;
(*)
err "bad CLANG version: $CFG_CLANG_VERSION, need >=3.0svn"
;;
esac
else
CFG_C_COMPILER="gcc"
if [ ! -z "$CFG_ENABLE_CLANG" ]
then
if [ -z "$CFG_CLANG" ]
then
err "clang requested but not found"
fi
CFG_CC="$CFG_CLANG"
CFG_USING_CLANG=1
putvar CFG_USING_CLANG
else
CFG_CC="gcc"
fi
fi

if [ ! -z "$CFG_ENABLE_CLANG" ]
then
if [ -z "$CC" ] || [[ $CC == *clang ]]
then
CFG_CLANG_VERSION=$($CFG_CC \
--version \
| grep version \
| sed 's/.*\(version .*\)/\1/; s/.*based on \(LLVM .*\))/\1/' \
| cut -d ' ' -f 2)

case $CFG_CLANG_VERSION in
(3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 3.4* | 3.5* )
step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
if [ -z "$CC" ]
then
CFG_CC="clang"
fi
;;
(*)
err "bad CLANG version: $CFG_CLANG_VERSION, need >=3.0svn"
;;
esac
else
msg "skipping CFG_ENABLE_CLANG version check; provided CC=$CC"
fi
fi

if [ ! -z "$CFG_ENABLE_CCACHE" ]
then
if [ -z "$CFG_CCACHE" ]
if [ -z "$CC" ]
then
err "ccache requested but not found"
if [ -z "$CFG_CCACHE" ]
then
err "ccache requested but not found"
fi

CFG_CC="ccache $CFG_CC"
fi
fi

CFG_C_COMPILER="ccache $CFG_C_COMPILER"
if [ -z "$CC" -a -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ]
then
err "either clang or gcc is required"
fi

# All safeguards based on $CFG_ENABLE_CLANG should occur before this
# point in the script; after this point, script logic should inspect
# $CFG_USING_CLANG rather than $CFG_ENABLE_CLANG.

# Set CFG_{CC,CXX,CPP,CFLAGS,CXXFLAGS}
envopt CC
envopt CXX
envopt CPP
envopt CFLAGS
envopt CXXFLAGS

# a little post-processing of various config values
CFG_PREFIX=${CFG_PREFIX%/}
CFG_MANDIR=${CFG_MANDIR%/}
Expand Down Expand Up @@ -742,11 +826,6 @@ do
esac
done

if [ -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ]
then
err "either clang or gcc is required"
fi

if [ ! -z "$CFG_PERF" ]
then
HAVE_PERF_LOGFD=`$CFG_PERF stat --log-fd 2>&1 | grep 'unknown option'`
Expand Down Expand Up @@ -961,7 +1040,7 @@ do
;;
esac

case "$CFG_C_COMPILER" in
case "$CFG_CC" in
("ccache clang")
LLVM_CXX_32="ccache clang++ -m32 -Qunused-arguments"
LLVM_CC_32="ccache clang -m32 -Qunused-arguments"
Expand Down Expand Up @@ -991,6 +1070,16 @@ do

LLVM_CXX_64="g++"
LLVM_CC_64="gcc"
;;

(*)
msg "inferring LLVM_CXX/CC from CXX/CC = $CXX/$CC"
LLVM_CXX_32="$CXX -m32"
LLVM_CC_32="$CC -m32"

LLVM_CXX_64="$CXX"
LLVM_CC_64="$CC"
;;
esac

LLVM_CFLAGS_32="-m32"
Expand Down Expand Up @@ -1073,7 +1162,6 @@ putvar CFG_PREFIX
putvar CFG_BUILD
putvar CFG_HOST
putvar CFG_TARGET
putvar CFG_C_COMPILER
putvar CFG_LIBDIR
putvar CFG_LIBDIR_RELATIVE
putvar CFG_DISABLE_MANAGE_SUBMODULES
Expand All @@ -1084,7 +1172,7 @@ putvar CFG_DISABLE_INJECT_STD_VERSION

# Avoid spurious warnings from clang by feeding it original source on
# ccache-miss rather than preprocessed input.
if [ ! -z "$CFG_ENABLE_CCACHE" ] && [ ! -z "$CFG_ENABLE_CLANG" ]
if [ ! -z "$CFG_ENABLE_CCACHE" ] && [ ! -z "$CFG_USING_CLANG" ]
then
CFG_CCACHE_CPP2=1
putvar CFG_CCACHE_CPP2
Expand Down
Loading

5 comments on commit ae67b74

@bors
Copy link
Contributor

@bors bors commented on ae67b74 May 21, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at pnkfelix@ae67b74

@bors
Copy link
Contributor

@bors bors commented on ae67b74 May 21, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging pnkfelix/rust/fsk-fix-13805 = ae67b74 into auto

@bors
Copy link
Contributor

@bors bors commented on ae67b74 May 21, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pnkfelix/rust/fsk-fix-13805 = ae67b74 merged ok, testing candidate = f30382d

@bors
Copy link
Contributor

@bors bors commented on ae67b74 May 21, 2014

@bors
Copy link
Contributor

@bors bors commented on ae67b74 May 21, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = f30382d

Please sign in to comment.