Enabling Portable Build Systems
Galois is developing build system configuration capabilities to improve the portability of build systems.
»
/* confdefs.h */
#define PACKAGE_NAME "Test"
#define PACKAGE_TARNAME "test"
#define PACKAGE_VERSION "0.1"
#define PACKAGE_STRING "Test 0.1"
#define PACKAGE_BUGREPORT "trevor@galois.com"
#define PACKAGE_URL ""
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UNISTD_H 1
#define HAVE_DLFCN_H 1
#define LT_OBJDIR ".libs/"
#define PACKAGE "Test"
#define VERSION "0.1"
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char hello ();
int
main ()
{
return hello ();
;
return 0;
}
$ gcc -o conftest -g -O2 conftest.c -lhello >&5
Configuration
API
Identify
Environments
Compatibility is KEY
Sandbox development
Cut out the guesswork
Reduce the recursive ./configure cycle.
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems. If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.
ac_cv_build=${ac_cv_build=i686-pc-linux-gnu}
ac_cv_c_compiler_gnu=${ac_cv_c_compiler_gnu=yes}
ac_cv_env_CC_set=
ac_cv_env_CC_value=
ac_cv_env_CFLAGS_set=
ac_cv_env_CFLAGS_value=
ac_cv_env_CPPFLAGS_set=
ac_cv_env_CPPFLAGS_value=
ac_cv_env_CPP_set=
ac_cv_env_CPP_value=
ac_cv_env_LDFLAGS_set=
ac_cv_env_LDFLAGS_value=
ac_cv_env_LIBS_set=
ac_cv_env_LIBS_value=
ac_cv_env_build_alias_set=
ac_cv_env_build_alias_value=
ac_cv_env_host_alias_set=
ac_cv_env_host_alias_value=
ac_cv_env_target_alias_set=
ac_cv_env_target_alias_value=
ac_cv_header_dlfcn_h=${ac_cv_header_dlfcn_h=yes}
ac_cv_header_inttypes_h=${ac_cv_header_inttypes_h=yes}
ac_cv_header_memory_h=${ac_cv_header_memory_h=yes}
ac_cv_header_stdc=${ac_cv_header_stdc=yes}
ac_cv_header_stdint_h=${ac_cv_header_stdint_h=yes}
ac_cv_header_stdlib_h=${ac_cv_header_stdlib_h=yes}
ac_cv_header_string_h=${ac_cv_header_string_h=yes}
ac_cv_header_strings_h=${ac_cv_header_strings_h=yes}
ac_cv_header_sys_stat_h=${ac_cv_header_sys_stat_h=yes}
ac_cv_header_sys_types_h=${ac_cv_header_sys_types_h=yes}
ac_cv_header_unistd_h=${ac_cv_header_unistd_h=yes}
ac_cv_host=${ac_cv_host=i686-pc-linux-gnu}
ac_cv_objext=${ac_cv_objext=o}
ac_cv_path_EGREP=${ac_cv_path_EGREP='/bin/grep -E'}
ac_cv_path_FGREP=${ac_cv_path_FGREP='/bin/grep -F'}
ac_cv_path_GREP=${ac_cv_path_GREP=/bin/grep}
ac_cv_path_SED=${ac_cv_path_SED=/bin/sed}
ac_cv_path_install=${ac_cv_path_install='/usr/bin/install -c'}
ac_cv_path_mkdir=${ac_cv_path_mkdir=/bin/mkdir}
ac_cv_prog_AWK=${ac_cv_prog_AWK=gawk}
ac_cv_prog_CPP=${ac_cv_prog_CPP='gcc -E'}
ac_cv_prog_ac_ct_AR=${ac_cv_prog_ac_ct_AR=ar}
ac_cv_prog_ac_ct_CC=${ac_cv_prog_ac_ct_CC=gcc}
ac_cv_prog_ac_ct_OBJDUMP=${ac_cv_prog_ac_ct_OBJDUMP=objdump}
ac_cv_prog_ac_ct_RANLIB=${ac_cv_prog_ac_ct_RANLIB=ranlib}
ac_cv_prog_ac_ct_STRIP=${ac_cv_prog_ac_ct_STRIP=strip}
ac_cv_prog_cc_c89=${ac_cv_prog_cc_c89=}
ac_cv_prog_cc_g=${ac_cv_prog_cc_g=yes}
ac_cv_prog_make_make_set=${ac_cv_prog_make_make_set=yes}
am_cv_CC_dependencies_compiler_type=${am_cv_CC_dependencies_compiler_type=gcc3}
lt_cv_deplibs_check_method=${lt_cv_deplibs_check_method=pass_all}
lt_cv_file_magic_cmd=${lt_cv_file_magic_cmd='$MAGIC_CMD'}
lt_cv_file_magic_test_file=${lt_cv_file_magic_test_file=}
lt_cv_ld_reload_flag=${lt_cv_ld_reload_flag=-r}
lt_cv_nm_interface=${lt_cv_nm_interface='BSD nm'}
lt_cv_objdir=${lt_cv_objdir=.libs}
lt_cv_path_LD=${lt_cv_path_LD=/usr/bin/ld}
lt_cv_path_NM=${lt_cv_path_NM='/usr/bin/nm -B'}
lt_cv_prog_compiler_c_o=${lt_cv_prog_compiler_c_o=yes}
lt_cv_prog_compiler_pic_works=${lt_cv_prog_compiler_pic_works=yes}
lt_cv_prog_compiler_rtti_exceptions=${lt_cv_prog_compiler_rtti_exceptions=no}
lt_cv_prog_compiler_static_works=${lt_cv_prog_compiler_static_works=yes}
lt_cv_prog_gnu_ld=${lt_cv_prog_gnu_ld=yes}
lt_cv_sys_global_symbol_pipe=${lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p'\'''}
test "${lt_cv_sys_global_symbol_to_c_name_address+set}" = set || lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"\2", (void *) \&\2},/p'\'''
test "${lt_cv_sys_global_symbol_to_c_name_address_lib_prefix+set}" = set || lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \(lib[^ ]*\)$/ {"\2", (void *) \&\2},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"lib\2", (void *) \&\2},/p'\'''
lt_cv_sys_global_symbol_to_cdecl=${lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^T .* \(.*\)$/extern int \1();/p'\'' -e '\''s/^[ABCDGIRSTW]* .* \(.*\)$/extern char \1;/p'\'''}
lt_cv_sys_max_cmd_len=${lt_cv_sys_max_cmd_len=1572864}
Fake an environment...
./configure, ./configure, ./configure...
Enabling Portable
Build Systems
E. Rogan Creswick
creswick@galois.com
$ ./configure && make && sudo make install
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking how to create a pax tar archive... gnutar
checking for style of include used by make... GNU
checking for g++... g++
checking for C++ compiler default output file name... a.out
checking whether the C++ compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking dependency style of g++... none
checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking dependency style of gcc... none
./configure: line 3838: TAR: command not found
./configure: line 3838: AMTAR: command not found
Defined: am__tar = tar --format=posix -chf - "$$tardir"
Defined: am__untar = tar -xf -
Defined: AMTAR = ${SHELL} /home/creswick/src/rose-0.9.5a-10647/config/missing --run tar
checking build system type... i686-pc-linux-gnu
Building ROSE for cpu = i686
Building ROSE for OS vendor = pc
Building ROSE for OS = linux-gnu
Try to identify the OS vendor...
Wait, you said....
...until the implicit dependencies
are resolved
Translation tricks
and black magic
Explicitly Specify
Build Requirements
ClearCase
No one can predict system.
Semi-autonomously identify environment details:
Build Environment
Target Environment
Compiler(s)
Intermediate programs
Build tools
Include paths
Library paths
Share
Environments
Current Status
Run-time tool locations
Shared library locations
Shared libraries
Static libraries
Run-time constants
$ env
ORBIT_SOCKETDIR=/tmp/orbit-creswick
SSH_AGENT_PID=2367
GPG_AGENT_INFO=/tmp/gpg-pwypWW/S.gpg-agent:2368:1
TERM=xterm
SHELL=/bin/bash
XDG_SESSION_COOKIE=e2439fc5d1208f5012a135434b4371ec-1285172177.563426-2087141492
WINDOW_MANAGER=xmonad
WINDOWID=39850601
GDK_NATIVE_WINDOWS=true
GNOME_KEYRING_CONTROL=/tmp/keyring-PJ2hFz
MOZILLA_FIVE_HOME=/home/creswick/myapps/mozilla-1.7.12
USER=creswick
LD_LIBRARY_PATH=:/home/creswick/myapps/mozilla-1.7.12
SSH_AUTH_SOCK=/tmp/ssh-XwDsKs2319/agent.2319
USERNAME=creswick
ENVDIR=/home/creswick/.bash_env.d
PROVER9HOME=/opt/python-misc/prover9/bin
DESKTOP_SESSION=default
PATH=/home/creswick/.cabal/bin:/home/creswick/myapps/ghc/bin:/home/creswick/.cabal/bin:/home/creswick/bin:/sbin:/bin:/usr/bin:/usr/sbin:/opt/bin:/opt/e17/bin:/home/creswick/bin:/usr/local/bin:/usr/bin:/bin:/usr/games:/home/creswick/.cabal/bin:/home/creswick/myapps/eclipse:/home/creswick/myapps/android-sdk/tools
GDM_XSERVER_LOCATION=local
PWD=/home/creswick/src/trac-wiki-chrome-extension
MALTPARSERHOME=/opt/python-misc/malt-1.2/
JAVA_HOME=/usr/lib/jvm/java-6-sun
LANG=en_US.UTF-8
GNOME_KEYRING_PID=2244
GWT_EXTERNAL_BROWSER=firefox
GDM_LANG=en_US.UTF-8
GDMSESSION=default
HISTCONTROL=ignoreboth
SHLVL=1
HOME=/home/creswick
WACOM_ERASER=Wacom Serial Tablet PC Pen Tablet/Digitizer eraser
LOGNAME=creswick
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-YHhZ4aB95B,guid=2ab840121c7abe3730d9f55900000032
XDG_DATA_DIRS=/usr/local/share/:/usr/share/:/usr/share/gdm/
LESSOPEN=| /usr/bin/lesspipe %s
WINDOWPATH=7
DISPLAY=:0.0
WACOM_STYLUS=Wacom Serial Tablet PC Pen Tablet/Digitizer
LESSCLOSE=/usr/bin/lesspipe %s %s
COLORTERM=gnome-terminal
XAUTHORITY=/home/creswick/.Xauthority
OLDPWD=/home/creswick/src
_=/usr/bin/env
Serialize environments
Ease debugging
Simplify cross-compilation
Solution Space
your
What is an "environment"?
Difficulties
Manipulate Tool Caches
CMake cache files
SCons Compilation Environments
Autotools cache / configure.in files
SET(CMAKE_CXX_COMPILER "/usr/bin/c++")
SET(CMAKE_CXX_COMPILER_ARG1 "")
SET(CMAKE_CXX_COMPILER_ID "GNU")
SET(CMAKE_CXX_PLATFORM_ID "Linux")
SET(CMAKE_AR "/usr/bin/ar")
SET(CMAKE_RANLIB "/usr/bin/ranlib")
SET(CMAKE_LINKER "/usr/bin/ld")
SET(CMAKE_COMPILER_IS_GNUCXX 1)
SET(CMAKE_CXX_COMPILER_LOADED 1)
SET(CMAKE_COMPILER_IS_MINGW )
SET(CMAKE_COMPILER_IS_CYGWIN )
IF(CMAKE_COMPILER_IS_CYGWIN)
SET(CYGWIN 1)
SET(UNIX 1)
ENDIF(CMAKE_COMPILER_IS_CYGWIN)
SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
IF(CMAKE_COMPILER_IS_MINGW)
SET(MINGW 1)
ENDIF(CMAKE_COMPILER_IS_MINGW)
SET(CMAKE_CXX_COMPILER_ID_RUN 1)
SET(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;H;o;O;obj;OBJ;def;DEF;rc;RC)
SET(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm)
SET(CMAKE_CXX_LINKER_PREFERENCE 30)
SET(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
# Save compiler ABI information.
SET(CMAKE_CXX_SIZEOF_DATA_PTR "4")
SET(CMAKE_CXX_COMPILER_ABI "ELF")
IF(CMAKE_CXX_SIZEOF_DATA_PTR)
SET(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
ENDIF(CMAKE_CXX_SIZEOF_DATA_PTR)
IF(CMAKE_CXX_COMPILER_ABI)
SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
ENDIF(CMAKE_CXX_COMPILER_ABI)
SET(CMAKE_CXX_HAS_ISYSROOT "")
SET(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;c")
SET(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/i486-linux-gnu/4.4.4;/usr/lib;/lib")
Intercept System Calls
LD_PRELOAD
ptrace(2)
Constrained Environments
chroot
scratchbox
$ ./configure && make && sudo make install
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking how to create a pax tar archive... gnutar
checking for style of include used by make... GNU
checking for g++... g++
checking for C++ compiler default output file name... a.out
checking whether the C++ compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking dependency style of g++... none
checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking dependency style of gcc... none
./configure: line 3838: TAR: command not found
./configure: line 3838: AMTAR: command not found
Defined: am__tar = tar --format=posix -chf - "$$tardir"
Defined: am__untar = tar -xf -
Defined: AMTAR = ${SHELL} /home/creswick/src/rose-0.9.5a-10647/config/missing --run tar
checking build system type... i686-pc-linux-gnu
Building ROSE for cpu = i686
Building ROSE for OS vendor = pc
Building ROSE for OS = linux-gnu
Try to identify the OS vendor...
What is a build system?
Build System
Environments aren't specified
Compatibility is KEY
Limited support for cross-compilation
Execution checks are skipped
Dependency identification happens on host
Limited support for host/target depenencies
Intermediate tools are difficult to use
As an example of using a cache file, to cross compile for the "MingW32" Win32 runtine environment on a Linux system, create a file 'win32.cache' with the following contents:
glib_cv_long_long_format=I64
glib_cv_stack_grows=no
Then execute the following commands:
PATH=/path/to/mingw32-compiler/bin:$PATH
chmod a-w win32.cache # prevent configure from changing it
./configure --cache-file=win32.cache --host=mingw32
Autotools
CMake
SCons
Make
Cabal
Rake
Maven
JAM
Host
Target
Configure
Build
import Development.Configure
configure :: Environment -> Either CfgError Configuration
configure env = do
headerExists env "hello.h"
uniqueLibraryExists env "hello"
strace
dtrace
Source analysis
etc...
Many environmental properties can impact a build.
Very few properties are explicitly specified.
Ok, they are explicit in the configure script, but not easily observable.
Build Environment
Target Environment
Run-time tool locations
Shared library locations
Shared libraries
Static libraries
Run-time constants
Compiler(s)
Intermediate programs
Build tools
Include paths
Library paths