| # 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) ; |
| |
| |
| # MIDL does not always generate '%_proxy.c' and '%_dlldata.c'. This behavior |
| # depends on contents of the source IDL file. Calling TOUCH_FILE below ensures |
| # that both files will be created so bjam will not try to recreate them |
| # constantly. |
| TOUCH_FILE = [ common.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)" |
| } |