From: "Aleksandras G." <alex@soften.ktu.lt>
To: wxWorkshop-users@groups.yahoo.com
Subject: Makefile auto-generation proposal


First, this is wicked..

yes, i remember Brian telling us about his plans
on integration of build-tools into wxWorkshop.

Now i started working again on workshop's
code-generation engine, i thought this build-tools
support would be wonderful.. and i could immediately use it.
Thus now, i cannot really wait to have it :/ especially as 
i just came up with a simple way to get basic prototype
working.

Before i do this nasty little thing (i think i will), 
thought i should at least confess about it.

my proposal:

Generally there would be:

1. Script-based templates for actual makefiles
2. Automatic generation (maintenance) of those makefiles
3. Adding multiple configurations
4. Selecting active configuration
5. Building it
6. Reviewing errors and warnings
7. Executing the binary

the key to all this is handling of scripted-templates, 
the syntax and parsing workshop already has - all it's
code gen. and widget-look and widget-set config_* files
are based on the their syntax. The syntax allows following:

(this is syntax spec. here is bit off-topic, but it may
help you understand the sample makefile-templates
below)

* simple name-value pairs (primitive elements):

  foo="value"

* the same with multi-line values:

  foo1 = [[ text line1
line2
line3]]

* multi-level composite elements with names:

  struct_1_name = {
    foo1 = "x"
    foo2 = [[y]]
    nested_struct = {
	foo11 = "z"
	foo12 = "something"
    }

* arrays of unnamed elements 

   array1 = { "dogs" "cats" { x="1" y="2" } "sparrows" }

   where elements can be either primitive or composite 

--

apart composition, there is scrip-interpretation code,
which supports 

* variable substitutions, assignments

    %(@assign_var(PROGRAM_NAME="first")

    This is my %(PROGRAM_NAME) application!

* if-branches
    
     <h1>Welcome to

	     %(IF%(ENV)="UNIX") unix %(END_IF)
	     $(IF%(ENV)!="UNIX") win32  %(END_IF)

         environment
     </h1>

* invocation of sub-scripts 

     %(@script[STD_HEADER_COMMENTS]

     # Set WXDIR for your system
     WXDIR = $(WXWIN)

     !include $(WXDIR)\src\makevc.env

* various special-processing tags (handled by compiled code within workshop

	tag = "MEMBER_INITS"
	content = "$(@member_list[init_source])"

	(example from config_srctempl.txt)

-------

Now to the makefile generation. Having this script-handling code
already in and working, i though it's a shame to not reuse it for
mekefile-generation system.

The main template file will be:

config_build.txt

which will contain "standard" templates for makefiles
e.g. various makefile.vc for libs or standalone apps,
then analogous .b32 .wat, etc.

Then the project's would have configurations which consist of:

* name of configuration
* a reference to makefile-template (it's name)
* set of name-value arguments passed to the makefile
  in it's generation process as well as to cmd-line
  of invoked build-tool

It's possible to have different configurations
referencing the same template.

Then there would be something analogous to 
VC's "Project | Set active configuration"

Template file config_build.txt:

it will have two types of top-level elements

* "script" - defines a snippet helper script (eg. for generation of object-file-list)

* template - defines single template for a makefile

multiple such elements can be contained within config_build.txt

Sample template element:

template = {

	name = "Makefile for Visual C++"

	args = { { "FINAL" { "0", "1" } }
                 { "USE_MY_XML" { "YES", "NO" } }
	       }

	output_file = "makefile.vc"

	build_cmdline = "nmake -f %(output_file) FINAL = %(FINAL)"
	exec_cmdline  = ".\%(IF%(FINAL)="1")Release\%(END_IF)%(PROGRAM).exe"

	content = "$(@script[VISUAL_C_mkf_script])"

	error_filter   = { __FILE__, "(", __LINE__, ") : ", __MESSAGE__, "\n" }
	warning_filter = { __FILE__, "(", __LINE__, ") : ", __MESSAGE__, "\n" }

}

i think it's self-descriptive enough (knowing the syntax described above).

Sample script would be is invoked from "content" variables of template = {..}

	script = {

	name = "VISUAL_C_mkf_script"

	content = [[
#
# File:		Auto-generated %(OUTPUT_FILE) from template %(TEMPLATE).
# Author:	
# Created:	%(DATE)
# Updated:	
# Copyright:
#
# Makefile : Builds %(PROGRAM) application
# Use FINAL=1 argument to nmake to build final version with no debug info.

# Set WXDIR for your system
WXDIR = $(WXWIN)

!include $(WXDIR)\src\makevc.env

PROGRAM = %(PROGRAM)

OBJECTS = %(@file_list["*.cpp",obj_file])


EXTRAINC = -I./../include

!if "$(FINAL)" == "1"
EXTRALIBS = wsexts.lib wxxml.lib
!else
EXTRALIBS = wsextsd.lib wxxmld.lib
!endif

all: $(D) $(OBJECTS)

!include $(WXDIR)/src/makeprog.vc

$D:
    mkdir .\$D
]]
}

and a tiny sub-script which is invoked from

%(@file_list["*.cpp",obj_file])

special-processing tag to generate list of .obj

script = {

	name = "obj_file"
	content = [[	$D/%(FILE).obj \
]]
}

The @file_list processing tag collects all file-names
from active project's file-list matching mask-argument.
Then invokes given obj_files script to generate output 
for a single file, multiple such outputs are concatenated 
and substituted in place of encountered @file_list tag.
This way it would be possible to generate file-sets of any
extension in any desired format. The makefile is automatically
regenerated each time any files are added/removed from the project.
Errors/warnings are outputted into Output-pane by applying
extraction-filters defined in the template.

Enough talking, i can't wait to 
code this sweet thing, now...


Aleks.