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`.

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.

----

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`).

----

As a drive-by fix, 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.)
  • Loading branch information
pnkfelix committed May 19, 2014
1 parent 5d2eddd commit 78d8293
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 76 deletions.
115 changes: 88 additions & 27 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 @@ -646,41 +670,69 @@ then
esac
fi

if [ ! -z "$CFG_ENABLE_CLANG" ]
if [ ! -z "$CC" ]
then
if [ -z "$CFG_CLANG" ]
msg "skipping compiler inference steps; using provided CC=$CC"
CFG_CC="$CC"
else
if [ ! -z "$CFG_ENABLE_CLANG" ]
then
err "clang requested but not found"
if [ -z "$CFG_CLANG" ]
then
err "clang requested but not found"
fi
CFG_CC="$CFG_CLANG"
else
CFG_CC="gcc"
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_CCACHE" ]
then
if [ -z "$CFG_CCACHE" ]
then
err "ccache requested but not found"
fi

CFG_CC="ccache $CFG_CC"
fi

msg "inferred compiler: $CFG_CC"
fi

if [ ! -z "$CFG_ENABLE_CCACHE" ]
if [ ! -z "$CFG_ENABLE_CLANG" ]
then
if [ -z "$CFG_CCACHE" ]
if [ -z "$CC" ] || [[ $CC == *clang ]]
then
err "ccache requested but not found"
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

CFG_C_COMPILER="ccache $CFG_C_COMPILER"
fi

# 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 @@ -961,7 +1013,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 +1043,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 +1135,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 Down
68 changes: 19 additions & 49 deletions mk/platform.mk
Original file line number Diff line number Diff line change
Expand Up @@ -81,57 +81,27 @@ CFG_DEPEND_FLAGS = -MMD -MP -MT $(1) -MF $(1:%.o=%.d)

AR := ar

CFG_INFO := $(info cfg: using $(CFG_C_COMPILER))
ifeq ($(CFG_C_COMPILER),clang)
# The -Qunused-arguments sidesteps spurious warnings from clang
ifeq ($(origin CC),default)
CC=clang -Qunused-arguments
endif
ifeq ($(origin CXX),default)
CXX=clang++ -Qunused-arguments
endif
ifeq ($(origin CPP),default)
CPP=clang -Qunused-arguments
endif
else
ifeq ($(CFG_C_COMPILER),gcc)
ifeq ($(origin CC),default)
CC=gcc
endif
ifeq ($(origin CXX),default)
CXX=g++
endif
ifeq ($(origin CPP),default)
CPP=gcc
define SET_FROM_CFG
ifdef CFG_$(1)
ifeq ($(origin $(1)),undefined)
$$(info cfg: using $(1)=$(CFG_$(1)) (CFG_$(1)))
$(1)=$(CFG_$(1))
endif
ifeq ($(origin $(1)),default)
$$(info cfg: using $(1)=$(CFG_$(1)) (CFG_$(1)))
$(1)=$(CFG_$(1))
endif
endif
else
ifeq ($(CFG_C_COMPILER),ccache clang)
endef

$(foreach cvar,CC CXX CPP CFLAGS CXXFLAGS CPPFLAGS,\
$(eval $(call SET_FROM_CFG,$(cvar))))

ifeq ($(CFG_ENABLE_CLANG),1)
# The -Qunused-arguments sidesteps spurious warnings from clang
ifeq ($(origin CC),default)
CC=ccache clang -Qunused-arguments
endif
ifeq ($(origin CXX),default)
CXX=ccache clang++ -Qunused-arguments
endif
ifeq ($(origin CPP),default)
CPP=ccache clang -Qunused-arguments
endif
else
ifeq ($(CFG_C_COMPILER),ccache gcc)
ifeq ($(origin CC),default)
CC=ccache gcc
endif
ifeq ($(origin CXX),default)
CXX=ccache g++
endif
ifeq ($(origin CPP),default)
CPP=ccache gcc
endif
else
CFG_ERR := $(error please try on a system with gcc or clang)
endif
endif
endif
CFLAGS += -Qunused-arguments
CXXFLAGS += -Qunused-arguments
CPPFLAGS += -Qunused-arguments
endif

CFG_RLIB_GLOB=lib$(1)-*.rlib
Expand Down

0 comments on commit 78d8293

Please sign in to comment.