Boost logo

Boost-Build :

From: Alexey Pakhunov (alexeypa_at_[hidden])
Date: 2005-11-17 14:56:39


Reece Dunn wrote:
> I think it is when you have another IDL file dependant on the first (see
> rabbit3.zip) - that is essentially the only thing I didn't try with your
> rabbit example.

Aha! I found it. midl.exe does not always create 'xxx_proxy.c' and
'xxx_dlldata.c' files. This behavior depends on contents of an .idl
file. So now I just create these files if midl.exe doesn't.

BTW, the generator for .idl files is registered by the following command:

generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H
C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;

Is it possible to make the output files 'C(%_proxy)' and 'C(%_dlldata)'
optional? So that if these files are missing bjam will not try to
recreate them.

Best regards/Venlig hilsen,
   Alexey Pakhunov.


# Copyright (c) 2005 Alexey Pakhunov.
#
# Use, modification and distribution is subject to the Boost Software
# License Version 1.0. (See accompanying file LICENSE_1_0.txt or
# http://www.boost.org/LICENSE_1_0.txt)

# Microsoft Interface Definition Language (MIDL) related routines

import common ;
import generators ;
import feature : feature get-values ;
import os ;
import scanner ;
import toolset : flags ;
import type ;

rule init ( )
{
}

type.register IDL : idl ;

# A type library (.tlb) is generated by MIDL compiler and can be included
# to resources of an application (.rc). In order to be found by a resource
# compiler its target type should be derived from 'H' - otherwise
# the property '<implicit-dependency>' will be ignored.
type.register MSTYPELIB : tlb : H ;

# Register scanner for MIDL files
class midl-scanner : scanner
{
    import path property-set regex scanner type virtual-target ;
    
    rule __init__ ( includes * )
    {
        scanner.__init__ ;
    
        self.includes = $(includes) ;

        # List of quoted strings
        self.re-strings = "[ \t]*\"([^\"]*)\"([ \t]*,[ \t]*\"([^\"]*)\")*[ \t]*" ;

        # 'import' and 'importlib' directives
        self.re-import = "import"$(self.re-strings)"[ \t]*;" ;
        self.re-importlib = "importlib[ \t]*[(]"$(self.re-strings)"[)][ \t]*;" ;

        # C preprocessor 'include' directive
        self.re-include-angle = "#[ \t]*include[ \t]*<(.*)>" ;
        self.re-include-quoted = "#[ \t]*include[ \t]*\"(.*)\"" ;
    }

    rule pattern ( )
    {
        # Match '#include', 'import' and 'importlib' directives
        return "((#[ \t]*include|import(lib)?).+(<(.*)>|\"(.*)\").+)" ;
    }

    rule process ( target : matches * : binding )
    {
        local included-angle = [ regex.transform $(matches) : $(self.re-include-angle) : 1 ] ;
        local included-quoted = [ regex.transform $(matches) : $(self.re-include-quoted) : 1 ] ;
        local imported = [ regex.transform $(matches) : $(self.re-import) : 1 3 ] ;
        local imported_tlbs = [ regex.transform $(matches) : $(self.re-importlib) : 1 3 ] ;

        # CONSIDER: the new scoping rule seem to defeat "on target" variables.
        local g = [ on $(target) return $(HDRGRIST) ] ;
        local b = [ NORMALIZE_PATH $(binding:D) ] ;

        # Attach binding of including file to included targets.
        # When target is directly created from virtual target
        # this extra information is unnecessary. But in other
        # cases, it allows to distinguish between two headers of the
        # same name included from different places.
        local g2 = $(g)"#"$(b) ;

        included-angle = $(included-angle:G=$(g)) ;
        included-quoted = $(included-quoted:G=$(g2)) ;
        imported = $(imported:G=$(g2)) ;
        imported_tlbs = $(imported_tlbs:G=$(g2)) ;

        local all = $(included-angle) $(included-quoted) $(imported) ;

        INCLUDES $(target) : $(all) ;
        DEPENDS $(target) : $(imported_tlbs) ;
        NOCARE $(all) $(imported_tlbs) ;
        SEARCH on $(included-angle) = $(self.includes:G=) ;
        SEARCH on $(included-quoted) = $(b) $(self.includes:G=) ;
        SEARCH on $(imported) = $(b) $(self.includes:G=) ;
        SEARCH on $(imported_tlbs) = $(b) $(self.includes:G=) ;
        
        scanner.propagate
            [ type.get-scanner CPP : [ property-set.create $(self.includes) ] ] :
            $(included-angle) $(included-quoted) : $(target) ;

        scanner.propagate $(__name__) : $(imported) : $(target) ;
    }
}

scanner.register midl-scanner : include ;
type.set-scanner IDL : midl-scanner ;

# Command line options
feature midl-stubless-proxy : yes no : propagated ;
feature midl-robust : yes no : propagated ;

