Re: More on Actions, routes and builders in general

Lars Ivar Igesund <[email protected]> Sat, 19 Jun 2004 21:10:16 +0100
Newsgroups gmane.comp.tools.aap.devel
Message-ID <[email protected]>
Bram Moolenaar wrote:

> They were not attached, thus I have to do a bit of guessing.

Sorry.

> You say all three primary actions defer the work to a "compile_dmd"
> action.  Then isn't it so that each action can accept the work and defer
> it to "compile_dmd"?  Where does this go wrong?

Ah, my description of the problem were somewhat wrong. There is only 1 
compile_dmd action that can output all three types of object. But there
are three primary compile actions in d.aap. These support only one 
output type each (because they add the correct buildaction attribute). 
But when the outtypes are checked, it looks at the compile_dmd, and thus 
it isn't able to distinguish between the primary actions.

Lars Ivar Igesund
dmd.py (text/plain, 6.6 KB)
# Part of the A-A-P recipe executive 

# Copyright (c) 2002-2004 Lars Ivar Igesund and 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 module sets up variables and actions for using the DMD compiler tools.
#

from RecPython import *
import Global
from Action import action_add
from Dictlist import str2dictlist
from RecPos import RecPos


def exists():
    """
    Return TRUE when the DMD toolchain can be found.
    """
    if program_path("dmd"):
        if os.name == "nt":
            if program_path("link"):
                return program_path("lib")
            else:
                return 0
        else:
            return program_path("gcc")
    else:
        return 0


def define_actions():
    """
    Define the actions that DMD can accomplish.
    """
    rd = Global.globals
    # Compile one sourcefile at the time
    define_action("compile_dmd", 0, """
        opt =
        @if _no.OPTIMIZE and int(_no.OPTIMIZE) > 0:
          opt = -O
        dbg =
        DEBUG ?=
        @if _no.DEBUG == 'yes':
          dbg = -g
        :sys $DMD $?DFLAGS $?DVERSION $opt $dbg $?DDEBUG $?DIMPORT -of$target 
                -c $source
        """,
        outtypes = ["object", "libobject", "dllobject"],
        intypes = ["d"])

    # Build a program from object files
    define_action("build_dmd", 0, """
        :sys $DMD -L$*?DLINKFLAGS _L+$*?LIBS -of$target $source
        """,
        outtypes = ["default"],
        intypes = ["object"])

    # Build a static lib from object files
    define_action("buildlib_dmd", 0, """
        @if os.name == "nt":
            :progsearch LIB lib
            :sys $LIB $?DLINKFLAGS -p512 -c $target $source
        @else:
            :sys $DMD $?DLINKFLAGS -of$target $source
        """,
        outtypes = ["default"],
        intypes = ["libobject"])

    # Build a dll from object files  
    define_action("builddll_dmd", 0, """
        @exec "import tools.dmd"
        @if os.name == "nt":
            @if _no.DIMPLIB and _no.DIMPLIB == "yes":
                DLINKFLAGS += /implib
        @if not tools.dmd.find_dll_main_object(source):
            @f = file("aap_dllmain.d", 'w')
            @f.write(tools.dmd.dll_main_source())
            @f.close()
            :do compile {target = aap_dllmain.obj} aap_dllmain.d
            source += aap_dllmain.obj
        :sys $DMD -L$*?DLINKFLAGS -L+$*?LIBS -of$target $source
        :del {f} {q} aap_dllmain.*
        """,
        outtypes = ["default"],
        intypes = ["dllobject"])

    # Build a program directly from source
    define_action("buildonestep_dmd", 0, """ 
        opt =
        @if _no.OPTIMIZE and int(_no.OPTIMIZE) > 0:
            opt = -O
        dbg =
        DEBUG ?=
        @if _no.DEBUG == 'yes':
            dbg = -g
        :sys $DMD $?DFLAGS $?DVERSION $opt $dbg $?DDEBUG $?DIMPORT
                -L$*?DLINKFLAGS -L+$*?LIBS -of$target $source
        :del {f} {q} *.obj
        """,
        outtypes = ["default"],
        intypes = ["d"])

    # Build a static lib directly from source
    define_action("buildlibonestep_dmd", 0, """
        opt =
        @if _no.OPTIMIZE and int(_no.OPTIMIZE) > 0:
            opt = -O
        dbg =
        DEBUG ?=
        @if _no.DEBUG == 'yes':
            dbg = -g
        :sys $DMD -c $?DFLAGS $?DVERSION $opt $dbg $?DDEBUG $?DIMPORT
                -op $source
        :progsearch LIB lib
        BDIR = 
        objects = `src2obj(source)`
        :sys $LIB $?DLINKFLAGS -p512 -c $target $objects
        :del {f} {q} *.obj
        """,
        outtypes = ["default"],
        intypes = ["d"])

    # Build a dll directly from source
    define_action("builddllonestep_dmd", 0, """
        opt =
        @if _no.OPTIMIZE and int(_no.OPTIMIZE) > 0:
            opt = -O
        dbg =
        DEBUG ?=
        @if _no.DEBUG == 'yes':
            dbg = -g
        @if os.name == "nt":
            @if _no.DIMPLIB and _no.DIMPLIB == "yes":
                DLINKFLAGS += -L/implib
        @exec "import tools.dmd"
        @if not tools.dmd.find_dll_main_source(source):
            @f = file("aap_dllmain.d", 'w')
            @f.write(tools.dmd.dll_main_source())
            @f.close()
            source += aap_dllmain.d
        :sys $DMD $?DFLAGS $?DVERSION $opt $dbg $?DDEBUG $?DIMPORT
                -L$*?DLINKFLAGS -L+$*?LIBS -of$target $source
        :del {f} {q} aap_dllmain.d
        :del {q} *.obj
        """,
        outtypes = ["default"],
        intypes = ["d"])
        
    if not rd["_top"].get("DMD"):
        rd["_top"]["DMD"] = "dmd"


