CmdStan 2.17.0 build process not detecting the compiler correctly

If I try to run make build on RHEL 6, I get the following errors:

clang++ -Wall -I . -isystem stan/lib/stan_math/lib/eigen_3.3.3 -isystem stan/lib/stan_math/lib/boost_1.64.0 -isystem stan/lib/stan_math/lib/cvodes_2.9.0/include -std=c++1y -DBOOST_RESULT_OF_USE_TR1 -DBOOST_NO_DECLTYPE -DBOOST_DISABLE_ASSERTS -DBOOST_PHOENIX_NO_VARIADIC_EXPRESSION -I src -I stan/src -isystem stan/lib/stan_math/ -DEIGEN_NO_DEBUG -DFUSION_MAX_VECTOR_SIZE=12 -stdlib=libc++ -Wno-unused-function -Wno-uninitialized -DNO_FPRINTF_OUTPUT -pipe  -c -O3 -o bin/cmdstan/stanc.o src/cmdstan/stanc.cpp
make: clang++: Command not found
make: *** [bin/cmdstan/stanc.o] Error 127

The immediate reason for the error is obvious: I don’t have clang++. The problem is why the build process is even invoking clang++ in the first place.

It looks like the makefile setup is buggy. In the top level makefile, the variable CC is set to g++, but after that, the makefile includes the file stan/lib/stan_math/make/default_compiler_options which sets CC to clang++, making the original initialization of CC completely pointless. The file stan/lib/stan_math/make/detect_cc doesn’t seem to make much sense either. It apparently tries to detect the C++ compiler by looking for strings in the variable CC, but either the user has already set CC, in which case detection already falls on the user, or the “detection” just regurgitates the default. It’s not like there’s any attempt to see if a compiler executable is in some path or the like.

This is also not a one-time problem affecting the build. Any time I need to compile a Stan file, I’d need to do make CC=my-compiler path/to/stan_file.

(There’s also the questionable decision to set CC to be the name of a C++ compiler, even though CC is a variable often traditionally set to a C compiler, especially on Linux clusters.)

In any case, compiler detection seems to be a mess. As a “chicken wire and duct tape” fix, I suggest removing the variables CC, O, O_STANC, and AR from stan/lib/stan_math/make/default_compiler_options. That way, at least if the end user sets those variables in the top-level makefile, they’ll actually do what it looks like they’re supposed to do.

You can also put

CC=g++

into a file called local in the make/ directory.

But it still doesn’t make sense to have CC, etc. set in both the main makefile and in stan/lib/stan_math/make/default_compiler_options, since the variables set in the latter totally override the former. Also, it would help to have comments in the main makefile indicate that this is the intended use of make/local, e.g. something like this:

##
# Users should only need to set these three variables for use:
#
# - CC: The compiler to use. Expecting g++ or clang++.
# - O: Optimization level. Valid values are {0, 1, 2, 3}.
# - AR: archiver (must specify for cross-compiling)
#
# To override them, create a file "local" in the "make" 
# subdirectory. Do NOT edit this file directly. (see
# the CmdStan guide for details).
##
CC = g++
O = 3
O_STANC = 0
AR = ar

ariddell:

Is it because clang++ is hard-coded in stan_math/make/default_compiler_options?

Yes.

I am not disputing that. I think we messed up when trying to get the makefiles in shape for 2.17.