# Part of the A-A-P recipe executive: Default variables, actions, etc. # Copyright (c) 2002-2003 stichting NLnet Labs # Permission to copy and use this file is specified in the file COPYING. # If this file is missing you can find it here: http://www.a-a-p.org/COPYING # # This recipe is read to set all kinds of defaults. # # Note: Don't read this as an example for a recipe, it contains all the # complicated stuff that you (hopefully) will not need to use in a normal # recipe. # # System directories to look for modules and tools. # This may be changed when installing Aap. @if os.path.isdir("/usr/local/share/aap"): AAPSYSDIR = /usr/local/share/aap @else: AAPSYSDIR = CFLAGS ?= CXXFLAGS ?= $CFLAGS LDFLAGS ?= CPPFLAGS ?= OPTIMIZE ?= 2 DEFAULTCHECK = md5 # Check if $CC exists. If not, try looking for "gcc". CC ?= cc @if not program_path(CC) and program_path('gcc'): CC = gcc # If $CXX was not set yet, use g++ if it exists, otherwise use $CC. CXX ?= @if not program_path(CXX) and program_path('g++'): CXX = g++ CXX ?= $CC # OBJSUF actually depends on the compiler, the tool should correct it. @if os.name in [ 'nt', 'dos', 'os2' ]: OBJSUF = .obj LIBOBJSUF = .obj DLLOBJSUF = .sob EXESUF = .exe LIBPRE = LIBSUF = .lib DLLPRE = DLLSUF = .dll LNKSUF = @else: OBJSUF = .o LIBOBJSUF = .o DLLOBJSUF = .sho EXESUF = LIBPRE = lib LIBSUF = .a DLLPRE = lib DLLSUF = .so LNKSUF = # XXX this should be in a separate Irix recipe... @if string.find(sys.platform, "irix") >= 0 and program_path("CC"): # static and shared objects are the same. DLLOBJSUF = .o CXXFLAGS = $CXXFLAGS -LANG:std # used in add_build_one() LTOBJSUF = .lo # Number of files handled at a time for upload/download commands. GROUPCOUNT = 20 # Check if $CC ($CXX) is GCC, remember this in $HASGCC ($HASGCCXX) # Use a dependency to avoid checking it more than once. # Use an action to share the code between checking $CC and $CXX. # TODO: handle the situation that $CC is not gcc but "gcc" does exist. HASGCC = HASGCCXX = :action gcccheck default @if _no.get("check_cpp"): val = $_recipe.HASGCCXX @else: val = $_recipe.HASGCC @if val == '': val = no # default result MESSAGE = error # Don't echo the commands here @try: testfile = `tempfname()`.c outfile = `tempfname()` :eval "#ifdef __GNUC__\nyes;\n#endif\n" >! $testfile @if _no.get("check_cpp"): :sys $CXX -E $testfile > $outfile @else: :sys $CC -E $testfile > $outfile :cat $outfile | :assign tt @if string.find(tt, "yes") >= 0: val = yes @except (StandardError, UserError), e: :log Warning: could not test C compiler for being GCC: `str(e)` :del {force}{quiet} $testfile $outfile @if _no.get("check_cpp"): _recipe.HASGCCXX = $val @else: _recipe.HASGCC = $val # Depending on the platform, check for available toolchains. # Actions are installed for every toolchain that exists. # The first one found sets $C_COMPILE_ACTION and friends: it is used as # default. Uses ideas from SCons. @if osname() == 'mswin': :toolsearch msvc mingw gcc icc bcc @elif osname() == 'os2': :toolsearch icc gcc msvc # Get the time, so that it remains the same while executing the recipe. :python import time GMTIME = time.gmtime(time.time()) DATESTR = time.strftime("%Y %b %d", GMTIME) TIMESTR = time.strftime("%X", GMTIME) # Default depedency checkers # GCC can detect included files better than we can, it works recursively. # If GCC is not available, use an internal function. :action depend {recursive} {buildcheck = $($)CC $($)CXX $($)CFLAGS $($)CXXFLAGS $($)CPPFLAGS $($)?DEFINE $($)?INCLUDE} c,cpp @if filetype == 'c': @if _no.HASGCC == '': :do gcccheck dummy usegcc = $HASGCC cc = $CC flags = $CFLAGS @else: @if _no.HASGCCXX == '': :do gcccheck {check_cpp} dummy usegcc = $HASGCCXX cc = $CXX flags = $CXXFLAGS @if usegcc != "yes": @ aap_depend_c(globals(), source, target, flags = flags) @else: # Buggy version of gcc on Mac OS X doesn't accept "-E -MM" for ".c" # files but "-E" is required for ".h" files... ss = $-source @if fname_fold(suffix(ss)) in ['h', 'H', 'hh', 'hpp', 'hxx']: EEE = -E @else: EEE = :sysdepend {filepat = .*: ([^:]*): No such file or directory} $cc $CPPFLAGS $?DEFINE $?INCLUDE $flags $?CDEPFLAGS $EEE -MM $-source > $-target # # Default A-A-P commands for action-filetype pairs. # Related default rules are mixed in. # # :do edit @if os.name == "posix": EDITOR = `os.environ.get('VISUAL', os.environ.get('EDITOR', 'vi'))` @else: EDITOR = `os.environ.get('VISUAL', os.environ.get('EDITOR', 'notepad'))` :action edit default @if globals().has_key('line') and os.path.basename(EDITOR)[:2] == "vi": :sys {i} $EDITOR +$line $source @elif globals().has_key('byte') and os.path.basename(EDITOR)[:3] == "vim": :sys {i} $EDITOR -c "go $byte" $source @else: :sys {i} $EDITOR $source PAINTER = `os.environ.get('PAINTER')` :action edit gif,jpeg,png @if not _no.PAINTER: :progsearch _recipe.PAINTER gimp kpaint :syspath '$PAINTER' $source # :do view # Use the $BROWSER environment variable, a proposed standard; colon separated # alternatives. If not set, search for one of the known browsers. BROWSER = `os.environ.get('BROWSER')` :action view html,xml,php @if not _no.BROWSER: :progsearch _recipe.BROWSER netscape mozilla konquerer grail iexplore mosaic lynx w3m :syspath '$BROWSER' $source @if os.name == "posix": PAGER = `os.environ.get('PAGER', 'more')` @else: PAGER = `os.environ.get('PAGER', '')` :action view default @if PAGER: # assume $PAGER can handle multiple files @if (globals().has_key('line') @ and (os.path.basename(PAGER)[:4] == "more" @ or os.path.basename(PAGER)[:4] == "less")): :sys {i} $PAGER +$line $source @else: :sys {i} $PAGER $source @else: # MS-Windows more always reads from stdin @ for fname in var2list(source): :sys {i} more <$fname :action view gif,jpeg,png :sys xv $source # :do compile :python define_action("compile", 1, """ @if not _no.get("target"): target = `src2obj(fname)` @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'compile': :do $DEFER_ACTION_NAME {target = $target} $source @else: :buildcheck $OPTIMIZE $?DEBUG :sys $CC $CPPFLAGS $?DEFINE $?INCLUDE `cflags_normal()` $CFLAGS -c -o $target $source """, outtypes = ["object", "libobject", "default"], intypes = ["c"], defer_var_names = ["C_COMPILE_ACTION", "COMPILE_ACTION"]) :rule {default} %$OBJSUF : {buildcheck = $($)CC $($)CPPFLAGS $($)?DEFINE $($)?INCLUDE $($)OPTIMIZE $($)?DEBUG $($)CFLAGS} %.c :do compile {target = $target} $source :python define_action("compile", 1, """ @if not _no.get("target"): target = `src2obj(fname)` :attr {buildaction = cxx_build} $target # Need to build with $CXX @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'compile': :do $DEFER_ACTION_NAME {target = $target} $source @else: :buildcheck $OPTIMIZE $?DEBUG :sys $CXX $CPPFLAGS $?DEFINE $?INCLUDE `cflags_normal()` $CXXFLAGS -c -o $target $source """, outtypes = ["object", "libobject", "default"], intypes = ["cpp"], defer_var_names = ["CXX_COMPILE_ACTION", "COMPILE_ACTION"]) :rule {default} %$OBJSUF : {buildcheck = $($)CXX $($)CPPFLAGS $($)?DEFINE $($)?INCLUDE $($)CXXFLAGS} %.cpp >always :attr {buildaction = cxx_build} $target # Need to build with $CXX >build :do compile {target = $target} $source # TODO: this only works for gcc DLLCFLAGS ?= -fPIC :python define_action("compile", 1, """ @if not _no.get("target"): target = `src2obj(fname, sufname = "DLLOBJSUF")` @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'compile': :do $DEFER_ACTION_NAME {target = $target} $source @else: :buildcheck $OPTIMIZE $?DEBUG :sys $CC $CPPFLAGS $?DEFINE $?INCLUDE `cflags_normal()` $CFLAGS $DLLCFLAGS -c -o $target $source """, outtypes = ["dllobject"], intypes = ["c"], defer_var_names = ["C_COMPILE_ACTION", "COMPILE_ACTION"]) @if _no.OBJSUF != _no.DLLOBJSUF: :rule {default} %$DLLOBJSUF : {buildcheck = $($)CC $($)CPPFLAGS $($)?DEFINE $($)?INCLUDE $($)OPTIMIZE $($)?DEBUG $($)CFLAGS $($)DLLCFLAGS} %.c :do compile {target = $target} $source # TODO: this only works for gcc DLLCXXFLAGS ?= -fPIC :python define_action("compile", 1, """ @if not _no.get("target"): target = `src2obj(fname, sufname = "DLLOBJSUF")` :attr {builddllaction = cxx_builddll} $target # Need to build with $CXX @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'compile': :do $DEFER_ACTION_NAME {target = $target} $source @else: :buildcheck $OPTIMIZE $?DEBUG :sys $CXX $CPPFLAGS $?DEFINE $?INCLUDE `cflags_normal()` $CXXFLAGS $DLLCXXFLAGS -c -o $target $source """, outtypes = ["dllobject"], intypes = ["cpp"], defer_var_names = ["CXX_COMPILE_ACTION", "COMPILE_ACTION"]) @if _no.OBJSUF != _no.DLLOBJSUF: :rule {default} %$DLLOBJSUF : {buildcheck = $($)CXX $($)CPPFLAGS $($)?DEFINE $($)?INCLUDE $($)CXXFLAGS $($)DLLCXXFLAGS} %.cpp >always :attr {builddllaction = cxx_builddll} $target # Need to build with $CXX >build :do compile {target = $target} $source # :do preproc :action preproc default c,cpp @if not _no.get("target"): target = `src2obj(fname, sufname = None)` + ".i" :sys $CC $CPPFLAGS $?DEFINE $?INCLUDE -E $source > $target # :do lex, lexpp LEX ?= :python define_action("lex", 1, """ @if not _no.LEX: # Prefer flex above lex, it should be able to do everything lex can. :progsearch _recipe.LEX flex lex @if not _no.LEX: :error Cannot find a lex program @if _no.get("target"): :sys $LEX $?LEXFLAGS -o$target $source @else: :sys $LEX $?LEXFLAGS $source """, outtypes = ["c"], intypes = ["lex"], outfilename = "$(source).c") :rule {default}{sourceexists} %.c : {buildcheck = $($)LEX $($)?LEXFLAGS} %.l :do lex {target = $target} $source LEXPP ?= :python define_action("lexpp", 1, """ @if not _no.LEXPP: # Prefer flex above lex, it should be able to do everything lex can. :progsearch _recipe.LEXPP flex++ lex++ flex lex @if not _no.LEXPP: :error Cannot find a lex program @if _no.get("target"): :sys $LEXPP $?LEXPPFLAGS -o$target $source @else: :sys $LEXPP $?LEXPPFLAGS $source """, outtypes = ["cpp"], intypes = ["lexpp"], outfilename = "$(source).cpp") :rule {default}{sourceexists} %.cpp : {buildcheck = $($)LEXPP $($)?LEXPPFLAGS} %.ll :do lexpp {target = $target} $source # :do yacc YACC ?= :python define_action("yacc", 1, """ @if not _no.YACC: # Find bison first, it's supposed to do more than yacc. :progsearch _recipe.YACC yacc bison @if not _no.YACC: :error Cannot find a yacc program @if _no.get("target"): :sys $YACC $?YACCFLAGS -o $target $source @else: :sys $YACC $?YACCFLAGS $source """, outtypes = ["c"], intypes = ["yacc"], outfilename = "$(source).c") :rule {default}{sourceexists} %.c : {buildcheck = $($)YACC $($)?YACCFLAGS} %.y :do yacc {target = $target} $source YACCPP ?= :python define_action("yaccpp", 1, """ @if not _no.YACCPP: # Find bison first, it's supposed to do more than yacc. :progsearch _recipe.YACCPP bison yacc @if not _no.YACCPP: :error Cannot find a yacc program @if _no.get("target"): :sys $YACCPP $?YACCPPFLAGS -o $target $source @else: :sys $YACCPP $?YACCPPFLAGS $source """, outtypes = ["cpp"], intypes = ["yaccpp"], outfilename = "$(source).cpp") :rule {default}{sourceexists} %.cpp : {buildcheck = $($)YACCPP $($)?YACCPPFLAGS} %.yy :do yaccpp {target = $target} $source # :do build # The generic build action. May invoke a language-specific build action. :python act = define_action("build", 1, """ @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'build': # Building is handled by a specific action. :do $DEFER_ACTION_NAME {target = $target} $source @else: ld = $?LD @if not ld: # No linker specified by the user, use $CC. ld = $CC :buildcheck $OPTIMIZE $?DEBUG :sys $ld $LDFLAGS `cflags_normal()` -o $target $source $?LIBS """, outtypes = ["default"], intypes = ["object", "libobject", "ltobject", "dll", "default"]) def default_build_defer_name(source = ""): if _no.get("BUILD_ACTION"): return var2string(_no.BUILD_ACTION) name = get_var_attr(source, "buildaction") if name: return name if _no.get("C_BUILD_ACTION"): return var2string(_no.C_BUILD_ACTION) if _no.get("LTLIBS"): return "ltbuild" return None act.defer_action_name = default_build_defer_name # The C++ build action. :python act = define_action("cxx_build", 0, """ @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'cxx_build': :do $DEFER_ACTION_NAME {target = $target} $source @else: ld = $?LD @if not ld: # No linker specified by the user, use $CXX. ld = $CXX :buildcheck $OPTIMIZE $?DEBUG :sys $ld $LDFLAGS `cflags_normal()` -o $target $source $?LIBS """, outtypes = ["default"], intypes = ["object", "libobject", "ltobject", "dll", "default"]) def default_cxx_build_defer_name(source = ""): if _no.get("CXX_BUILD_ACTION"): return var2string(_no.CXX_BUILD_ACTION) if _no.get("LTLIBS"): return "ltbuild_cxx" return None act.defer_action_name = default_cxx_build_defer_name # :do buildlib @if os.name in [ 'nt', 'dos', 'os2' ]: AR ?= lib ARFLAGS ?= /nologo :python define_action("buildlib", 1, """ @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'buildlib': :do $DEFER_ACTION_NAME {target = $target} $source @else: :sys $AR $ARFLAGS /OUT:$target $source """, outtypes = ["default"], intypes = ["libobject", "object", "default"], defer_var_names = ["{buildlibaction}", "BUILDLIB_ACTION"]) @else: AR ?= ar ARFLAGS ?= r findranlibprog {virtual}: :progsearch _recipe.RANLIB ranlib :python define_action("buildlib", 1, """ @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'buildlib': :do $DEFER_ACTION_NAME {target = $target} $source @else: :sys $AR $ARFLAGS $target $source @if not _no.has_key("RANLIB"): :update findranlibprog @if _no.get("RANLIB"): :sys $RANLIB $?RANLIBFLAGS $target """, outtypes = ["default"], intypes = ["libobject", "object", "default"], defer_var_names = ["{buildlibaction}", "BUILDLIB_ACTION"]) # :do builddll @if os.name in [ 'nt', 'dos', 'os2' ]: # XXX not tested at all! SHLINK ?= link SHLINKFLAGS ?= /nologo /dll :python define_action("builddll", 1, """ @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'builddll': :do $DEFER_ACTION_NAME {target = $target} $source @else: :sys $SHLINK $SHLINKFLAGS /OUT:$target $source """, outtypes = ["default"], intypes = ["dllobject", "default"], defer_var_names = ["{builddllaction}", "BUILDDLL_ACTION"]) :python # TODO: Is this correct? act = define_action("cxx_builddll", 1, """ :do builddll {target = $target} $source """, outtypes = ["default"], intypes = ["dllobject", "default"]) def default_cxx_builddll_defer_name(source = ""): return "builddll" act.defer_action_name = default_cxx_builddll_defer_name @else: SHLINK ?= ld SHLINKFLAGS ?= -shared :python define_action("builddll", 1, """ @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'builddll': :do $DEFER_ACTION_NAME {target = $target} $source @else: :sys $SHLINK $LDFLAGS $SHLINKFLAGS -o $target $source """, outtypes = ["default"], intypes = ["dllobject", "default"], defer_var_names = ["{builddllaction}", "BUILDDLL_ACTION"]) CXXSHLINK ?= $CXX CXXSHLINKFLAGS ?= -shared :python define_action("cxx_builddll", 1, """ @if DEFER_ACTION_NAME and DEFER_ACTION_NAME != 'cxx_builddll': :do $DEFER_ACTION_NAME {target = $target} $source @else: :sys $CXXSHLINK $LDFLAGS $CXXSHLINKFLAGS -o $target $source """, outtypes = ["default"], intypes = ["dllobject", "default"], defer_var_names = ["{builddllaction}", "CXX_BUILDDLL_ACTION", "BUILDDLL_ACTION"]) # :do email MAILER = `os.environ.get('MAILER', 'mail')` :action email default @if globals().get("edit"): :do edit $fname :sys $MAILER -s $subject $to <$fname # :do reference REFERENCER = :action reference default @if not _no.REFERENCER: :progsearch _recipe.REFERENCER aref ctags @if os.path.basename(var2string(_no.REFERENCER)) == "aref": :sys $REFERENCER -u $source @else: :sys $REFERENCER $source # :do strip findstripprog {virtual}: :progsearch _recipe.STRIP strip :action strip default @if not _no.get("STRIP"): :update findstripprog :sys $STRIP $?STRIPFLAGS $source # :do extract TAR = tar BUNZIP2 = bunzip2 UNZIP = unzip :action extract tar @if _no.TAR == 'tar': :assertpkg tar :sys $TAR xf $source :action extract targz @if _no.TAR == 'tar': :assertpkg tar :sys $TAR xzf $source :action extract tarbz2 @if _no.BUNZIP2 == 'bunzip2': :assertpkg bunzip2 tar :sys $BUNZIP2 -c $source | $TAR xf - :action extract zip @if _no.UNZIP == 'unzip': :assertpkg unzip :sys $UNZIP $source # # INSTALL and UNINSTALL actions # PREFIX ?= /usr/local DESTDIR ?= # :do installexec/uninstallexec EXECMODE ?= 0755 EXECDIR ?= bin/ :action installexec default @if not _no.has_key("STRIP"): :update findstripprog dest = $EXECDIR @install_files(dest, source, var2string(_no.EXECMODE), strip = 1) :action uninstallexec default dest = $EXECDIR @uninstall_files(dest, source) # :do installsbin/uninstallsbin SBINDIR ?= sbin/ :action installsbin default dest = $SBINDIR @install_files(dest, source, var2string(_no.EXECMODE)) :action uninstallsbin default dest = $SBINDIR @uninstall_files(dest, source) # :do installlib/uninstalllib LIBDIR ?= lib/ LIBMODE ?= 0644 :action installlib default dest = $LIBDIR @install_files(dest, source, var2string(_no.LIBMODE)) :action uninstalllib default dest = $LIBDIR @uninstall_files(dest, source) # :do installdll/uninstalldll DLLDIR ?= lib/ DLLMODE ?= 0755 :action installdll default dest = $DLLDIR @install_files(dest, source, var2string(_no.DLLMODE)) :action uninstalldll default dest = $DLLDIR @uninstall_files(dest, source) # :do installconf/uninstallconf CONFDIR ?= etc/ CONFMODE ?= 0644 :action installconf default dest = $CONFDIR @install_files(dest, source, var2string(_no.CONFMODE)) :action uninstallconf default dest = $CONFDIR @uninstall_files(dest, source) # :do installdata/uninstalldata DATADIR ?= share/ DATAMODE ?= 0644 :action installdata default @if _no.get("PKGNAME") == None: :error For installing data you must set $($)PKGNAME dest = $DATADIR$PKGNAME @install_files(dest, source, var2string(_no.DATAMODE)) :action uninstalldata default @if _no.get("PKGNAME") == None: :error For installing data you must set $($)PKGNAME dest = $DATADIR$PKGNAME @uninstall_files(dest, source) # :do installman/uninstallman MANDIR ?= man/ MANMODE ?= 0644 :action installman default dest = $MANDIR @install_files(dest, source, var2string(_no.MANMODE), mandir = 1) :action uninstallman default dest = $MANDIR @uninstall_files(dest, source, mandir = 1) # :do installinfo/uninstallinfo INFODIR ?= info/ INFOMODE ?= 0644 :action installinfo default dest = $INFODIR @install_files(dest, source, var2string(_no.INFOMODE)) :action uninstallinfo default dest = $INFODIR @uninstall_files(dest, source) # :do installinclude/uninstallinclude INCLUDEDIR ?= include/ INCLUDEMODE ?= 0644 :action installinclude default dest = $INCLUDEDIR @install_files(dest, source, var2string(_no.INCLUDEMODE)) :action uninstallinclude default dest = $INCLUDEDIR @uninstall_files(dest, source) # vim: set sw=4 sts=4 tw=79 :