def use_actions(scope):
    """
    Setup variables so that the default actions use the DMD actions.
    """
    scope["D_COMPILE_ACTION"] = "compile_dmd"
    scope["D_BUILD_ACTION"] = "build_dmd"
    scope["D_BUILDLIB_ACTION"] = "buildlib_dmd"
    scope["D_BUILDDLL_ACTION"] = "builddll_dmd"
    scope["D_BUILDONESTEP_ACTION"] = "buildonestep_dmd"
    scope["D_BUILDDLLONESTEP_ACTION"] = "builddllonestep_dmd"
    scope["D_BUILDLIBONESTEP_ACTION"] = "buildlibonestep_dmd"


def find_phobos():
    dmd_path = program_path("dmd")
    import re
    phobos_path = re.sub('bin', 'lib', dmd_path)
    return re.sub('dmd.EXE', '', phobos_path)


def find_dll_main_source(sourcestr):
    import re
    m = re.compile(r"BOOL\s+DllMain\s*\(\s*HINSTANCE")
    for si in var2list(sourcestr):
        f = file2string(si)
        if m.search(f):
            return 1

    return None 

def find_dll_main_object(sourcestr):
    for si in var2list(sourcestr):
        f = file2string(si)
        from string import find
        if find(f, "[email protected]") > -1:
            return 1

    return None 

def dll_main_source():
    source = """
        import std.c.windows.windows;

        HINSTANCE g_hInst;

        extern (C)
        {
            void gc_init();
            void gc_term();
            void _minit();
            void _moduleCtor();
        }

        export:
        extern (Windows)
        BOOL DllMain(HINSTANCE hInstance,
                     ULONG ulReason,
                     LPVOID pvReserved)
        {   
            switch (ulReason)
            {
                case DLL_PROCESS_ATTACH:
                gc_init();
                _minit();
                _moduleCtor();
                break;

                case DLL_PROCESS_DETACH:
                gc_term();
                break;

                case DLL_THREAD_ATTACH:
                case DLL_THREAD_DETACH:
                return false;
            }
            g_hInst = hInstance;
            return true;
        }
        """
    return source

