1# Copyright (c) 2005 Alexey Pakhunov. 2# 3# Use, modification and distribution is subject to the Boost Software 4# License Version 1.0. (See accompanying file LICENSE_1_0.txt or 5# http://www.boost.org/LICENSE_1_0.txt) 6 7# Microsoft Interface Definition Language (MIDL) related routines 8 9import common ; 10import generators ; 11import feature : feature get-values ; 12import os ; 13import scanner ; 14import toolset : flags ; 15import type ; 16 17rule init ( ) 18{ 19} 20 21type.register IDL : idl ; 22 23# A type library (.tlb) is generated by MIDL compiler and can be included 24# to resources of an application (.rc). In order to be found by a resource 25# compiler its target type should be derived from 'H' - otherwise 26# the property '<implicit-dependency>' will be ignored. 27type.register MSTYPELIB : tlb : H ; 28 29 30# Register scanner for MIDL files 31class midl-scanner : scanner 32{ 33 import path property-set regex scanner type virtual-target ; 34 35 rule __init__ ( includes * ) 36 { 37 scanner.__init__ ; 38 39 self.includes = $(includes) ; 40 41 # List of quoted strings 42 self.re-strings = "[ \t]*\"([^\"]*)\"([ \t]*,[ \t]*\"([^\"]*)\")*[ \t]*" ; 43 44 # 'import' and 'importlib' directives 45 self.re-import = "import"$(self.re-strings)"[ \t]*;" ; 46 self.re-importlib = "importlib[ \t]*[(]"$(self.re-strings)"[)][ \t]*;" ; 47 48 # C preprocessor 'include' directive 49 self.re-include-angle = "#[ \t]*include[ \t]*<(.*)>" ; 50 self.re-include-quoted = "#[ \t]*include[ \t]*\"(.*)\"" ; 51 } 52 53 rule pattern ( ) 54 { 55 # Match '#include', 'import' and 'importlib' directives 56 return "((#[ \t]*include|import(lib)?).+(<(.*)>|\"(.*)\").+)" ; 57 } 58 59 rule process ( target : matches * : binding ) 60 { 61 local included-angle = [ regex.transform $(matches) : $(self.re-include-angle) : 1 ] ; 62 local included-quoted = [ regex.transform $(matches) : $(self.re-include-quoted) : 1 ] ; 63 local imported = [ regex.transform $(matches) : $(self.re-import) : 1 3 ] ; 64 local imported_tlbs = [ regex.transform $(matches) : $(self.re-importlib) : 1 3 ] ; 65 66 # CONSIDER: the new scoping rule seem to defeat "on target" variables. 67 local g = [ on $(target) return $(HDRGRIST) ] ; 68 local b = [ NORMALIZE_PATH $(binding:D) ] ; 69 70 # Attach binding of including file to included targets. 71 # When target is directly created from virtual target 72 # this extra information is unnecessary. But in other 73 # cases, it allows to distinguish between two headers of the 74 # same name included from different places. 75 local g2 = $(g)"#"$(b) ; 76 77 included-angle = $(included-angle:G=$(g)) ; 78 included-quoted = $(included-quoted:G=$(g2)) ; 79 imported = $(imported:G=$(g2)) ; 80 imported_tlbs = $(imported_tlbs:G=$(g2)) ; 81 82 local all = $(included-angle) $(included-quoted) $(imported) ; 83 84 INCLUDES $(target) : $(all) ; 85 DEPENDS $(target) : $(imported_tlbs) ; 86 NOCARE $(all) $(imported_tlbs) ; 87 SEARCH on $(included-angle) = $(self.includes:G=) ; 88 SEARCH on $(included-quoted) = $(b) $(self.includes:G=) ; 89 SEARCH on $(imported) = $(b) $(self.includes:G=) ; 90 SEARCH on $(imported_tlbs) = $(b) $(self.includes:G=) ; 91 92 scanner.propagate 93 [ type.get-scanner CPP : [ property-set.create $(self.includes) ] ] : 94 $(included-angle) $(included-quoted) : $(target) ; 95 96 scanner.propagate $(__name__) : $(imported) : $(target) ; 97 } 98} 99 100scanner.register midl-scanner : include ; 101type.set-scanner IDL : midl-scanner ; 102 103 104# Command line options 105feature midl-stubless-proxy : yes no : propagated ; 106feature midl-robust : yes no : propagated ; 107 108flags midl.compile.idl MIDLFLAGS <midl-stubless-proxy>yes : /Oicf ; 109flags midl.compile.idl MIDLFLAGS <midl-stubless-proxy>no : /Oic ; 110flags midl.compile.idl MIDLFLAGS <midl-robust>yes : /robust ; 111flags midl.compile.idl MIDLFLAGS <midl-robust>no : /no_robust ; 112 113# Architecture-specific options 114architecture-x86 = <architecture> <architecture>x86 ; 115address-model-32 = <address-model> <address-model>32 ; 116address-model-64 = <address-model> <address-model>64 ; 117 118flags midl.compile.idl MIDLFLAGS $(architecture-x86)/$(address-model-32) : /win32 ; 119flags midl.compile.idl MIDLFLAGS $(architecture-x86)/<address-model>64 : /x64 ; 120flags midl.compile.idl MIDLFLAGS <architecture>ia64/$(address-model-64) : /ia64 ; 121 122 123flags midl.compile.idl DEFINES <define> ; 124flags midl.compile.idl UNDEFS <undef> ; 125flags midl.compile.idl INCLUDES <include> ; 126 127 128generators.register-c-compiler midl.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) ; 129 130 131# MIDL does not always generate '%_proxy.c' and '%_dlldata.c'. This behavior 132# depends on contents of the source IDL file. Calling TOUCH_FILE below ensures 133# that both files will be created so bjam will not try to recreate them 134# constantly. 135TOUCH_FILE = [ common.file-touch-command ] ; 136 137actions compile.idl 138{ 139 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)")" 140 $(TOUCH_FILE) "$(<[4]:W)" 141 $(TOUCH_FILE) "$(<[5]:W)" 142} 143