From d497c9e77e2d91a67f89a48130dff6a050fb1d91 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Wed, 23 Nov 2005 07:58:07 +0000 Subject: [PATCH] Add support for Microsoft IDL compiler. Patch from Alexey Pakhunov. [SVN r31750] --- v2/tools/midl.jam | 153 ++++++++++++++++++++++++++++++++++++++++++++++ v2/tools/msvc.jam | 20 ++++++ 2 files changed, 173 insertions(+) create mode 100644 v2/tools/midl.jam diff --git a/v2/tools/midl.jam b/v2/tools/midl.jam new file mode 100644 index 000000000..5d7c487a0 --- /dev/null +++ b/v2/tools/midl.jam @@ -0,0 +1,153 @@ +# 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 '' 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 yes : /Oicf ; +flags midl.compile.idl MIDLFLAGS no : /Oic ; +flags midl.compile.idl MIDLFLAGS yes : /robust ; +flags midl.compile.idl MIDLFLAGS no : /no_robust ; + +# Architecture-specific options +architecture-x86 = x86 ; +address-model-32 = 32 ; +address-model-64 = 64 ; + +flags midl.compile.idl MIDLFLAGS $(architecture-x86)/$(address-model-32) : /win32 ; +flags midl.compile.idl MIDLFLAGS $(architecture-x86)/64 : /x64 ; +flags midl.compile.idl MIDLFLAGS ia64/$(address-model-64) : /ia64 ; + + +flags midl.compile.idl DEFINES ; +flags midl.compile.idl UNDEFS ; +flags midl.compile.idl INCLUDES ; + + +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)" +} diff --git a/v2/tools/msvc.jam b/v2/tools/msvc.jam index 34fccdfd2..9982a4fac 100644 --- a/v2/tools/msvc.jam +++ b/v2/tools/msvc.jam @@ -18,6 +18,7 @@ import sequence : unique ; import common ; import "class" : new ; import rc ; +import midl ; if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] { @@ -36,6 +37,9 @@ feature.subfeature toolset msvc : vendor # 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 @@ local rule configure-really ( assembler = [ get-values : $(options) ] ; assembler ?= ml ; + idl-compiler = [ get-values : $(options) ] ; + idl-compiler ?= midl ; + for local i in 1 2 3 { @@ -342,6 +349,7 @@ local rule configure-really ( 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.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : msvc generators.override msvc.compile.rc : rc.resource-compile ; generators.register-standard msvc.compile.asm : ASM : OBJ : msvc ; +generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : msvc ; +generators.override msvc.compile.idl : midl.compile.idl ; + # # Declare flags and action for compilation # @@ -553,6 +564,15 @@ actions compile.rc $(.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 : ;