# vim: set sw=4 et sts=4 tw=79 fo+=l:
d.aap (text/plain, 7.3 KB)
# Part of the A-A-P recipe executive: Module for the D Programming Language.

# Copyright (c) 2002 - 2004 Lars Ivar Igesund and 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
#

# Last Change: 2004 Jun 16

# See also dmd.py in the tools directory for compiler specific info.

# (1) Filetype recognition
# This is included in Filetype.py

# (2) Default values
DCOMP = dmd
SUPPORTED_TOOLS = "dmd"

# (3) Object file suffixes
# dll and lib objects are equal to normal objects.
_top.D_LIBOBJSUF = $OBJSUF
_top.D_DLLOBJSUF = $OBJSUF

# (4) Search for tools
# Actions are installed for every toolchain that exists.
# The first one found sets $D_COMPILE_ACTION and friends.
:toolsearch dmd

# (4.5) Check for dependency checker. If not present, download it.
:assertpkg ddepcheck {optional}

# If not downloaded, build it from local copy.
:progsearch _top.DDEPCHECK ddepcheck

@if not _top.DDEPCHECK:
    bindir = "`Global.aap_bindir`"
    toolsdir = "`Global.aap_toolsdir`"
    :mkdir {force} $bindir
    :print ddepcheck not found, building from: $toolsdir/ddepcheck.d
    :progsearch dc dmd
    @if not os.access(Global.aap_bindir, os.W_OK):
        :print -----------
        :print The "ddepcheck" program cannot be found
        :print Aap can build and install it for you, but you don't have write
        :print access to the Aap binaries directory.
        @r = " " 
        @while not r == '1' and not r == '2': 
            :print 1. Become root/administrator and install in the Aap binaries
                        directory.
            :print 2. Specify another location to install ddepcheck.
            :print q. Quit
            @r = raw_input("Select an option: ")
            @if r == '1':
                :asroot $dc -O -of$bindir`os.sep`ddepcheck$EXESUF 
                            $toolsdir`os.sep`ddepcheck.d
            @elif r == '2':
                :print The path entered must be writable from your user.
                @bindir = raw_input("Enter install path for ddepcheck ")
                :sys $dc -O -of$bindir`os.sep`ddepcheck$EXESUF 
                        $toolsdir`os.sep`ddepcheck.d
                :print NOTE: It might be necessary to add $bindir to your PATH 
                        before the next execution of Aap.
                _top.DDEPCHECK = $bindir`os.sep`ddepcheck$EXESUF
            @elif r == 'q':
                :quit
    @else:
        :sys $dc -O -of$bindir`os.sep`ddepcheck$EXESUF 
                $toolsdir`os.sep`ddepcheck.d
    :del {q} ddepcheck$OBJSUF ddepcheck.map 
    @if not _top.DDEPCHECK:
        :progsearch _top.DDEPCHECK ddepcheck
    @if not _top.DDEPCHECK:
        :error Building ddepcheck failed or the program cannot be found.

# (5) Actions, Rules and Routes

# :do depend
#

:action depend {recursive} 
        {buildcheck = $DCOMP $?DFLAGS $?DVERSION $?DDEBUG $?DIMPORT } d
    :sys $_top.DDEPCHECK -m $?DIMPORT $source > $target

# :do compile