flags midl.compile.idl MIDLFLAGS <midl-stubless-proxy>yes : /Oicf ;
flags midl.compile.idl MIDLFLAGS <midl-stubless-proxy>no : /Oic ;
flags midl.compile.idl MIDLFLAGS <midl-robust>yes : /robust ;
flags midl.compile.idl MIDLFLAGS <midl-robust>no : /no_robust ;

# Architecture-specific options
architecture-x86 = <architecture> <architecture>x86 ;
address-model-32 = <address-model> <address-model>32 ;
address-model-64 = <address-model> <address-model>64 ;

flags midl.compile.idl MIDLFLAGS $(architecture-x86)/$(address-model-32) : /win32 ;
flags midl.compile.idl MIDLFLAGS $(architecture-x86)/<address-model>64 : /x64 ;
flags midl.compile.idl MIDLFLAGS <architecture>ia64/$(address-model-64) : /ia64 ;

flags midl.compile.idl DEFINES <define> ;
flags midl.compile.idl UNDEFS <undef> ;
flags midl.compile.idl INCLUDES <include> ;

generators.register-c-compiler midl.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) ;

# Returns a command that may be used for 'touching' files.
# It is not a real 'touch' command on NT because it adds an empty line at
# the end of file but it works with source files
rule file-touch-command ( )
{
    if [ os.name ] in NT
    {
        return "echo. >> " ;
    }
    else
    {
        return "touch " ;
    }
}

TOUCH_FILE = [ file-touch-command ] ;

actions compile.idl
{
    midl /nologo @"@($(<[1]:W).rsp:E=$(nl)"$(>:W)" $(nl)-D$(DEFINES) $(nl)"-I$(INCLUDES)" $(nl)-U$(UNDEFS) $(nl)$(MIDLFLAGS) $(nl)/tlb "$(<[1]:W)" $(nl)/h "$(<[2]:W)" $(nl)/iid "$(<[3]:W)" $(nl)/proxy "$(<[4]:W)" $(nl)/dlldata "$(<[5]:W)")"
    $(TOUCH_FILE) "$(<[4]:W)"
    $(TOUCH_FILE) "$(<[5]:W)"
}

Index: msvc.jam
===================================================================
RCS file: /cvsroot/boost/boost/tools/build/v2/tools/msvc.jam,v
retrieving revision 1.64
diff -u -r1.64 msvc.jam
--- msvc.jam 14 Nov 2005 15:15:06 -0000 1.64
+++ msvc.jam 17 Nov 2005 19:47:17 -0000
@@ -18,6 +18,7 @@
 import common ;
 import "class" : new ;
 import rc ;
+import midl ;
 
 if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
 {
@@ -36,6 +37,9 @@
 # List of all registered configurations
 .versions = [ new configurations ] ;
 
+# Inherit MIDL flags
+toolset.inherit-flags msvc : midl ;
+
 RM = [ common.rm-command ] ;
 nl = "
 " ;
@@ -321,6 +325,9 @@
         assembler = [ get-values <assembler> : $(options) ] ;
         assembler ?= ml ;
 
+ idl-compiler = [ get-values <idl-compiler> : $(options) ] ;
+ idl-compiler ?= midl ;
+
 
         for local i in 1 2 3
         {
@@ -342,6 +349,7 @@
                 flags msvc.compile .ASM $(cond) : $(command[$(i)])$(assembler) ;
                 flags msvc.link .LD $(cond) : $(command[$(i)])$(linker) ;
                 flags msvc.archive .LD $(cond) : $(command[$(i)])$(linker) ;
+ flags msvc.compile .IDL $(cond) : $(command[$(i)])$(idl-compiler) ;
             }
         }
 
@@ -487,6 +495,9 @@
 generators.override msvc.compile.rc : rc.resource-compile ;
 generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ;
 
+generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;
+generators.override msvc.compile.idl : midl.compile.idl ;
+
 #
 # Declare flags and action for compilation
 #
@@ -553,6 +564,15 @@
     $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES)" -fo "$(<:W)" "$(>:W)"
 }
 
+TOUCH_FILE = [ midl.file-touch-command ] ;
+
+actions compile.idl
+{
+ $(.IDL) /nologo @"@($(<[1]:W).rsp:E=$(nl)"$(>:W)" $(nl)-D$(DEFINES) $(nl)"-I$(INCLUDES)" $(nl)-U$(UNDEFS) $(nl)$(MIDLFLAGS) $(nl)/tlb "$(<[1]:W)" $(nl)/h "$(<[2]:W)" $(nl)/iid "$(<[3]:W)" $(nl)/proxy "$(<[4]:W)" $(nl)/dlldata "$(<[5]:W)")"
+ $(TOUCH_FILE) "$(<[4]:W)"
+ $(TOUCH_FILE) "$(<[5]:W)"
+}
+
 # Declare flags and action for the assembler
 
 flags msvc.compile.asm USER_ASMFLAGS <asmflags> : ;


Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk