rm -f configure.log
all=no
debug=no
libs=""
logging=no
check=no
closefrom=yes
competition=no
coverage=no
flexible=yes
profile=no
memory_fuzzing=no
contracts=yes
tracing=yes
unlocked=yes
pedantic=no
options=""
quiet=no
m32=no
contrib=yes
ipasir=yes
shared=no
pic=no
if [ -f ./scripts/colors.sh ]
then
. ./scripts/colors.sh
elif [ -f ../scripts/colors.sh ]
then
. ../scripts/colors.sh
else
BAD=""
HILITE=""
BOLD=""
NORMAL=""
fi
die () {
if [ -f configure.log ]
then
checklog=" (check also 'configure.log')"
else
checklog=""
fi
cecho "${BOLD}configure:${NORMAL} ${BAD}error:${NORMAL} $*${checklog}"
exit 1
}
rm -f configure.log
msg () {
cecho "${BOLD}configure:${NORMAL} $*"
}
for dir in . ..
do
[ -f $dir/scripts/colors.sh ] || continue
. $dir/scripts/colors.sh || exit 1
break
done
usage () {
cat << EOF
usage: configure [ <option> ... ]
where '<option>' is one of the following
-h|--help print this command line summary
-g|--debug compile with debugging information
-c|--check compile with assertion checking (default for '-g')
-l|--log[ging] include logging code (but disabled by default)
-a|--all short cut for all above, e.g., '-g -l' (thus also '-c')
-q|--quiet exclude message and profiling code (logging too)
-p|--pedantic add '--pedantic' and '-Werror' compilation flag
-s|--symbols add '-ggdb3' (even for optimized compilation)
--coverage compile with '-ftest-coverage -fprofile-arcs' for 'gcov'
--profile compile with '-pg' to profile with 'gprof'
--memory-fuzzing compile with '-rdynamic -fno-omit-frame-pointer' and
'-DMOBICAL_MEMORY' to fuzz for bad memory allocation handling
--no-contracts compile without API contract checking code
--no-tracing compile without API call tracing code
--no-contrib compile without contributed code
--no-ipasir compile without ipasir interface
--competition configure for the competition
('--quiet', '--no-contracts', '--no-tracing')
-f... pass '-f<option>[=<val>]' options to the makefile
-W... pass '-W<warning>' options to the makefile
-m32 pass '-m32' to the compiler (compile for 32 bit)
-ggdb3 pass '-ggdb3' to makefile (like '-s')
-O|-O[123] pass '-O' or '-O[123]' to the makefile
-static... pass '-static...' option to makefile
-shared add '-fpic' compilation flag and produce shared library
The environment variable CXX can be used to set a different C++
compiler than the default 'g++'. Similarly you can add additional
compilation options by setting CXXFLAGS and CFLAGS. For example
CXX=clang++ CXXFLAGS=-fPIC ./configure
will enforce to use 'clang++' as C++ compiler and also produce
position independent code. In order to be shell independent we also
allow to have the following form. Thus for instance
./configure CXX="g++-8" CXXFLAGS="-fPIC -fsanitize=address"
will have the same effect as
CXX="g++-8" ./configure -fPIC -fsanitize=address
The following configuration options might be usefull during porting the
code to a new platform and are usually not necessary to change.
--no-closefrom use our own 'closefrom' replacement
--no-flexible do not use flexible array members
--no-unlocked force compilation without unlocked IO
EOF
exit 0
}
while [ $# -gt 0 ]
do
case $1 in
-h|--help) usage;;
-a|--all) all=yes;;
-g|--debug) debug=yes;;
-c|--check) check=yes;;
-l|--log|--logging) logging=yes;;
-l*) libs="$libs $1";;
-p|--pedantic) pedantic=yes;;
-q|--quiet) quiet=yes;;
--no-contracts | --no-contract) contracts=no;;
--no-tracing | --no-trace) tracing=no;;
--no-contrib) contrib=no;;
--no-ipasir) ipasir=no;;
--coverage) coverage=yes;;
--profile) profile=yes;;
--memory-fuzzing) memory_fuzzing=yes;;
--competition) competition=yes;;
--no-closefrom) closefrom=no;;
--no-flexible) flexible=no;;
--no-unlocked) unlocked=no;;
-m32) options="$options $1";m32=yes;;
-fpic|-fPIC) options="$options $1"; pic=yes;;
-f*|-W*|-ggdb3|-O|-O1|-O2|-O3) options="$options $1";;
-s|--symbols) options="$options -ggdb3";;
-static*) options="$options $1";;
-shared|--shared) shared=yes;;
CXX=*)
CXX="`expr \"$1\" : 'CXX=\(.*\)'`"
;;
CXXFLAGS=*)
CXXFLAGS="`expr \"$1\" : 'CXXFLAGS=\(.*\)'`"
;;
CC=*)
CC="`expr \"$1\" : 'CXX=\(.*\)'`"
;;
CFLAGS=*)
CFLAGS="`expr \"$1\" : 'CFLAGS=\(.*\)'`"
;;
*) die "invalid option '$1' (try '-h')";;
esac
shift
done
if [ $quiet = yes ]
then
[ $logging = yes ] && die "can not combine '-q' with '-l'"
fi
if [ $all = yes ]
then
[ $check = yes ] && die "'-a' subsumes '-c'"
[ $debug = yes ] && die "'-a' subsumes '-g'"
[ $logging = yes ] && die "'-a' subsumes '-l'"
check=yes
debug=yes
logging=yes
elif [ $debug = yes ]
then
[ $check = yes ] && die "'-g' subsumes '-c'"
check=yes
fi
build_in_default_build_sub_directory () {
if [ -d build ]
then
msg "reusing default 'build' directory"
else
mkdir build 2>/dev/null || \
die "failed to generate 'build' directory"
msg "making default 'build' directory"
fi
cd build
msg "building in default ${HILITE}'`pwd`'${NORMAL}"
build=build
}
if [ -f configure -a -f makefile.in -a -d src ]
then
root="`pwd`"
build_in_default_build_sub_directory
elif [ -f ../configure -a -f ../makefile.in -a -d ../src ]
then
cwd="`pwd`"
build=`basename "$cwd"`
root=`dirname "$cwd"`
case x"$build" in
xsrc|xtest|xscripts)
cd ..
build_in_default_build_sub_directory
;;
*)
msg "building in ${HILITE}'$build'${NORMAL} sub-directory"
;;
esac
else
die "call 'configure' from root of CaDiCaL source or a sub-directory"
fi
msg "root directory '$root'"
src="$root/src"
if [ -d "$src" ]
then
msg "source directory '$src'"
else
die "could not find source director '$src'"
fi
[ x"$CXX" = x ] && CXX=g++
[ x"$CXXFLAGS" = x ] || CXXFLAGS="$CXXFLAGS "
if [ x"$CC" = x ]
then
case x"$CXX" in
xclang++) CC=clang ;;
xg++) CC=gcc ;;
*) CC="$CXX";;
esac
fi
[ x"$CFLAGS" = x ] || CFLAGS="$CFLAGS "
case x"$CXX" in
x*g++*|x*clang++*) CXXFLAGS="${CXXFLAGS}-Wall -Wextra"; CFLAGS="${CFLAGS}-Wall -Wextra";;
*) CXXFLAGS="${CXXFLAGS}-W"; CFLAGS="${CFLAGS}-W";;
esac
if [ $debug = yes ]
then
CXXFLAGS="$CXXFLAGS -g"
CFLAGS="$CFLAGS -g"
else
case x"$CXX" in
x*g++*|x*clang++*) CXXFLAGS="$CXXFLAGS -O3"; CFLAGS="$CFLAGS -O3";;
*) CXXFLAGS="$CXXFLAGS -O"; CFLAGS="$CFLAGS -O";;
esac
fi
if [ $m32 = yes ]
then
case x"$CXX" in
x*g++*)
options="$options -mpc64"
msg "forcing portable 64-bit FPU mode ('-mpc64') for '$CXX'"
;;
esac
fi
if [ $competition = yes ]
then
quiet=yes
contracts=no
tracing=no
contrib=no
fi
[ $check = no ] && CXXFLAGS="$CXXFLAGS -DNDEBUG"
[ $logging = yes ] && CXXFLAGS="$CXXFLAGS -DLOGGING"
[ $quiet = yes ] && CXXFLAGS="$CXXFLAGS -DQUIET"
[ $profile = yes ] && CXXFLAGS="$CXXFLAGS -pg"
[ $coverage = yes ] && CXXFLAGS="$CXXFLAGS -ftest-coverage -fprofile-arcs"
[ $check = no ] && CFLAGS="$CFLAGS -DNDEBUG"
[ $logging = yes ] && CFLAGS="$CFLAGS -DLOGGING"
[ $quiet = yes ] && CFLAGS="$CFLAGS -DQUIET"
[ $profile = yes ] && CFLAGS="$CFLAGS -pg"
[ $coverage = yes ] && CFLAGS="$CFLAGS -ftest-coverage -fprofile-arcs"
[ $memory_fuzzing = yes ] && CXXFLAGS="$CXXFLAGS -rdynamic -fno-omit-frame-pointer -DMOBICAL_MEMORY"
if [ $pedantic = yes ]
then
CXXFLAGS="$CXXFLAGS --pedantic -Werror -std=c++11"
CFLAGS="$CFLAGS --pedantic -Werror"
case x"$CXX" in
x*g++*|x*clang++*)
CXXFLAGS="${CXXFLAGS} -Wp,-D_GLIBCXX_ASSERTIONS"
;;
esac
case x"$CC" in
x*g++*|x*clang++*)
CFLAGS="${CFLAGS} -Wp,-D_GLIBCXX_ASSERTIONS"
;;
esac
fi
[ $contracts = no ] && CXXFLAGS="$CXXFLAGS -DNCONTRACTS"
[ $tracing = no ] && CXXFLAGS="$CXXFLAGS -DNTRACING"
[ $contrib = no ] && CXXFLAGS="$CXXFLAGS -DNCONTRIB"
[ $ipasir = no ] && CXXFLAGS="$CXXFLAGS -DNIPASIR"
[ $shared = yes -a $pic = no ] && CXXFLAGS="$CXXFLAGS -fpic"
[ $contracts = no ] && CFLAGS="$CFLAGS -DNCONTRACTS"
[ $tracing = no ] && CFLAGS="$CFLAGS -DNTRACING"
[ $contrib = no ] && CFLAGS="$CFLAGS -DNCONTRIB"
[ $ipasir = no ] && CFLAGS="$CFLAGS -DNIPASIR"
[ $shared = yes -a $pic = no ] && CFLAGS="$CFLAGS -fpic"
CXXFLAGS="$CXXFLAGS$options"
CFLAGS="$CFLAGS$options"
case x"$CXX" in
x*g++* | x*clang++*) WERROR="-Werror -pedantic";;
*) WERROR="";;
esac
feature=./configure-hello-world
cat <<EOF > $feature.cpp
#include <iostream>
int main () { std::cout << "hello world" << std::endl; }
EOF
if $CXX $CXXFLAGS $WERROR -o $feature.exe $feature.cpp 2>>configure.log
then
if [ ! "`$feature.exe 2>>configure.log|tr -d '\r'`" = "hello world" ]
then
die "execution of '$feature.exe' failed"
fi
else
die "test compilation '$feature.cpp'"
fi
feature=./configure-requires-c++11
cat <<EOF > $feature.cpp
#include <cstdio>
#include <vector>
// old variadic macro usage 'ARGS...' / '#ARGS' discouraged in g++-7...
// new variadic macro usage '...' / '__VA_ARGS__' available in C99/C++11
//
#define MACRO(FMT, ...) printf (FMT "\n", __VA_ARGS__)
// we use ranged for loops which became available in gcc 4.6 and for
// the gcc 4.6 as well as 4.8 requires '-std=c++11' too.
//
unsigned f (const std::vector<unsigned> & a) {
unsigned res = 0;
for (auto i : a) res += i;
return res;
}
int main () { MACRO ("%d", 42); return 0; }
EOF
if $CXX $CXXFLAGS $WERROR -o $feature.exe $feature.cpp 2>>configure.log
then
if [ "`$feature.exe 2>>configure.log|tr -d '\r'`" = 42 ]
then
msg "compiler supports all required C99/C++11 extensions"
else
die "checking compilation without '-std=c++11' failed"
fi
else
CXXFLAGS="$CXXFLAGS -std=c++11"
if $CXX $CXXFLAGS -o $feature.exe $feature.cpp 2>>configure.log
then
if [ "`$feature.exe 2>>configure.log|tr -d '\r'`" = 42 ]
then
msg "using '-std=c++11' for all required C99/C++11 extensions"
else
die "checking compilation with '-std=c++11' failed"
fi
else
die "compiler does not support C99/C++11 even with '-std=c++11'"
fi
fi
if [ $flexible = yes ]
then
feature=./configure-have-flexible-array-members
cat <<EOF > $feature.cpp
#include <cstdlib>
struct S {
int size;
int flexible_array_member[];
};
int main () {
struct S * s = (struct S*) malloc (12);
s->size = 2;
s->flexible_array_member[0] = 1;
s->flexible_array_member[1] = -1;
int res = 0;
for (int i = 0; i != s->size; i++)
res += s->flexible_array_member[i];
free (s);
return res;
}
EOF
if $CXX $CXXFLAGS -o $feature.exe $feature.cpp 2>>configure.log
then
if $feature.exe
then
msg "compiler configuration supports flexible array members"
else
msg "no support for flexible array members (non zero exit code)"
flexible=no
fi
else
msg "no support for flexible array members (compilation failed)"
flexible=no
fi
else
msg "not using flexible array members (since '--no-flexible' specified)"
fi
[ $flexible = no ] && CXXFLAGS="$CXXFLAGS -DNFLEXIBLE"
if [ $unlocked = yes ]
then
feature=./configure-have-unlocked-io
cat <<EOF > $feature.cpp
#include <cstdio>
int main () {
const char * path = "$feature.log";
FILE * file = fopen (path, "w");
if (!file) return 1;
if (putc_unlocked (42, file) != 42) return 1;
if (fclose (file)) return 1;
file = fopen (path, "r");
if (!file) return 1;
if (getc_unlocked (file) != 42) return 1;
if (fclose (file)) return 1;
return 0;
}
EOF
if $CXX $CXXFLAGS -o $feature.exe $feature.cpp 2>>configure.log
then
if $feature.exe
then
msg "unlocked IO with '{putc,getc}_unlocked' seems to work"
else
msg "not using unlocked IO (running '$feature.exe' failed)"
unlocked=no
fi
else
msg "not using unlocked IO (failed to compile '$feature.cpp')"
unlocked=no
fi
else
msg "not using unlocked IO (since '--no-unlocked' specified)"
fi
[ $unlocked = no ] && CXXFLAGS="$CXXFLAGS -DNUNLOCKED"
if [ $closefrom = yes ]
then
feature=./configure-have-closefrom
cat <<EOF > $feature.cpp
extern "C" {
#include <unistd.h>
};
int main () {
closefrom (0);
return 0;
}
EOF
if $CXX $CXXFLAGS -o $feature.exe $feature.cpp 2>>configure.log
then
if $feature.exe
then
msg "'closefrom' seems to be working"
else
msg "'closefrom' does not seem to be working"
closefrom=no
fi
else
msg "can not use 'closefrom' (failed to compile '$feature.cpp')"
closefrom=no
fi
else
msg "not using 'closefrom' (since '--no-closefrom' specified)"
fi
[ $closefrom = no ] && CXXFLAGS="$CXXFLAGS -DNCLOSEFROM"
goals="libcadical.a cadical mobical"
sharedlibrary="libcadical.so"
cadicaldynamic="cadical-dynamic"
if [ $shared = yes ]
then
msg "adding '$sharedlibrary' and '$cadicaldynamic' to default makefile goal"
goals="$goals $sharedlibrary $cadicaldynamic"
else
if [ -f $sharedlibrary ]
then
msg "removing stale dynamic library '$sharedlibrary' (without '-shared')"
rm -f $sharedlibrary || exit 1
fi
if [ -f $cadicaldynamic ]
then
msg "removing stale dynamically linked '$cadicaldynamic' (without '-shared')"
rm -f $cadicaldynamic || exit 1
fi
msg "no '$sharedlibrary' shared library generated (without '-shared')"
msg "no '$cadicaldynamic' dynamically linked binary generated (without '-shared')"
fi
msg "compiling C++ with ${HILITE}'$CXX $CXXFLAGS'${NORMAL}"
msg "compiling C with ${HILITE}'$CC $CFLAGS'${NORMAL}"
rm -f makefile
sed \
-e "2c\\
# This 'makefile' is generated from '../makefile.in'." \
-e "s,@CXX@,$CXX," \
-e "s#@CXXFLAGS@#$CXXFLAGS#" \
-e "s#@CC@#$CC#" \
-e "s#@CFLAGS@#$CFLAGS#" \
-e "s#@LIBS@#$libs#" \
-e "s#@CONTRIB@#$contrib#" \
-e "s#@IPASIR@#$ipasir#" \
-e "s#@ROOT@#$root#" \
-e "s#@GOALS@#$goals#" \
../makefile.in > makefile
msg "generated '$build/makefile' from '../makefile.in'"
build="`pwd`"
makefile="`dirname "$build"`/makefile"
cat <<EOF > "$makefile"
CADICALBUILD=$build
all:
\$(MAKE) -C "\$(CADICALBUILD)"
clean:
@if [ -d "\$(CADICALBUILD)" ]; \\
then \\
if [ -f "\$(CADICALBUILD)"/makefile ]; \\
then \\
touch "\$(CADICALBUILD)"/build.hpp; \\
\$(MAKE) -C "\$(CADICALBUILD)" clean; \\
fi; \\
rm -rf "\$(CADICALBUILD)"; \\
fi
rm -f "$src/makefile"
rm -f "$makefile"
test:
\$(MAKE) -C "\$(CADICALBUILD)" test
cadical:
\$(MAKE) -C "\$(CADICALBUILD)" cadical
mobical:
\$(MAKE) -C "\$(CADICALBUILD)" mobical
update:
\$(MAKE) -C "\$(CADICALBUILD)" update
format:
\$(MAKE) -C "\$(CADICALBUILD)" format
.PHONY: all cadical clean mobical test format
EOF
msg "generated '../makefile' as proxy to ..."
msg "... '$build/makefile'"
if [ -f $src/makefile ]
then
msg "removing '$src/makefile'"
rm -f $src/makefile
fi
msg "linking '$root/makefile'"
ln -s $root/makefile $src/makefile
msg "now run ${HILITE}'make'${NORMAL} to compile CaDiCaL"
msg "optionally run 'make test'"