:python

    define_action("compile", 1, """
        @if not _no.get("target"):
            target = `src2obj(fname)`
        :attr {buildaction = d_builddll} $target
        @if DEFER_ACTION_NAME:
            :do $DEFER_ACTION_NAME {target = $target} $source
        @else:
            :print "No default compile action for D. Install one of the"
            :print "supported tool chains(" + $SUPPORTED_TOOLS + ")"
        """,
        outtypes = ["dllobject"],
        intypes = ["d"],
        defer_var_names = ["D_COMPILE_ACTION"])

    define_action("compile", 1, """
        @if not _no.get("target"):
            target = `src2obj(fname)`
        :attr {buildaction = d_buildlib} $target
        @if DEFER_ACTION_NAME:
            :do $DEFER_ACTION_NAME {target = $target} $source
        @else:
            :print "No default compile action for D. Install one of the"
            :print "supported tool chains(" + $SUPPORTED_TOOLS + ")"
        """,
        outtypes = ["libobject"],
        intypes = ["d"],
        defer_var_names = ["D_COMPILE_ACTION"])

    define_action("compile", 1, """
        @if not _no.get("target"):
            target = `src2obj(fname)`
        :attr {buildaction = d_build} $target
        @if DEFER_ACTION_NAME:
            :do $DEFER_ACTION_NAME {target = $target} $source
        @else:
            :print "No default compile action for D. Install one of the"
            :print "supported tool chains(" + $SUPPORTED_TOOLS + ")"
        """,
        outtypes = ["object", "default"],
        intypes = ["d"],
        defer_var_names = ["D_COMPILE_ACTION"])

:rule {global}{default} %$OBJSUF : {buildcheck = $DCOMP $?DFLAGS $?DVERSION $?DDEBUG $?DIMPORT } %.d
    :do compile {target = $target} $source

# :do build for object files resulting from "d" source files.

:python
    define_action("d_build", 0, """
        @if DEFER_ACTION_NAME:
            :do $DEFER_ACTION_NAME {target = $target} $source
        @else:
            :print "No default build action for D. Install one of the" 
            :print "supported tool chains (" + $SUPPORTED_TOOLS + ")"
        """,
        outtypes = ["default"],
        intypes = ["object"],
        defer_var_names = ["D_BUILD_ACTION"])

    define_action("d_builddll", 0, """
        @if DEFER_ACTION_NAME:
            :do $DEFER_ACTION_NAME {target = $target} $source
        @else:
            :print "No default builddll action for D. Install one of the" 
            :print "supported tool chains (" + $SUPPORTED_TOOLS + ")"
        """,
        outtypes = ["default"],
        intypes = ["object"],
        defer_var_names = ["D_BUILDDLL_ACTION"])

    define_action("d_buildlib", 0, """
        @if DEFER_ACTION_NAME:
            :do $DEFER_ACTION_NAME {target = $target} $source
        @else:
            :print "No default buildlib action for D. Install one of the" 
            :print "supported tool chains (" + $SUPPORTED_TOOLS + ")"
        """,
        outtypes = ["default"],
        intypes = ["object"],
        defer_var_names = ["D_BUILDLIB_ACTION"])

# :do buildonestep to build targets directly from "d" source

:python
    define_action("buildonestep", 1, """
        @if DEFER_ACTION_NAME:
            :do $DEFER_ACTION_NAME {target = $target} $source
        @else:
            :print "No default buildonestep action for D. Install on of the"
            :print "supported tool chains (" + $SUPPORTED_TOOLS +")"
        """,
        outtypes = ["default"],
        intypes = ["d"],
        defer_var_names = ["D_BUILDONESTEP_ACTION"])

    define_action("buildlibonestep", 1, """
        @if DEFER_ACTION_NAME:
            :do $DEFER_ACTION_NAME {target = $target} $source
        @else:
            :print "No default buildlibonestep action for D. Install on of the"
            :print "supported tool chains (" + $SUPPORTED_TOOLS +")"
        """,
        outtypes = ["default"],
        intypes = ["d"],
        defer_var_names = ["D_BUILDLIBONESTEP_ACTION"])

    define_action("builddllonestep", 1, """
        @if DEFER_ACTION_NAME:
            :do $DEFER_ACTION_NAME {target = $target} $source
        @else:
            :print "No default builddllonestep action for D. Install on of the"
            :print "supported tool chains (" + $SUPPORTED_TOOLS +")"
        """,
        outtypes = ["default"],
        intypes = ["d"],
        defer_var_names = ["D_BUILDDLLONESTEP_ACTION"])

# vim: set sw=4 sts=4 tw=79 :