1# Copyright Vladimir Prus 2004. 2# Copyright Peter Dimov 2018 3# 4# Distributed under the Boost Software License, Version 1.0. 5# (See accompanying file LICENSE_1_0.txt 6# or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8import common ; 9import errors ; 10import feature ; 11import clang ; 12import msvc ; 13import os ; 14import toolset ; 15import generators ; 16import path ; 17import regex ; 18 19feature.extend-subfeature toolset clang : platform : win ; 20 21toolset.inherit-generators clang-win <toolset>clang <toolset-clang:platform>win : msvc : msvc.compile.c.pch msvc.compile.c++.pch ; 22toolset.inherit-flags clang-win : msvc ; 23toolset.inherit-rules clang-win : msvc ; 24 25# Override default do-nothing generators. 26generators.override clang-win.compile.rc : rc.compile.resource ; 27generators.override clang-win.compile.mc : mc.compile ; 28 29if [ MATCH (--debug-(clang-(win-)?)?configuration) : [ modules.peek : ARGV ] ] 30{ 31 local rule .notice ( messages * ) 32 { 33 ECHO "notice: [clang-win]" $(messages) ; 34 } 35} 36else 37{ 38 local rule .notice ( messages * ) 39 { 40 } 41} 42 43# [ get-option archiver : 32 : $(options) ] 44# 45# returns <archiver-32>, or <archiver> 46 47local rule get-option ( option : addr : options * ) 48{ 49 local r = [ feature.get-values "<$(option)-$(addr)>" : $(options) ] ; 50 r ?= [ feature.get-values "<$(option)>" : $(options) ] ; 51 return $(r) ; 52} 53 54# init 55# 56# options: 57# 58# <assembler>ml.exe (or <assembler-32>, or <assembler-64>) 59# <archiver>lib.exe 60# <manifest-tool>mt.exe 61# <resource-compiler>rc.exe 62# <mc-compiler>mc.exe 63# <idl-compiler>midl.exe 64 65rule init ( version ? : command * : options * ) 66{ 67 command = [ common.get-invocation-command-nodefault clang-win : clang-cl.exe : $(command) ] ; 68 69 if ! $(command) 70 { 71 errors.error "Cannot configure toolset clang-win: no 'clang-cl.exe' command found or given" ; 72 } 73 74 local compiler = "\"$(command)\"" ; 75 compiler = "$(compiler:J= )" ; 76 77 version ?= [ MATCH "version ([0-9.]+)" : [ SHELL "$(compiler) -v 2>&1" ] ] ; 78 79 .notice "using compiler '$(compiler)', version '$(version)'" ; 80 81 local condition = [ common.check-init-parameters clang-win : version $(version) ] ; 82 83 common.handle-options clang-win : $(condition) : $(command) : $(options) ; 84 85 for local addr in 32 64 86 { 87 local config = [ SPLIT_BY_CHARACTERS [ SHELL "$(compiler) -m$(addr) -### foo.obj /link 2>&1" ] : "\n" ] ; 88 89 local match = 1 ; 90 local items ; 91 92 while $(match) 93 { 94 match = [ MATCH "^ *(\"[^\"]*\")(.*)" : $(config) ] ; 95 96 if $(match) 97 { 98 items += $(match[1]) ; 99 config = $(match[2]) ; 100 } 101 } 102 103 local ml ; 104 105 if $(items) 106 { 107 ml = [ regex.replace $(items[1]) "x64\\\\+link\\.exe" "x64\\ml64.exe" ] ; 108 ml = [ regex.replace $(ml) "x86\\\\+link\\.exe" "x86\\ml.exe" ] ; 109 110 if ! [ MATCH "(ml\\.exe)" "(ml64\\.exe)" : $(ml) ] 111 { 112 ml = ; 113 } 114 } 115 116 local assembler = [ get-option "assembler" : $(addr) : $(options) ] ; 117 assembler ?= $(ml) ; 118 if $(addr) = 32 { assembler ?= ml.exe ; } else { assembler ?= ml64.exe ; } 119 120 local link ; 121 122 if $(items) 123 { 124 link = [ regex.replace $(items[1]) "\\\\+HostX64\\\\+x86\\\\+" "\\HostX86\\x86\\" ] ; 125 } 126 127 local archiver = [ get-option "archiver" : $(addr) : $(options) ] ; 128 129 if $(link) 130 { 131 archiver ?= "$(link) /lib" ; 132 } 133 archiver ?= lib.exe ; 134 135 .notice "$(addr):" "using assembler '$(assembler)'" ; 136 .notice "$(addr):" "using archiver '$(archiver)'" ; 137 138 local manifest-tool = [ get-option "manifest-tool" : $(addr) : $(options) ] ; 139 local resource-compiler = [ get-option "resource-compiler" : $(addr) : $(options) ] ; 140 local mc-compiler = [ get-option "mc-compiler" : $(addr) : $(options) ] ; 141 local idl-compiler = [ get-option "idl-compiler" : $(addr) : $(options) ] ; 142 143 for local item in $(items) 144 { 145 match = [ MATCH "\"-libpath:(.*)\\\\+Lib\\\\.*\\\\um\\\\+x(.*)\"" : $(item) ] ; 146 147 if $(match) 148 { 149 local sdk-path = "$(match[1])\\bin\\x$(match[2])" ; 150 .notice "$(addr):" "using SDK path '$(sdk-path)'" ; 151 152 manifest-tool ?= "\"$(sdk-path)\\mt.exe\"" ; 153 resource-compiler ?= "\"$(sdk-path)\\rc.exe\"" ; 154 mc-compiler ?= "\"$(sdk-path)\\mc.exe\"" ; 155 idl-compiler ?= "\"$(sdk-path)\\midl.exe\"" ; 156 } 157 } 158 159 manifest-tool ?= mt.exe ; 160 resource-compiler ?= rc.exe ; 161 mc-compiler ?= mc.exe ; 162 idl-compiler ?= midl.exe ; 163 164 .notice "$(addr):" "using manifest-tool '$(manifest-tool)'" ; 165 .notice "$(addr):" "using resource-compiler '$(resource-compiler)'" ; 166 .notice "$(addr):" "using mc-compiler '$(mc-compiler)'" ; 167 .notice "$(addr):" "using idl-compiler '$(idl-compiler)'" ; 168 169 local cond = "$(condition)/<architecture>/<address-model>$(addr)" "$(condition)/<architecture>x86/<address-model>$(addr)" ; 170 if $(addr) = 32 { cond += "$(condition)/<architecture>/<address-model>" ; } 171 172 toolset.flags clang-win.compile .CC $(cond) : $(compiler) -m$(addr) ; 173 toolset.flags clang-win.link .LD $(cond) : $(compiler) -m$(addr) /link "/incremental:no" "/manifest" ; 174 toolset.flags clang-win.compile .ASM $(cond) : $(assembler) -nologo -c -Zp4 -Cp -Cx ; 175 toolset.flags clang-win.compile .ASM_OUTPUT $(cond) : -Fo ; 176 toolset.flags clang-win.archive .LD $(cond) : $(archiver) /nologo ; 177 toolset.flags clang-win.link .MT $(cond) : $(manifest-tool) -nologo ; 178 toolset.flags clang-win.compile .MC $(cond) : $(mc-compiler) ; 179 toolset.flags clang-win.compile .RC $(cond) : $(resource-compiler) ; 180 toolset.flags clang-win.compile .IDL $(cond) : $(idl-compiler) ; 181 } 182 183 toolset.flags clang-win.link LIBRARY_OPTION <toolset>clang-win : "" : unchecked ; 184} 185