Skip to content

Commit 459a750

Browse files
committed
Merge pull request #33 from softworkz/submit_parallel
Parallel NASM Builds and various fixes
2 parents e62d42d + f65aa5c commit 459a750

6 files changed

Lines changed: 351 additions & 179 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
*.exe
2-
*.zip
2+
*.zip
3+
/.vs

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ VSNASM
77
[![license](https://img.shields.io/github/license/ShiftMediaProject/VSNASM.svg)](https://github.com/ShiftMediaProject/VSNASM)
88
[![donate](https://img.shields.io/badge/donate-link-brightgreen.svg)](https://shiftmediaproject.github.io/8-donate/)
99

10+
## New Version 2.0
11+
12+
### Major Update with Parallel Build Support
13+
14+
**Changes**
15+
16+
- Added support for PARALLEL NASM builds
17+
- Proper change detection for NASM files
18+
(rebuilds when the NASM file or its dependencies have changed)
19+
- Incremental Builds working reliably
20+
- Clean is working properly
21+
(doesn't start building NASM files when you clean the project)
22+
1023
## About
1124

1225
This project provides a set of build customisations that can be used within Visual Studio to compile assembly code using NASM.

install_script.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,10 @@ echo Checking for existing NASM in NASMPATH...
332332
if exist "%NASMPATH%\nasm.exe" (
333333
"%NASMPATH%\nasm.exe" -v >nul 2>&1
334334
if %ERRORLEVEL% equ 0 (
335-
echo "Using existing NASM binary from %NASMPATH%\nasm.exe..."
335+
echo Using existing NASM binary from "%NASMPATH%\nasm.exe"...
336336
goto SkipInstallNASM
337337
) else (
338-
echo "..existing NASM not found in NASMPATH=%NASMPATH%."
338+
echo Warning: A suitable nasm was not found in NASMPATH="%NASMPATH%".
339339
)
340340
)
341341
REM Download the latest nasm binary for windows

nasm.props

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3-
<PropertyGroup
4-
Condition="'$(NASMBeforeTargets)' == '' and '$(NASMAfterTargets)' == '' and '$(ConfigurationType)' != 'Makefile'">
5-
<NASMBeforeTargets>Midl</NASMBeforeTargets>
6-
<NASMAfterTargets>CustomBuild</NASMAfterTargets>
7-
</PropertyGroup>
83
<PropertyGroup>
94
<NasmPath Condition= "'$(NASMPATH)' == ''">$(VCInstallDir)</NasmPath>
105
</PropertyGroup>
116
<ItemDefinitionGroup>
127
<NASM>
13-
<ObjectFileName>$(IntDir)%(FileName).obj</ObjectFileName>
8+
<Outputs>$(IntDir)%(FileName).obj</Outputs>
149
<CommandLineTemplate Condition="'$(Platform)' == 'Win32'">"$(NasmPath)\nasm.exe" -Xvc -f win32 [AllOptions] [AdditionalOptions] "%(FullPath)"</CommandLineTemplate>
1510
<CommandLineTemplate Condition="'$(Platform)' == 'x64'">"$(NasmPath)\nasm.exe" -Xvc -f win64 [AllOptions] [AdditionalOptions] "%(FullPath)"</CommandLineTemplate>
16-
<CommandLineTemplate Condition="'$(Platform)' != 'Win32' and '$(Platform)' != 'x64'">echo NASM not supported on this platform
17-
exit 1</CommandLineTemplate>
11+
<CommandLineTemplate Condition="'$(Platform)' != 'Win32' and '$(Platform)' != 'x64'">echo NASM not supported on this platform &amp; exit 1</CommandLineTemplate>
1812
<ExecutionDescription>%(Identity)</ExecutionDescription>
13+
<Message Condition="'%(NASM.Message)' == ''">Performing NASM Compilation</Message>
14+
<LinkObjects Condition="'%(NASM.LinkObjects)' == ''">true</LinkObjects>
15+
<TreatOutputAsContent Condition="'%(NASM.TreatOutputAsContent)' == ''">false</TreatOutputAsContent>
16+
<TrackerLogDirectory Condition="'%(NASM.TrackerLogDirectory)' == ''">$(TLogLocation)</TrackerLogDirectory>
17+
<MinimalRebuildFromTracking Condition="'%(NASM.MinimalRebuildFromTracking)' == ''">true</MinimalRebuildFromTracking>
18+
<OutputItemType Condition="'%(NASM.OutputItemType)' == ''">Object</OutputItemType>
19+
<BuildInParallel Condition="'%(NASM.BuildInParallel)' == ''">true</BuildInParallel>
20+
<MaxProcesses Condition="'%(NASM.MaxProcesses)' == ''">0</MaxProcesses>
21+
<MaxItemsInBatch Condition="'%(NASM.MaxItemsInBatch)' == ''">1</MaxItemsInBatch>
22+
<VerifyInputsAndOutputsExist Condition="'%(NASM.VerifyInputsAndOutputsExist)' == ''">true</VerifyInputsAndOutputsExist>
1923
</NASM>
2024
</ItemDefinitionGroup>
2125
</Project>

nasm.targets

Lines changed: 196 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,86 +7,227 @@
77
<Targets>_NASM</Targets>
88
</AvailableItemName>
99
</ItemGroup>
10+
1011
<PropertyGroup>
1112
<ComputeLinkInputsTargets>
1213
$(ComputeLinkInputsTargets);
1314
ComputeNASMOutput;
1415
</ComputeLinkInputsTargets>
16+
</PropertyGroup>
17+
18+
<PropertyGroup>
1519
<ComputeLibInputsTargets>
1620
$(ComputeLibInputsTargets);
1721
ComputeNASMOutput;
1822
</ComputeLibInputsTargets>
1923
</PropertyGroup>
24+
25+
<PropertyGroup>
26+
<ComputeImpLibInputsTargets>
27+
$(ComputeImpLibInputsTargets);
28+
ComputeNASMOutput;
29+
</ComputeImpLibInputsTargets>
30+
</PropertyGroup>
31+
2032
<UsingTask
2133
TaskName="NASM"
2234
TaskFactory="XamlTaskFactory"
2335
AssemblyName="Microsoft.Build.Tasks.v4.0">
2436
<Task>$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml</Task>
2537
</UsingTask>
26-
<Target
27-
Name="_WriteNasmTlogs"
28-
Condition="'@(NASM)' != '' and '@(SelectedFiles)' == ''">
38+
39+
<!-- *******************************************************************************************
40+
NASM
41+
******************************************************************************************* -->
42+
43+
<PropertyGroup Condition="'$(NASMAfterTargets)'!='' or '$(NASMBeforeTargets)'!=''">
44+
<NASMToolBeforeTargets>$(NASMBeforeTargets)</NASMToolBeforeTargets>
45+
<NASMToolAfterTargets>$(NASMAfterTargets)</NASMToolAfterTargets>
46+
</PropertyGroup>
47+
48+
<!--If no before/after targets are set, then set the default-->
49+
<PropertyGroup Condition="'$(NASMAfterTargets)'=='' and '$(NASMBeforeTargets)'==''">
50+
<NASMToolBeforeTargets>Midl</NASMToolBeforeTargets>
51+
<NASMToolAfterTargets>PreBuildEvent</NASMToolAfterTargets>
52+
<NASMBeforeTargets>PostBuildEvent</NASMBeforeTargets>
53+
<NASMAfterTargets>BscMake</NASMAfterTargets>
54+
</PropertyGroup>
55+
56+
<!-- If Selective File Build is enabled, then dont let custom interupt the build order-->
57+
<PropertyGroup Condition="'$(SelectedFiles)'!=''">
58+
<NASMToolBeforeTargets></NASMToolBeforeTargets>
59+
<NASMToolAfterTargets></NASMToolAfterTargets>
60+
<NASMBeforeTargets></NASMBeforeTargets>
61+
<NASMAfterTargets></NASMAfterTargets>
62+
</PropertyGroup>
63+
64+
<Target Name="_NASM"
65+
BeforeTargets="$(NASMToolBeforeTargets)"
66+
AfterTargets="$(NASMToolAfterTargets)"
67+
DependsOnTargets="SelectNASM;ComputeNASMOutput">
68+
69+
<PropertyGroup>
70+
<CustomBuildToolArchitecture Condition="'$(CustomBuildToolArchitecture)' == ''">Native32Bit</CustomBuildToolArchitecture>
71+
</PropertyGroup>
72+
2973
<ItemGroup>
30-
<NASM Remove="@(NASM)" Condition="'%(NASM.ExcludedFromBuild)' == 'true' or '%(NASM.ObjectFileName)' == ''" />
74+
<NASM Update="@(NASM)">
75+
<Inputs>%(NASM.FullPath);%(NASM.AdditionalDependencies);$(MSBuildProjectFile)</Inputs>
76+
<AdditionalInputs>%(NASM.FullPath);%(NASM.AdditionalDependencies);$(MSBuildProjectFile)</AdditionalInputs>
77+
78+
<Message>%(NASM.ExecutionDescription)</Message>
79+
80+
<!-- option fragments used for [AllOptions] -->
81+
<_NasmOpt_Debug></_NasmOpt_Debug>
82+
<_NasmOpt_Prefix></_NasmOpt_Prefix>
83+
<_NasmOpt_Postfix></_NasmOpt_Postfix>
84+
<_NasmOpt_IncludePaths></_NasmOpt_IncludePaths>
85+
<_NasmOpt_PreIncludeFiles></_NasmOpt_PreIncludeFiles>
86+
<_NasmOpt_Defines></_NasmOpt_Defines>
87+
<_NasmOpt_Undefines></_NasmOpt_Undefines>
88+
<_NasmOpt_Werror></_NasmOpt_Werror>
89+
90+
<_NasmOpt_Debug Condition="'%(NASM.GenerateDebugInformation)' == 'true'">-g</_NasmOpt_Debug>
91+
<_NasmOpt_Prefix Condition="'%(NASM.SymbolsPrefix)' != ''">--prefix %(NASM.SymbolsPrefix)</_NasmOpt_Prefix>
92+
<_NasmOpt_Postfix Condition="'%(NASM.SymbolsPostfix)' != ''">--postfix %(NASM.SymbolsPostfix)</_NasmOpt_Postfix>
93+
<_NasmOpt_IncludePaths Condition="'%(NASM.IncludePaths)' != ''">-I"$([System.String]::Copy('%(NASM.IncludePaths)').Trim(';').Replace(';', '/" -I"'))/"</_NasmOpt_IncludePaths>
94+
<_NasmOpt_PreIncludeFiles Condition="'%(NASM.PreIncludeFiles)' != ''">-P"$([System.String]::Copy('%(NASM.PreIncludeFiles)').Trim(';').Replace(';', '" -P"'))"</_NasmOpt_PreIncludeFiles>
95+
<_NasmOpt_Defines Condition="'%(NASM.PreprocessorDefinitions)' != ''">-D$([System.String]::Copy('%(NASM.PreprocessorDefinitions)').Trim(';').Replace(';', ' -D'))</_NasmOpt_Defines>
96+
<_NasmOpt_Undefines Condition="'%(NASM.UndefinePreprocessorDefinitions)' != ''">-U$([System.String]::Copy('%(NASM.UndefinePreprocessorDefinitions)').Trim(';').Replace(';', ' -U'))</_NasmOpt_Undefines>
97+
<_NasmOpt_Werror Condition="'%(NASM.TreatWarningsAsErrors)' == 'true'">-Werror</_NasmOpt_Werror>
98+
</NASM>
3199
</ItemGroup>
32-
<ItemGroup Condition="'@(NASM)' != ''">
33-
<_NasmReadTlog Include="^%(NASM.FullPath);%(NASM.AdditionalDependencies)" />
34-
<_NasmWriteTlog Include="^%(NASM.FullPath);$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '%(NASM.ObjectFileName)'))" />
100+
101+
<ItemGroup>
102+
<NASM Update="@(NASM)">
103+
<_NasmAllOptions>-o "%(NASM.Outputs)" %(NASM._NasmOpt_Debug) %(NASM._NasmOpt_Prefix) %(NASM._NasmOpt_Postfix) %(NASM._NasmOpt_IncludePaths) %(NASM._NasmOpt_PreIncludeFiles) %(NASM._NasmOpt_Defines) %(NASM._NasmOpt_Undefines) %(NASM._NasmOpt_Werror)</_NasmAllOptions>
104+
</NASM>
35105
</ItemGroup>
36-
<WriteLinesToFile
37-
Condition="'@(_NasmReadTlog)' != ''"
38-
File="$(TLogLocation)Nasm.read.1u.tlog"
39-
Lines="@(_NasmReadTlog->MetaData('Identity')->ToUpperInvariant());"
40-
Overwrite="true"
41-
Encoding="Unicode"/>
42-
<WriteLinesToFile
43-
Condition="'@(_NasmWriteTlog)' != ''"
44-
File="$(TLogLocation)Nasm.write.1u.tlog"
45-
Lines="@(_NasmWriteTlog->MetaData('Identity')->ToUpperInvariant());"
46-
Overwrite="true"
47-
Encoding="Unicode"/>
106+
48107
<ItemGroup>
49-
<_NasmReadTlog Remove="@(_NasmReadTlog)" />
50-
<_NasmWriteTlog Remove="@(_NasmWriteTlog)" />
108+
<NASM Update="@(NASM)">
109+
<Command>$([System.String]::Copy('%(NASM.CommandLineTemplate)').Replace('[AllOptions]', '%(NASM._NasmAllOptions)').Replace('[AdditionalOptions]', '%(NASM.AdditionalOptions)'))</Command>
110+
</NASM>
51111
</ItemGroup>
52-
</Target>
53-
<Target
54-
Name="_NASM"
55-
BeforeTargets="$(NASMBeforeTargets)"
56-
AfterTargets="$(NASMAfterTargets)"
57-
Condition="'@(NASM)' != ''"
58-
Outputs="%(NASM.ObjectFileName)"
59-
Inputs="%(NASM.Identity);%(NASM.AdditionalDependencies);$(MSBuildProjectFile)"
60-
DependsOnTargets="_WriteNasmTlogs;_SelectedFiles">
61-
<ItemGroup Condition="'@(SelectedFiles)' != ''">
62-
<NASM Remove="@(NASM)" Condition="'%(Identity)' != '@(SelectedFiles)'" />
112+
113+
<!-- delete old ParallelCustomBuild tlogs, same as CustomBuild -->
114+
<GetOutOfDateItems
115+
Sources ="@(_EmptyItemGroup)"
116+
OutputsMetadataName ="Outputs"
117+
DependenciesMetadataName ="AdditionalInputs"
118+
CommandMetadataName ="Command"
119+
TLogDirectory ="$(TLogLocation)"
120+
TLogNamePrefix ="ParallelNasmBuild"
121+
TrackFileAccess ="$(TrackFileAccess)"
122+
/>
123+
124+
<!-- Get out of date items for NASM (full build case) -->
125+
<GetOutOfDateItems
126+
Condition ="'$(SelectedFiles)' == ''"
127+
Sources ="@(NASM)"
128+
OutputsMetadataName ="Outputs"
129+
DependenciesMetadataName ="AdditionalInputs"
130+
CommandMetadataName ="Command"
131+
TLogDirectory ="$(TLogLocation)"
132+
TLogNamePrefix ="NasmBuild"
133+
TrackFileAccess ="$(TrackFileAccess)"
134+
CheckForInterdependencies ="true">
135+
<Output TaskParameter="OutOfDateSources" ItemName="_NasmBuild" />
136+
</GetOutOfDateItems>
137+
138+
<!-- Selected-files build: just take all NASM items -->
139+
<ItemGroup Condition ="'$(SelectedFiles)' != ''">
140+
<_NasmBuild Include="@(NASM)" />
141+
</ItemGroup>
142+
143+
<!-- Build items which can be built in parallel (ignored for selected-files build) -->
144+
<ItemGroup Condition="'$(SelectedFiles)' == ''">
145+
<_ParallelNasmBuild Include="@(_NasmBuild)"
146+
Condition="'%(_NasmBuild.BuildInParallel)' == 'true' and '%(_NasmBuild.DependsOnAnotherItemOutput)' != 'true'" />
63147
</ItemGroup>
64-
<Message
65-
Condition="'@(NASM)' != '' and '%(NASM.ExcludedFromBuild)' != 'true'"
66-
Importance="High"
67-
Text="%(NASM.ExecutionDescription)" />
68-
<NASM
69-
Condition="'@(NASM)' != '' and '%(NASM.ExcludedFromBuild)' != 'true'"
70-
Inputs="%(NASM.Inputs)"
71-
ObjectFileName="%(NASM.ObjectFileName)"
72-
SymbolsPrefix="%(NASM.SymbolsPrefix)"
73-
SymbolsPostfix="%(NASM.SymbolsPostfix)"
74-
GenerateDebugInformation="%(NASM.GenerateDebugInformation)"
75-
IncludePaths="%(NASM.IncludePaths)"
76-
PreIncludeFiles="%(NASM.PreIncludeFiles)"
77-
PreprocessorDefinitions="%(NASM.PreprocessorDefinitions)"
78-
UndefinePreprocessorDefinitions="%(NASM.UndefinePreprocessorDefinitions)"
79-
TreatWarningsAsErrors="%(NASM.TreatWarningsAsErrors)"
80-
CommandLineTemplate="%(NASM.CommandLineTemplate)"
81-
AdditionalOptions="%(NASM.AdditionalOptions)"
148+
149+
<ParallelCustomBuild
150+
Condition ="'@(_ParallelNasmBuild)' != ''"
151+
Sources ="@(_ParallelNasmBuild)"
152+
MaxProcesses ="%(_ParallelNasmBuild.MaxProcesses)"
153+
MaxItemsInBatch ="%(_ParallelNasmBuild.MaxItemsInBatch)"
154+
AcceptableNonZeroExitCodes ="%(_ParallelNasmBuild.AcceptableNonZeroExitCodes)"
155+
StdOutEncoding ="%(_ParallelNasmBuild.StdOutEncoding)"
156+
StdErrEncoding ="%(_ParallelNasmBuild.StdErrEncoding)"
157+
UseMsbuildResourceManager ="$(UseMsbuildResourceManager)"
82158
/>
159+
160+
<!-- build the remaining items sequentially -->
161+
<ItemGroup Condition="'@(_ParallelNasmBuild)' != ''">
162+
<_NasmBuild Remove="@(_ParallelNasmBuild)" />
163+
<_ParallelNasmBuild Remove="@(_ParallelNasmBuild)" />
164+
</ItemGroup>
165+
166+
<CustomBuild Condition ="'@(_NasmBuild)' != ''"
167+
Sources ="@(_NasmBuild)"
168+
BuildSuffix ="$(_BuildSuffix)"
169+
MinimalRebuildFromTracking ="false"
170+
AcceptableNonZeroExitCodes ="%(_NasmBuild.AcceptableNonZeroExitCodes)"
171+
StdOutEncoding ="%(_NasmBuild.StdOutEncoding)"
172+
StdErrEncoding ="%(_NasmBuild.StdErrEncoding)">
173+
</CustomBuild>
174+
175+
<ItemGroup Condition="'@(_NasmBuild)' != ''">
176+
<_NasmBuild Remove="@(_NasmBuild)" />
177+
</ItemGroup>
178+
83179
</Target>
84-
<Target
85-
Name="ComputeNASMOutput"
86-
Condition="'@(NASM)' != ''">
180+
181+
<Target Name="SelectNASM" DependsOnTargets="_SelectedFiles">
182+
<ItemGroup Condition="'@(SelectedFiles)'!=''">
183+
<NASM Remove="@(NASM)" Condition="'%(Identity)'!='@(SelectedFiles)'"/>
184+
<NASM>
185+
<MinimalRebuildFromTracking>false</MinimalRebuildFromTracking>
186+
</NASM>
187+
</ItemGroup>
188+
<ItemGroup>
189+
<NASM Update="@(NASM)">
190+
<Outputs Condition="'%(NASM.ObjectFileName)' != ''">%(NASM.ObjectFileName)</Outputs>
191+
</NASM>
192+
</ItemGroup>
193+
</Target>
194+
195+
196+
<Target Name="ComputeNASMOutput" DependsOnTargets="SelectNASM" >
197+
198+
<ItemGroup >
199+
<NASMOutputs Include="@(NASM->Metadata('Outputs'))" Condition="'@(NASM)' != ''"/>
200+
201+
<NASMOutputs Condition="'%(NASMOutputs.ExcludedFromBuild)'!='true'
202+
and '%(NASMOutputs.OutputItemType)'==''
203+
and '%(NASMOutputs.LinkObjects)'=='true'
204+
and ('%(Extension)'=='.obj' or '%(Extension)'=='.res' or '%(Extension)'=='.rsc' or '%(Extension)'=='.lib')">
205+
<OutputItemType Condition="'$(ConfigurationType)'=='StaticLibrary'">Lib</OutputItemType>
206+
<OutputItemType Condition="'$(ConfigurationType)'!='StaticLibrary'">Link</OutputItemType>
207+
</NASMOutputs>
208+
</ItemGroup>
209+
210+
<!-- Add NASM Outputs to lib, link or other tools -->
211+
<CreateItem
212+
Include="@(NASMOutputs)"
213+
Condition="'%(NASMOutputs.OutputItemType)'!=''">
214+
<Output
215+
TaskParameter="Include"
216+
ItemName="%(NASMOutputs.OutputItemType)"/>
217+
<Output
218+
TaskParameter="Include"
219+
Condition="'%(NASMOutputs.OutputItemType)' == 'Link' and '$(GenerateImportLib)'=='true'"
220+
ItemName="ImpLib"/>
221+
</CreateItem>
222+
223+
<MakeDir Directories="@(NASMOutputs->'%(RootDir)%(Directory)')" />
224+
225+
<!-- Cleanup -->
87226
<ItemGroup>
88-
<Link Include="@(NASM->Metadata('ObjectFileName')->Distinct()->ClearMetadata())" Condition="'%(NASM.ExcludedFromBuild)' != 'true'"/>
89-
<Lib Include="@(NASM->Metadata('ObjectFileName')->Distinct()->ClearMetadata())" Condition="'%(NASM.ExcludedFromBuild)' != 'true'"/>
227+
<NASMOutputs Remove="@(NASMOutputs)" />
90228
</ItemGroup>
229+
91230
</Target>
231+
232+
92233
</Project>

0 commit comments

Comments
 (0)