<?xml version="1.0" ?>

<!-- Author: Francesco Montorsi <frm@users.sourceforge.net>         -->
<!-- Source: http://wiki.wxwidgets.org/wiki.pl?Bakefile_Utils       -->
<!-- Date: 1/5/2005                                                 -->
<!-- Last revision: 15/1/2006                                       -->

<!--                                                                -->
<!--             GENERIC BAKEFILE WITH UTILITY TAGS                 -->
<!--                                                                -->
<!--    This bakefile provides various new tags for easier          -->
<!--    target creation (in particular these tags give you          -->
<!--    the tools required to build INSTALL/UNINSTALL/RPM           -->
<!--    targets.                                                    -->

<makefile>
    <requires version="0.2.0"/>

    <!--                                                                -->
    <!--                            NEW TAGS                            -->
    <!--                                                                -->

    <!-- Removes the $(value) list of files. Each file should be        -->
    <!-- separed from the previous with a single space.                 -->
    <define-tag name="rmfiles" rules="action">
        <clean-files>$(value)</clean-files>
    </define-tag>

    <!-- Recursively removes the $(value) file from the current folder. -->
    <!-- Usage sample:                                                  -->
    <!--          <action id="deepclean">                               -->
    <!--              <rmfile-rec>$(BUILDDIR)/*.o</rmfile>              -->
    <!--          </action>                                             -->
    <define-tag name="rmfile-rec" rules="action">
        <if cond="TOOLSET=='unix'"><command>$(RM) -r $(value)</command></if>
        <if cond="TOOLSET=='win32'"><command>-del /S $(value)</command></if>
    </define-tag>

    <!-- Removes the $(value) folder.                                   -->
    <!-- Usage sample:                                                  -->
    <!--          <action id="uninstall-scripts">                       -->
    <!--              <rmdir>$(DATADIR)/myscripts</rmdir>               -->
    <!--          </action>                                             -->
    <define-tag name="rmdir" rules="action">
        <if cond="TARGETING_WIN32=='0'">
            <command>rm -rf $(value)</command>
        </if>
        <if cond="TARGETING_WIN32=='1' and FORMAT!='mingw'">
            <command>-if exist $(value) rmdir /S /Q $(value)</command>
        </if>
        <if cond="TARGETING_WIN32=='1' and FORMAT=='mingw'">
            <!-- The MINGW format needs the "then" keyword... -->
            <command>-if exist $(value) then rmdir /S /Q $(value)</command>
        </if>
    </define-tag>

    <!-- Removes the intermediate folders whose names are composed as   -->
    <!-- "$(value)[u][d]" where 'u' is used when Unicode is enabled and -->
    <!-- 'd' is used for debug builds.                                  -->
    <!-- Usage sample:                                                  -->
    <!--          <set var="BUILDDIR">$(FORMAT)$(WXLIBPOSTFIX)</set>    -->
    <!--          <action id="deepclean">                               -->
    <!--              <rmintdir>$(FORMAT)</rmintdir>                    -->
    <!--          </action>                                             -->
    <define-tag name="rmintdir" rules="action">
        <rmdir>$(value)</rmdir>
        <rmdir>$(value)</rmdir>
        <rmdir>$(value)u</rmdir>
        <rmdir>$(value)ud</rmdir>
    </define-tag>

    <!-- Removes *all* intermediate files from the given folder         -->
    <!-- recursively.                                                   -->
    <!-- NOTE: BE CAREFUL SINCE THIS TAG WILL REMOVE A LOT OF FILES     -->
    <!--       JUST LOOKING AT THEIR EXTENSION !!                       -->
    <!-- Usage sample:                                                  -->
    <!--          <action id="deepclean">                               -->
    <!--              <rmintfiles>build</rmintfiles>                    -->
    <!--          </action>                                             -->
    <define-tag name="rmintfiles" rules="action">

        <!-- remove results -->
        <rmfile-rec>$(value)$(DIRSEP)*.a</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.lib</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.pdb</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.dll</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.exp</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.so*</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.exe</rmfile-rec>

        <!-- various intermediate files for the bakefile-supported compilers -->
        <rmfile-rec>$(value)$(DIRSEP)*.obj</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.o</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.log</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.manifest*</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.log</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP).bakefile_gen.state</rmfile-rec>

        <!-- MSVC -->
        <rmfile-rec>$(value)$(DIRSEP)*.pch</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.ncb</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.plg</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.ncb</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.aps</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.suo</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.user</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.res</rmfile-rec>

        <!-- Borland -->
        <rmfile-rec>$(value)$(DIRSEP)*.il?</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.tds</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.idb</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)*.map</rmfile-rec>

        <!-- autoconf -->
        <rmdir>$(value)$(DIRSEP)autom4te.cache</rmdir>
        <rmdir>$(value)$(DIRSEP).deps</rmdir>
        <rmfile-rec>$(value)$(DIRSEP)config.status</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)config.log</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)Makefile</rmfile-rec>
        <rmfile-rec>$(value)$(DIRSEP)bk-deps</rmfile-rec>
    </define-tag>

    <!-- Includes the $(value)/include path in include search paths and the $(value)/lib
         path in the library search paths when the boolean option whose name is given in
         the BOOLOPT attribute of this tag, has value == '1'.
         If the attribute BOOLOPT is missing, then the $(value)/include and $(value)/lib
         paths are always added.

         E.g.
                  <stdlib-paths>$(MYLIBPATH)</stdlibs-path>

                  <option name="USE_MYLIB"><values>0,1</values></option>
                  <stdlib-paths boolopt="USE_MYLIB">$(MYLIBPATH)</stdlibs-path>
    -->
    <define-tag name="stdlib-paths" rules="lib,exe,dll,module">
        <include>$(substituteFromDict(
                        mk.evalExpr('$(' + getTagAttrib('boolopt', '1') + ')'),
                            {'1':value+'/include', '0':''}))</include>
        <lib-path>$(substituteFromDict(
                        mk.evalExpr('$(' + getTagAttrib('boolopt', '1') + ')'),
                            {'1':value+'/lib', '0':''}))</lib-path>
    </define-tag>





    <!--                                                                -->
    <!--                           NEW RULES                            -->
    <!--                                                                -->

    <!-- Forces the presence of the $(id) option into the final makefile; -->
    <!-- this rule (which is really used more like a tag) is a tweaky way -->
    <!-- to tell Bakefile not to remove from the final makefile an option -->
    <!-- which has been qualified as 'useless'.                           -->
    <!-- See bakefile docs for the VARS_DONT_ELIMINATE global switch.     -->
    <!-- Usage sample:                                                    -->
    <!--    <force-opt-presence id="MY_USELESS_OPTION"/>                  -->
    <define-rule name="force-opt-presence" extends="phony">
        <template id="dummytemplate_for_$(id)"/>
        <!-- <set var="VARS_DONT_ELIMINATE" append="1">$(id)</set> -->
    </define-rule>

    <!-- Changes the current directory to the folder given to the CD    -->
    <!-- tag and then executes the command given to the RUN tag.        -->
    <!-- Usage sample:                                                  -->
    <!--          <cd-and-run id="tarball">                             -->
    <!--              <cd>..</cd>                                       -->
    <!--              <run>tar -cvzf tarball.tar.gz myproj/*</run>      -->
    <!--          </cd-and-run>                                         -->
    <define-rule name="cd-and-run" extends="action">
        <template>
            <set var="__cmddir"/>
            <set var="__cmdstr"/>
        </template>
        <define-tag name="cd">
            <set var="__cmddir">$(nativePaths(value))</set>
        </define-tag>
        <define-tag name="run">
            <set var="__cmdstr">$(value)</set>
            <if cond="FORMAT=='msvc' or FORMAT=='mingw' or FORMAT=='gnu' or FORMAT=='autoconf'">
                <command>( cd $(__cmddir) &amp;&amp; $(__cmdstr) )</command>
            </if>
            <if cond="FORMAT=='borland' or FORMAT=='watcom'">
                <command>-cd $(__cmddir)</command>
                <command>-$(__cmdstr)</command>
            </if>
        </define-tag>
    </define-rule>

    <!-- Helps you to set the MAKEARGS variable manually.               -->
    <!-- he MAKEARGS variable is usually automatically generated by     -->
    <!-- Bakefile using all the options available; the problem is that  -->
    <!-- maybe you have to translate from an option name to another...  -->
    <!-- For example, I often found that I need to translate the:       -->
    <!--   WX_UNICODE=1/0,                                              -->
    <!--   WX_SHARED=1/0,                                               -->
    <!--   WX_DEBUG=1/0,                                                -->
    <!-- options of the build system of my wxWidgets-based projects, to -->
    <!-- some other option name, when building the non wx-based part of -->
    <!-- those projects, like:                                          -->
    <!--   UNICODE=1/0,                                                 -->
    <!--   SHARED=1/0,                                                  -->
    <!--   BUILD=debug/release                                          -->
    <!-- To do such kind of substitution in the arguments passed to the -->
    <!-- other MAKEs by the <subproject> targets, you need to write the -->
    <!-- MAKEARGS variable by hand... and this tag helps you a lot !    -->
    <!-- Usage sample:                                                  -->
    <!--      <set var="BUILD_EQUIVALENT">                              -->
    <!--           <if cond="WX_DEBUG=='1'">debug</if>                  -->
    <!--           <if cond="WX_DEBUG=='0'">release</if>                -->
    <!--      </set>                                                    -->
    <!--      <smart-subproject id="nonwxbased">                        -->
    <!--           <set-makeargs>                                       -->
    <!--                    UNICODE=$(WX_UNICODE)                       -->
    <!--                    SHARED=$(WX_SHARED)                         -->
    <!--                    BUILD=$(BUILD_EQUIVALENT)                   -->
    <!--           </set-makeargs>                                      -->
    <!--      </smart-subproject>                                       -->
    <define-rule name="smart-subproject" extends="subproject">
        <template>
        </template>
        <define-tag name="set-makeargs">
            <set var="_MAKEARGS">
                CC="$(CC)" CXX="$(CXX)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)"
                CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(value)
            </set>

            <!-- now adjust the real MAKEARGS -->
            <if cond="FORMAT=='borland'">
                <set var="MAKEARGS" make_var="1">$(''.join(['-D%s ' % (x) for x in _MAKEARGS.split()]))</set>
            </if>
            <if cond="FORMAT!='borland'">
                <set var="MAKEARGS" make_var="1">$(_MAKEARGS)</set>
            </if>
        </define-tag>
    </define-rule>

    <!-- exactly like <copy-files> but this target just does not contain the "if not exist"
            check and thus always performs the copy of the files (maybe overwriting old
            versions of them). -->
    <define-rule name="force-copy-files" extends="action">
        <template>
            <is-phony/>
            <set var="__srcdir"/>

            <!--
                DigitalMars' smake has problems with long command lines, so we
                have to work around it. More details here:
                http://sourceforge.net/mailarchive/message.php?msg_id=9595825
                -->
            <if cond="TOOLSET=='win32' and FORMAT=='dmars_smake'">
                <set var="__copy_depends" eval="0">
                    $(''.join(['$(__srcdir)%s ' % (x) for x in __files.split()]))
                </set>
                <set var="__deps" append="1">$(__copy_depends)</set>
                <set var="__copy_script_name">$(FORMAT)_copy_$(id).bat</set>
            </if>

            <set var="__copy_cmd" eval="0">

                <if cond="TOOLSET=='unix'">
                    @mkdir -p $(__dstdir)
                    @for f in $(__files); do \
                            cp -pRf $(__srcdir)$(DOLLAR)$(DOLLAR)f $(__dstdir) ; \
                    done
                </if>

                <if cond="TOOLSET in ['win32','os2'] and FORMAT!='mingw' and FORMAT!='dmars_smake'">
                    if not exist $(__dstdir) mkdir $(__dstdir)
                    for %f in ($(__files)) do copy $(__srcdir)%f $(__dstdir)
                </if>
                <if cond="TOOLSET=='win32' and FORMAT=='dmars_smake'">
                    if not exist $(__dstdir) mkdir $(__dstdir)
                    echo copy $(__srcdir)%%1 $(__dstdir)\%%1 &gt; $(__copy_script_name)
                    !$(__copy_script_name) $**
                    del $(__copy_script_name)
                </if>
                <if cond="TOOLSET=='win32' and FORMAT=='mingw'">
                    if not exist $(__dstdir) mkdir $(__dstdir)
                    for %%f in ($(__files)) do copy $(__srcdir)%%f $(__dstdir)
                </if>

            </set>
            <command>$(__copy_cmd)</command>
        </template>
        <define-tag name="dstdir">
            <set var="__dstdir">$(nativePaths(value))</set>
        </define-tag>
        <define-tag name="srcdir">
            <set var="__srcdir">$(nativePaths(value))$(DIRSEP)</set>
        </define-tag>
        <define-tag name="files">
            <set var="__files">$(' '.join(value.split()))</set>
        </define-tag>
    </define-rule>

</makefile>

