| 227 |
dpurdie |
1 |
#
|
|
|
2 |
# Module name : CSHARP
|
|
|
3 |
# Module type : Makefile system
|
|
|
4 |
# Compiler(s) : ANSI C
|
|
|
5 |
# Environment(s): WIN32
|
|
|
6 |
#
|
|
|
7 |
# Description:
|
|
|
8 |
# CSHARP for Windows
|
|
|
9 |
#
|
|
|
10 |
#............................................................................#
|
|
|
11 |
use strict;
|
|
|
12 |
use warnings;
|
| 4097 |
dpurdie |
13 |
use File::Basename;
|
|
|
14 |
use File::Spec::Functions;
|
| 227 |
dpurdie |
15 |
use MakeEntry;
|
|
|
16 |
|
|
|
17 |
#
|
| 4074 |
dpurdie |
18 |
# External data
|
|
|
19 |
#
|
|
|
20 |
our %SRC_DEPEND;
|
|
|
21 |
|
|
|
22 |
#
|
| 227 |
dpurdie |
23 |
# Global data
|
|
|
24 |
#
|
|
|
25 |
my %resource_files;
|
|
|
26 |
my $pdb_none;
|
|
|
27 |
|
| 343 |
dpurdie |
28 |
my $toolset_name = 'csharp'; # Toolset name : Error reporting
|
| 255 |
dpurdie |
29 |
my $toolset_info;
|
|
|
30 |
my $toolset_version = '1.1';
|
|
|
31 |
my %ToolsetVersion =
|
|
|
32 |
(
|
|
|
33 |
'1.1' => { 'def' => 'CSHARP.DEF', # Def file to use
|
|
|
34 |
'pragma' => 0, # True: Compiler supports #pragma
|
|
|
35 |
'warnings' => '', # Comma sep list of warnings to ignore
|
|
|
36 |
},
|
|
|
37 |
|
|
|
38 |
'2.0' => { 'def' => 'CSHARP2005.DEF',
|
|
|
39 |
'pragma' => 1,
|
|
|
40 |
'warnings' => '1668',
|
|
|
41 |
},
|
| 291 |
dpurdie |
42 |
|
|
|
43 |
'3.5' => { 'def' => 'CSHARP2008.DEF',
|
|
|
44 |
'pragma' => 1,
|
|
|
45 |
'warnings' => '1668',
|
|
|
46 |
},
|
| 347 |
dpurdie |
47 |
|
|
|
48 |
'4.0' => { 'def' => 'CSHARP2010.DEF',
|
|
|
49 |
'pragma' => 1,
|
|
|
50 |
'warnings' => '1668',
|
| 351 |
dpurdie |
51 |
'platform' => 'x86',
|
| 347 |
dpurdie |
52 |
},
|
| 4192 |
dpurdie |
53 |
|
|
|
54 |
'4.5' => { 'def' => 'CSHARP2012.DEF',
|
|
|
55 |
'pragma' => 1,
|
|
|
56 |
'warnings' => '1668',
|
|
|
57 |
'platform' => 'x86',
|
|
|
58 |
},
|
| 6133 |
dpurdie |
59 |
|
|
|
60 |
'4.6' => { 'def' => 'CSHARP2015.DEF',
|
|
|
61 |
'pragma' => 1,
|
|
|
62 |
'warnings' => '1668',
|
|
|
63 |
'platform' => 'x86',
|
|
|
64 |
},
|
|
|
65 |
|
| 255 |
dpurdie |
66 |
);
|
|
|
67 |
|
|
|
68 |
|
| 227 |
dpurdie |
69 |
##############################################################################
|
|
|
70 |
# ToolsetInit()
|
|
|
71 |
# Runtime initialisation
|
|
|
72 |
#
|
|
|
73 |
##############################################################################
|
|
|
74 |
|
|
|
75 |
ToolsetInit();
|
|
|
76 |
|
|
|
77 |
sub ToolsetInit
|
|
|
78 |
{
|
|
|
79 |
|
|
|
80 |
#.. Parse arguments (Toolset arguments)
|
|
|
81 |
#
|
| 343 |
dpurdie |
82 |
Debug( "$toolset_name(@::ScmToolsetArgs)" );
|
| 227 |
dpurdie |
83 |
|
|
|
84 |
foreach $_ ( @::ScmToolsetArgs ) {
|
|
|
85 |
if (/^--Version=(.*)/) { # MS SDK Version
|
|
|
86 |
$toolset_version = $1;
|
|
|
87 |
|
|
|
88 |
} else {
|
| 343 |
dpurdie |
89 |
Message( "$toolset_name toolset: unknown option $_ -- ignored\n" );
|
| 227 |
dpurdie |
90 |
}
|
|
|
91 |
}
|
|
|
92 |
|
|
|
93 |
#.. Parse arguments (platform arguments)
|
|
|
94 |
#
|
| 343 |
dpurdie |
95 |
Debug( "$toolset_name(@::ScmPlatformArgs)" );
|
| 227 |
dpurdie |
96 |
|
|
|
97 |
foreach $_ ( @::ScmPlatformArgs ) {
|
|
|
98 |
if (/^--product=(.*)/) { # GBE product
|
|
|
99 |
|
|
|
100 |
} elsif (/^--Version=(.*)/) { # MS SDK Version
|
|
|
101 |
$toolset_version = $1;
|
|
|
102 |
|
|
|
103 |
} else {
|
| 343 |
dpurdie |
104 |
Message( "$toolset_name toolset: unknown platform argument $_ -- ignored\n" );
|
| 227 |
dpurdie |
105 |
}
|
|
|
106 |
}
|
|
|
107 |
|
| 255 |
dpurdie |
108 |
#.. Validate SDK version
|
|
|
109 |
# Currently supported versions are described in a HASH
|
| 227 |
dpurdie |
110 |
#
|
| 255 |
dpurdie |
111 |
$toolset_info = $ToolsetVersion{$toolset_version};
|
| 343 |
dpurdie |
112 |
Error( "$toolset_name toolset: Unknown version: $toolset_version" ) unless ( defined $toolset_info );
|
| 255 |
dpurdie |
113 |
|
| 227 |
dpurdie |
114 |
#.. Standard.rul requirements
|
|
|
115 |
#
|
|
|
116 |
$::s = undef;
|
|
|
117 |
$::o = '';
|
|
|
118 |
$::a = 'netmodule';
|
|
|
119 |
$::so = 'dll';
|
|
|
120 |
$::exe = '.exe';
|
|
|
121 |
|
|
|
122 |
#.. Toolset configuration
|
|
|
123 |
#
|
|
|
124 |
$::ScmToolsetVersion = "1.0.0"; # our version
|
|
|
125 |
$::ScmToolsetGenerate = 0; # generate optional
|
|
|
126 |
$::ScmToolsetProgDependancies = 0; # handle Prog dependancies myself
|
|
|
127 |
%::ScmToolsetProgSource = ( # handle these files directly
|
|
|
128 |
'.cs' => '', # Will be flagged as "CSRCS"
|
|
|
129 |
'.resx' => '--Resource=', # Will be passed with prefix
|
|
|
130 |
'.dtd' => '--Dtd=', # Will be passed with prefix
|
|
|
131 |
);
|
|
|
132 |
|
|
|
133 |
#.. define Visual C/C+ environment
|
|
|
134 |
Init( "csharp" );
|
| 255 |
dpurdie |
135 |
ToolsetDefines( $toolset_info->{'def'} );
|
| 227 |
dpurdie |
136 |
ToolsetRules( "csharp.rul" );
|
|
|
137 |
# ToolsetRules( "standard.rul" );
|
|
|
138 |
|
|
|
139 |
|
|
|
140 |
#.. Extend the CompilerOption directive
|
|
|
141 |
# Create a standard data structure
|
|
|
142 |
# This is a hash of hashes
|
|
|
143 |
# The first hash is keyed by CompileOption keyword
|
|
|
144 |
# The second hash contains pairs of values to set or remove
|
|
|
145 |
#
|
|
|
146 |
%::ScmToolsetCompilerOptions =
|
|
|
147 |
(
|
|
|
148 |
#
|
|
|
149 |
# Control the thread model to use
|
|
|
150 |
# This will affect the compiler options and the linker options
|
|
|
151 |
#
|
|
|
152 |
'noaddlibs' => { 'ADDLINKLIBS' , undef }, # Don't add link libs
|
|
|
153 |
'addlibs' => { 'ADDLINKLIBS' , '1' }, # default
|
|
|
154 |
'nowarn=' => { 'NOWARNLIST' ,\&NoWarns }, # Suppress warnings
|
|
|
155 |
'nopdb' => { 'PDB_NONE', 1 }, # Disable all PDB files
|
|
|
156 |
'pdb' => { 'PDB_NONE', undef }, # Enable PDB files: Default
|
|
|
157 |
'subsystem:windows' => { 'LDSUBSYSTEM' , 'winexe' },
|
|
|
158 |
'subsystem:console' => { 'LDSUBSYSTEM' , 'exe' },
|
| 351 |
dpurdie |
159 |
'platform:32' => { 'NET_PLATFORM', 'x86' },
|
|
|
160 |
'platform:64' => { 'NET_PLATFORM', 'x64' },
|
|
|
161 |
'platform:any' => { 'NET_PLATFORM', undef },
|
| 2931 |
dpurdie |
162 |
'noversiondll' => { 'NO_VERSIONED_DLLS', 1 },
|
| 227 |
dpurdie |
163 |
);
|
|
|
164 |
|
|
|
165 |
#
|
|
|
166 |
# Set default options
|
|
|
167 |
#
|
|
|
168 |
$::ScmCompilerOpts{'ADDLINKLIBS'} = '1';
|
| 255 |
dpurdie |
169 |
$::ScmCompilerOpts{'NOWARNLIST'} = $toolset_info->{'warnings'};
|
| 227 |
dpurdie |
170 |
$::ScmCompilerOpts{'LDSUBSYSTEM'} = 'winexe';
|
| 351 |
dpurdie |
171 |
$::ScmCompilerOpts{'NET_PLATFORM'} = $toolset_info->{'platform'};
|
| 2931 |
dpurdie |
172 |
$::ScmCompilerOpts{'NO_VERSIONED_DLLS'} = undef;
|
| 227 |
dpurdie |
173 |
}
|
|
|
174 |
|
|
|
175 |
|
|
|
176 |
#-------------------------------------------------------------------------------
|
|
|
177 |
# Function : NoWarns
|
|
|
178 |
#
|
|
|
179 |
# Description : ScmToolsetCompilerOptions extension function
|
| 255 |
dpurdie |
180 |
# Accumulates the NoWarn options as a comma seperated list
|
| 227 |
dpurdie |
181 |
#
|
|
|
182 |
# Inputs : $key - Name of the Option
|
|
|
183 |
# $value - Option Value. Comma sep list of numbers
|
| 255 |
dpurdie |
184 |
# $ukey - User key (within $::ScmCompilerOpts)
|
| 227 |
dpurdie |
185 |
#
|
|
|
186 |
# Returns : New sting to save
|
|
|
187 |
#
|
|
|
188 |
sub NoWarns
|
|
|
189 |
{
|
| 255 |
dpurdie |
190 |
my ($key, $value, $ukey) = @_;
|
|
|
191 |
my @NoWarnList = split (',', $::ScmCompilerOpts{$ukey});
|
| 261 |
dpurdie |
192 |
UniquePush ( \@NoWarnList, split (',', $value) );
|
| 227 |
dpurdie |
193 |
return join ',', @NoWarnList;
|
|
|
194 |
}
|
|
|
195 |
|
|
|
196 |
##############################################################################
|
|
|
197 |
# ToolsetPreprocess()
|
|
|
198 |
# Process collected data before the makefile is generated
|
|
|
199 |
# This, optional, routine is called from within MakefileGenerate()
|
|
|
200 |
# It allows the toolset to massage any of the collected data before
|
|
|
201 |
# the makefile is created
|
|
|
202 |
#
|
|
|
203 |
##############################################################################
|
|
|
204 |
sub ToolsetPreprocess
|
|
|
205 |
{
|
|
|
206 |
#
|
|
|
207 |
# Extract the current state of PDB_NONE
|
|
|
208 |
# Are PDB files to be constructed.
|
|
|
209 |
#
|
|
|
210 |
$pdb_none = $::ScmCompilerOpts{'PDB_NONE'};
|
|
|
211 |
}
|
|
|
212 |
|
|
|
213 |
##############################################################################
|
|
|
214 |
# ToolsetPostprocess
|
|
|
215 |
# Process collected data as the makefile is generated
|
|
|
216 |
# This, optional, routine is called from within MakefileGenerate()
|
|
|
217 |
# It allows the toolset to massage any of the collected data before
|
|
|
218 |
# the makefile is finally closed created
|
|
|
219 |
#
|
|
|
220 |
##############################################################################
|
|
|
221 |
|
|
|
222 |
sub ToolsetPostprocess
|
|
|
223 |
{
|
|
|
224 |
#
|
|
|
225 |
# Generate Recipes to create Resource Files
|
|
|
226 |
# This is done outside of the Prog and Lib routines
|
|
|
227 |
# so that they can be agregated
|
|
|
228 |
#
|
|
|
229 |
# Note: don't make the makefile a dependant as changes to the
|
|
|
230 |
# makefile won't affect the file
|
|
|
231 |
#
|
|
|
232 |
for my $resource ( sort keys %resource_files )
|
|
|
233 |
{
|
|
|
234 |
my $src = $resource_files{$resource}{src};
|
|
|
235 |
my $root = $resource_files{$resource}{root};
|
|
|
236 |
|
|
|
237 |
my $me = MakeEntry::New (*MAKEFILE, $resource );
|
|
|
238 |
$me->AddComment ("Build Resource: $root" );
|
| 261 |
dpurdie |
239 |
# $me->AddDependancy ( '$(SCM_MAKEFILE)' );
|
| 227 |
dpurdie |
240 |
$me->AddDependancy ( $src );
|
| 4074 |
dpurdie |
241 |
if ( exists $SRC_DEPEND{$src} )
|
|
|
242 |
{
|
|
|
243 |
$me->AddDependancy ( split( /$;/, $SRC_DEPEND{$src} ) );
|
|
|
244 |
}
|
| 227 |
dpurdie |
245 |
$me->AddRecipe ( '$(RESGEN)' );
|
|
|
246 |
$me->Print();
|
|
|
247 |
|
|
|
248 |
#
|
|
|
249 |
# Add to the deletion list
|
|
|
250 |
#
|
|
|
251 |
ToolsetGenerate( $resource );
|
|
|
252 |
}
|
|
|
253 |
}
|
|
|
254 |
|
|
|
255 |
#-------------------------------------------------------------------------------
|
|
|
256 |
# Function : Toolset_genres
|
|
|
257 |
#
|
|
|
258 |
# Description : Internal function to assist in the creation of a resource
|
|
|
259 |
# In many cases it will create an entry for later processing
|
|
|
260 |
#
|
|
|
261 |
# Inputs : $subdir - Root of the target directory for the generated
|
|
|
262 |
# resource file
|
| 4097 |
dpurdie |
263 |
# $src - Path to the source resource file
|
| 227 |
dpurdie |
264 |
#
|
|
|
265 |
# Returns : Path to the generated resource file
|
|
|
266 |
# This will be FQN named file
|
|
|
267 |
# Path to the associated .CS file
|
|
|
268 |
#
|
|
|
269 |
# Notes : Create and maintain the %resource_files hash
|
|
|
270 |
# Key is the path to the compiled file
|
|
|
271 |
# Values are:
|
|
|
272 |
# {src} - Path to the source file
|
|
|
273 |
# {root} - Basic file name (Display Purposes Only)
|
|
|
274 |
#
|
|
|
275 |
# Need to create a '.resource' file with a FQN name
|
|
|
276 |
# This is not that simple. Need to
|
|
|
277 |
# 1) Extract the (optional) ThisName from the .resx file
|
|
|
278 |
# If not specified then the ThisName is the rootfilename
|
|
|
279 |
# without any .as[pca]x extension.
|
|
|
280 |
# 2) Extract the namespace from the associated .cs file
|
|
|
281 |
# 3) FQN = NameSpace.ThisName
|
|
|
282 |
#
|
|
|
283 |
#
|
|
|
284 |
sub Toolset_genres
|
|
|
285 |
{
|
|
|
286 |
my ($subdir, $src ) = @_;
|
|
|
287 |
|
|
|
288 |
#
|
|
|
289 |
# Ensure that the .cs file also exists
|
| 4097 |
dpurdie |
290 |
# We may have a NAME.Designer.cs or a NAME.cs file - Different VS versions do it differently
|
|
|
291 |
# The file 'should' be in the same directory, but may be in the parent
|
| 227 |
dpurdie |
292 |
#
|
| 4097 |
dpurdie |
293 |
my $csfile;
|
|
|
294 |
my @csNames = qw(.Designer.cs .cs);
|
|
|
295 |
my @csDirs = qw( . ..);
|
|
|
296 |
my($csfilename, $csdirectories, $cssuffix) = fileparse($src, '.resx');
|
|
|
297 |
csScan:
|
|
|
298 |
foreach my $dir (@csDirs){
|
|
|
299 |
foreach my $name (@csNames) {
|
|
|
300 |
my $testPath = catfile($csdirectories, $dir ,$csfilename . $name);
|
|
|
301 |
if (-f $testPath)
|
|
|
302 |
{
|
|
|
303 |
$csfile = $testPath;
|
|
|
304 |
$csfile =~ s~\\~/~g;
|
|
|
305 |
last csScan;
|
|
|
306 |
}
|
|
|
307 |
}
|
|
|
308 |
}
|
| 3967 |
dpurdie |
309 |
|
| 4097 |
dpurdie |
310 |
# Warn if we can't find one.
|
|
|
311 |
# Create a dummy name - may fail later
|
| 227 |
dpurdie |
312 |
#
|
| 4097 |
dpurdie |
313 |
unless ($csfile)
|
|
|
314 |
{
|
|
|
315 |
Warning ("$toolset_name toolset: Resx File without a .cs or Designer.cs file", "File: $src");
|
|
|
316 |
($csfile = $src) =~ s~\.resx$~.cs~;
|
|
|
317 |
}
|
|
|
318 |
|
|
|
319 |
#
|
| 227 |
dpurdie |
320 |
# Scan the .resx file looking for the ThisName element
|
|
|
321 |
# A very simple and crude parser
|
|
|
322 |
#
|
|
|
323 |
my $ThisName;
|
| 3967 |
dpurdie |
324 |
my $ThisNameGuess;
|
| 227 |
dpurdie |
325 |
open ( SCAN, '<', $src ) || Error ("Cannot open file for reading: $!", "File: $src" );
|
|
|
326 |
while ( <SCAN> )
|
|
|
327 |
{
|
|
|
328 |
if ( m~\<data name=\"\$this\.Name\"\>~ )
|
|
|
329 |
{
|
|
|
330 |
# Next line will contain the needed data item
|
|
|
331 |
my $element = <SCAN>;
|
|
|
332 |
$element =~ m~\<.+\>(.+)\</.+\>~;
|
|
|
333 |
$ThisName = $1;
|
| 343 |
dpurdie |
334 |
Error ("$toolset_name toolset: Resx parsing: Bad this.Name", "File: $src") unless $ThisName;
|
| 227 |
dpurdie |
335 |
$ThisName =~ s~\s+~~g;
|
|
|
336 |
last;
|
|
|
337 |
}
|
|
|
338 |
}
|
|
|
339 |
close SCAN;
|
|
|
340 |
|
|
|
341 |
#
|
|
|
342 |
# Name not found
|
|
|
343 |
# Use a default. Filename with any .aspx, .asax, .ascx removed
|
|
|
344 |
#
|
|
|
345 |
unless ( $ThisName )
|
|
|
346 |
{
|
| 3967 |
dpurdie |
347 |
$ThisNameGuess = $ThisName;
|
|
|
348 |
$ThisNameGuess = StripDirExt($src);
|
|
|
349 |
$ThisNameGuess =~ s~\.as[pac]x~~i;
|
| 227 |
dpurdie |
350 |
}
|
|
|
351 |
|
|
|
352 |
#
|
| 3967 |
dpurdie |
353 |
# Scan the.cs file looking for the namespace and class
|
| 227 |
dpurdie |
354 |
# A very simple and crude parser
|
|
|
355 |
#
|
|
|
356 |
my $NameSpace;
|
| 3967 |
dpurdie |
357 |
my $ClassName;
|
|
|
358 |
|
| 227 |
dpurdie |
359 |
open ( SCAN, '<', $csfile ) || Error ("Cannot open file for reading: $!", "File: $csfile" );
|
|
|
360 |
while ( <SCAN> )
|
|
|
361 |
{
|
| 3967 |
dpurdie |
362 |
next if ( m ~\s*//~);
|
|
|
363 |
|
|
|
364 |
if ( m~namespace\s+(\S+)~ ) {
|
| 227 |
dpurdie |
365 |
$NameSpace = $1;
|
| 3967 |
dpurdie |
366 |
|
|
|
367 |
} elsif ( m~\s+class\s+(\S+)~ ) {
|
|
|
368 |
$ClassName = $1;
|
|
|
369 |
|
| 227 |
dpurdie |
370 |
}
|
| 3967 |
dpurdie |
371 |
last if ( defined($NameSpace) && defined($ClassName) );
|
|
|
372 |
|
| 227 |
dpurdie |
373 |
}
|
|
|
374 |
close SCAN;
|
| 343 |
dpurdie |
375 |
Error ("$toolset_name toolset: Resx parsing: NameSpace not found", "File: $csfile") unless $NameSpace;
|
| 227 |
dpurdie |
376 |
|
|
|
377 |
#
|
|
|
378 |
# Need to create an output file name that is a function of the FQN
|
| 3967 |
dpurdie |
379 |
# To be backwardly compatible
|
|
|
380 |
# Use the ClassName - if it was found
|
|
|
381 |
# Else Use the ThisName - if it was found
|
|
|
382 |
# Else Use the Guessed ThisName
|
| 227 |
dpurdie |
383 |
#
|
| 3967 |
dpurdie |
384 |
if ( !defined($ClassName)) {
|
|
|
385 |
$ClassName = $ThisName;
|
|
|
386 |
if ( !defined($ClassName)) {
|
|
|
387 |
$ClassName = $ThisNameGuess;
|
|
|
388 |
}
|
|
|
389 |
}
|
|
|
390 |
|
|
|
391 |
my $root = "$NameSpace.$ClassName.resources";
|
| 227 |
dpurdie |
392 |
my $resource = $subdir . '/' . $root;
|
|
|
393 |
$resource_files{$resource}{src} = $src;
|
|
|
394 |
$resource_files{$resource}{root} = $root;
|
|
|
395 |
|
|
|
396 |
return $resource, $csfile;
|
|
|
397 |
}
|
|
|
398 |
|
|
|
399 |
|
|
|
400 |
#-------------------------------------------------------------------------------
|
|
|
401 |
# Function : Toolset_gensnk
|
|
|
402 |
#
|
|
|
403 |
# Description : Function to create a wrapper file for the processing
|
|
|
404 |
# of a StrongNameKey file
|
|
|
405 |
#
|
|
|
406 |
# Create only one wrapper per SNK file
|
|
|
407 |
#
|
|
|
408 |
# Inputs : $name - Name of component
|
|
|
409 |
# $snk - Path to the SNK file
|
|
|
410 |
#
|
|
|
411 |
# Returns : Path to the wrapper file
|
|
|
412 |
#
|
|
|
413 |
my %snk_data;
|
|
|
414 |
sub Toolset_gensnk
|
|
|
415 |
{
|
|
|
416 |
my ($name, $snk ) = @_;
|
|
|
417 |
my $file = StripDirExt( $snk );
|
|
|
418 |
|
|
|
419 |
#
|
|
|
420 |
# Only create the file once
|
|
|
421 |
# Otherwise we will get nasty make messages
|
|
|
422 |
#
|
|
|
423 |
|
|
|
424 |
if ( exists $snk_data{$snk} )
|
|
|
425 |
{
|
|
|
426 |
return $snk_data{$snk}{output};
|
|
|
427 |
}
|
|
|
428 |
|
|
|
429 |
#
|
|
|
430 |
# Determine the target name
|
|
|
431 |
# Create the source file in the currentt directory
|
|
|
432 |
# If we build it in the OBJ directory we get two files
|
|
|
433 |
#
|
|
|
434 |
my $snk_file = '$(OBJDIR)/' . "Jats_${file}.cs";
|
|
|
435 |
$snk_data{$snk}{output} = $snk_file;
|
|
|
436 |
ToolsetGenerate( $snk_file );
|
|
|
437 |
|
|
|
438 |
#
|
|
|
439 |
# Determine the Tag Name
|
|
|
440 |
# Used to conatin information in the makefile
|
|
|
441 |
#
|
|
|
442 |
my $tag = "${file}_snk";
|
|
|
443 |
|
|
|
444 |
#
|
|
|
445 |
# Create Rules and Recipes to create the SNK wrapper file
|
|
|
446 |
#
|
|
|
447 |
my $me = MakeEntry::New (*MAKEFILE, $snk_file );
|
|
|
448 |
$me->AddComment ("Build Strong Name Key File Wrapper: $snk" );
|
|
|
449 |
$me->AddDependancy ( $snk );
|
| 261 |
dpurdie |
450 |
$me->AddDependancy ( '$(SCM_MAKEFILE)' );
|
| 227 |
dpurdie |
451 |
$me->AddRecipe ( '$(call GenSnkWrapper,' . $tag . ')' );
|
|
|
452 |
$me->Print();
|
|
|
453 |
|
|
|
454 |
#
|
|
|
455 |
# Create the data t be placed into the wrapper file
|
|
|
456 |
#
|
|
|
457 |
my ($io) = ToolsetPrinter::New();
|
|
|
458 |
|
|
|
459 |
my $ms_snk = $snk;
|
|
|
460 |
|
|
|
461 |
$io->Label( "SNK Wrapper file content", $tag ); # label
|
|
|
462 |
$io->SetTag( $tag ); # macro tag
|
| 255 |
dpurdie |
463 |
$io->Cmd( '// This is JATS GENERATED FILE' );
|
|
|
464 |
$io->Cmd( '// Do not edit' );
|
|
|
465 |
$io->Cmd( '// Do not version control' );
|
|
|
466 |
|
| 227 |
dpurdie |
467 |
$io->Cmd( 'using System.Reflection;' );
|
|
|
468 |
$io->Cmd( 'using System.Runtime.CompilerServices;' );
|
|
|
469 |
|
|
|
470 |
$io->Cmd( '//' );
|
|
|
471 |
$io->Cmd( '// In order to sign your assembly you must specify a key to use. Refer to the' );
|
|
|
472 |
$io->Cmd( '// Microsoft .NET Framework documentation for more information on assembly signing.' );
|
|
|
473 |
$io->Cmd( '//' );
|
|
|
474 |
$io->Cmd( '// Use the attributes below to control which key is used for signing.' );
|
|
|
475 |
$io->Cmd( '//' );
|
|
|
476 |
$io->Cmd( '// Notes:' );
|
|
|
477 |
$io->Cmd( '// (*) If no key is specified, the assembly is not signed.' );
|
|
|
478 |
$io->Cmd( '// (*) KeyName refers to a key that has been installed in the Crypto Service' );
|
|
|
479 |
$io->Cmd( '// Provider (CSP) on your machine. KeyFile refers to a file which contains' );
|
|
|
480 |
$io->Cmd( '// a key.' );
|
|
|
481 |
$io->Cmd( '// (*) If the KeyFile and the KeyName values are both specified, the' );
|
|
|
482 |
$io->Cmd( '// following processing occurs:' );
|
|
|
483 |
$io->Cmd( '// (1) If the KeyName can be found in the CSP, that key is used.' );
|
|
|
484 |
$io->Cmd( '// (2) If the KeyName does not exist and the KeyFile does exist, the key' );
|
|
|
485 |
$io->Cmd( '// in the KeyFile is installed into the CSP and used.' );
|
|
|
486 |
$io->Cmd( '// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.' );
|
|
|
487 |
$io->Cmd( '// When specifying the KeyFile, the location of the KeyFile should be' );
|
|
|
488 |
$io->Cmd( '// relative to the project output directory which is' );
|
|
|
489 |
$io->Cmd( '// %Project Directory%\obj\<configuration>. For example, if your KeyFile is' );
|
|
|
490 |
$io->Cmd( '// located in the project directory, you would specify the AssemblyKeyFile' );
|
|
|
491 |
$io->Cmd( '// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]' );
|
|
|
492 |
$io->Cmd( '// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework' );
|
|
|
493 |
$io->Cmd( '// documentation for more information on this.' );
|
|
|
494 |
$io->Cmd( '//' );
|
|
|
495 |
|
|
|
496 |
$io->Cmd( '[assembly: AssemblyDelaySign(false)]' );
|
| 255 |
dpurdie |
497 |
$io->Cmd( '#pragma warning disable 1699' ) if ($toolset_info->{'pragma'});
|
| 227 |
dpurdie |
498 |
$io->Cmd( '[assembly: AssemblyKeyFile(@"'. $snk .'")]' );
|
| 255 |
dpurdie |
499 |
$io->Cmd( '#pragma warning restore 1699' ) if ($toolset_info->{'pragma'});
|
| 227 |
dpurdie |
500 |
$io->Cmd( '[assembly: AssemblyKeyName("")]' );
|
|
|
501 |
$io->Newline();
|
|
|
502 |
|
|
|
503 |
#
|
|
|
504 |
# Return the path to where the file will be created
|
|
|
505 |
#
|
|
|
506 |
return $snk_file;
|
|
|
507 |
}
|
|
|
508 |
|
|
|
509 |
|
|
|
510 |
###############################################################################
|
|
|
511 |
# ToolsetLD( $name, \@args, \@objs, \@libraries )
|
|
|
512 |
# This subroutine takes the user options and builds the rules
|
|
|
513 |
# required to link the program 'name'.
|
|
|
514 |
#
|
|
|
515 |
# Arguments:
|
|
|
516 |
# $name - Name of the target program
|
|
|
517 |
# $pArgs - Ref to an array of argumennts
|
|
|
518 |
# $pObjs - Ref to an array of object files
|
|
|
519 |
# $pLibs - Ref to an array of libraries
|
|
|
520 |
#
|
|
|
521 |
# Output:
|
|
|
522 |
# Makefile recipes to create the Program
|
|
|
523 |
#
|
|
|
524 |
# Notes:
|
|
|
525 |
# This Program Builder will handle its own dependancies
|
|
|
526 |
# It will also create rules and recipes to construct various
|
|
|
527 |
# parts directly fromm source
|
|
|
528 |
#
|
|
|
529 |
# Options:
|
|
|
530 |
# --Resource=file.resx
|
|
|
531 |
# --Dtd=file.dtd
|
|
|
532 |
# --Icon=file
|
|
|
533 |
# --Entry=xxxxx # Entry point
|
|
|
534 |
# --Console # Console app
|
|
|
535 |
# --Windows # Windows app (default)
|
|
|
536 |
# --DLL # As a DLL (No P|D)
|
|
|
537 |
# --Doc
|
|
|
538 |
# --NoPDB
|
|
|
539 |
# CSharpSourceFile
|
|
|
540 |
#
|
|
|
541 |
#
|
|
|
542 |
###############################################################################
|
|
|
543 |
|
|
|
544 |
sub ToolsetLD
|
|
|
545 |
{
|
|
|
546 |
my ( $name, $pArgs, $pObjs, $pLibs ) = @_;
|
|
|
547 |
my ( @reslist, @resources, @csource, @dtd );
|
|
|
548 |
my $no_pdb = $pdb_none;
|
|
|
549 |
my $entry;
|
|
|
550 |
my $noaddlibs;
|
|
|
551 |
my $icon;
|
|
|
552 |
my $docFile;
|
|
|
553 |
my ($base, $root, $full );
|
|
|
554 |
my $link_target = $::ScmCompilerOpts{'LDSUBSYSTEM'};
|
|
|
555 |
my $snk;
|
|
|
556 |
my $is_a_dll;
|
|
|
557 |
|
|
|
558 |
#.. Parse arguments
|
|
|
559 |
#
|
|
|
560 |
foreach ( @$pArgs ) {
|
|
|
561 |
if (/^--Resource=(.+)/) { # Resource definition
|
|
|
562 |
push @reslist, MakeSrcResolve($1);
|
|
|
563 |
|
|
|
564 |
} elsif (/^--Dtd=(.+)/) { # dtd definition
|
|
|
565 |
push @dtd, MakeSrcResolve($1);
|
|
|
566 |
|
|
|
567 |
} elsif (/^--Icon=(.+)/) {
|
| 343 |
dpurdie |
568 |
Error ("$toolset_name LD: Only one Icon file allowed") if ( $icon );
|
| 227 |
dpurdie |
569 |
$icon = MakeSrcResolve($1);
|
|
|
570 |
|
|
|
571 |
} elsif (/^--StrongNameKey=(.+)/) {
|
| 343 |
dpurdie |
572 |
Error ("$toolset_name LD: Only one SNK file allowed") if ( $snk );
|
| 227 |
dpurdie |
573 |
$snk = MakeSrcResolve($1);
|
|
|
574 |
|
|
|
575 |
} elsif (/^--Entry=(.+)/) {
|
|
|
576 |
$entry = $1;
|
|
|
577 |
|
|
|
578 |
} elsif (/^--Doc/) {
|
|
|
579 |
$docFile = 1;
|
|
|
580 |
|
|
|
581 |
} elsif (/^--Windows/) {
|
|
|
582 |
$link_target = 'winexe';
|
|
|
583 |
|
|
|
584 |
} elsif (/^--Console/) {
|
|
|
585 |
$link_target = 'exe';
|
|
|
586 |
|
|
|
587 |
} elsif (/^--DLL/) {
|
|
|
588 |
$is_a_dll = 1;
|
|
|
589 |
|
|
|
590 |
} elsif (/^--NoPDB$/) {
|
|
|
591 |
$no_pdb = 1;
|
|
|
592 |
|
|
|
593 |
} elsif ( !/^-/ ) {
|
|
|
594 |
push @csource, MakeSrcResolve($_);
|
|
|
595 |
|
|
|
596 |
} else {
|
| 343 |
dpurdie |
597 |
Message( "$toolset_name LD: unknown option $_ -- ignored\n" );
|
| 227 |
dpurdie |
598 |
|
|
|
599 |
}
|
|
|
600 |
}
|
|
|
601 |
|
|
|
602 |
#
|
|
|
603 |
# Determine the target output name
|
|
|
604 |
#
|
|
|
605 |
$base = $name;
|
|
|
606 |
$root = "\$(BINDIR)/$base";
|
|
|
607 |
$full = $root . $::exe;
|
|
|
608 |
$docFile = "$root.xml" if ( $docFile );
|
|
|
609 |
|
|
|
610 |
#
|
|
|
611 |
# Special case for DLLs that need to be created without a D or P mangled
|
|
|
612 |
# into the name. Create them as Progs just to fool the system
|
|
|
613 |
# Used when creating specialised web services
|
|
|
614 |
#
|
|
|
615 |
if ( $is_a_dll )
|
|
|
616 |
{
|
|
|
617 |
#
|
|
|
618 |
# Create a phony target
|
|
|
619 |
# The EXE name is not actually created, but the EXE target needs to be retained
|
|
|
620 |
#
|
|
|
621 |
my $exe_name = $root . $::exe;
|
|
|
622 |
my $dll_name = $root . '.' . $::so;
|
|
|
623 |
$full = $dll_name;
|
|
|
624 |
$link_target = 'library';
|
|
|
625 |
|
|
|
626 |
my $me = MakeEntry::New (*MAKEFILE, $exe_name, '--Phony' );
|
|
|
627 |
$me->AddComment ("Build Program: $name as a DLL" );
|
|
|
628 |
$me->AddDependancy ( $dll_name );
|
|
|
629 |
$me->Print();
|
| 255 |
dpurdie |
630 |
|
|
|
631 |
#
|
|
|
632 |
# Need to specifically clean this up, since we have fiddled with the
|
|
|
633 |
# name of the generated file
|
|
|
634 |
#
|
|
|
635 |
ToolsetGenerate( $dll_name );
|
| 227 |
dpurdie |
636 |
}
|
|
|
637 |
|
|
|
638 |
#
|
|
|
639 |
# Create Rules and Recipes to convert the .resx files to .resource files
|
|
|
640 |
#
|
|
|
641 |
foreach my $res ( @reslist )
|
|
|
642 |
{
|
|
|
643 |
my ($res, $cs) = Toolset_genres ('$(OBJDIR)', $res );
|
|
|
644 |
|
|
|
645 |
UniquePush ( \@resources, $res );
|
|
|
646 |
UniquePush ( \@csource, $cs );
|
|
|
647 |
}
|
|
|
648 |
|
|
|
649 |
#
|
|
|
650 |
# Create Rules and Recipes to provide Assembly instructions
|
|
|
651 |
# for the creation of a StrongNameKey
|
|
|
652 |
#
|
|
|
653 |
if ( $snk )
|
|
|
654 |
{
|
|
|
655 |
UniquePush ( \@csource, Toolset_gensnk ($name, $snk ) );
|
|
|
656 |
}
|
|
|
657 |
|
| 335 |
dpurdie |
658 |
my ($io) = ToolsetPrinter::New();
|
|
|
659 |
my $dep = $io->SetLdTarget( $name );
|
|
|
660 |
|
| 227 |
dpurdie |
661 |
#
|
|
|
662 |
# Create Rules and Recipes to create the Program
|
|
|
663 |
# This will be a combination of source, libraries and resources
|
|
|
664 |
#
|
|
|
665 |
my $me = MakeEntry::New (*MAKEFILE, $full );
|
|
|
666 |
$me->AddComment ("Build Program: $name" );
|
|
|
667 |
$me->AddName ( $docFile ) if ( $docFile );
|
| 335 |
dpurdie |
668 |
$me->AddDependancy ( $dep );
|
| 261 |
dpurdie |
669 |
$me->AddDependancy ( '$(SCM_MAKEFILE)' );
|
| 227 |
dpurdie |
670 |
$me->AddDependancy ( @resources );
|
|
|
671 |
$me->AddDependancy ( @csource );
|
|
|
672 |
$me->AddDependancy ( @dtd );
|
|
|
673 |
$me->AddDependancy ( $icon );
|
|
|
674 |
$me->AddRecipe ( '$(CSC)' );
|
|
|
675 |
$me->Print();
|
|
|
676 |
|
|
|
677 |
|
|
|
678 |
#
|
|
|
679 |
#.. Compiler command file
|
|
|
680 |
# Now piece together a variable $(name_ld) which ends up in
|
|
|
681 |
# the command file linking the application.
|
|
|
682 |
#
|
|
|
683 |
$io->Label( "Linker commands", $name ); # label
|
|
|
684 |
$io->SetTag( "${name}_ld" ); # macro tag
|
|
|
685 |
|
|
|
686 |
$io->Label( "Linker Command File", $name ); # label
|
|
|
687 |
|
|
|
688 |
#
|
|
|
689 |
# Basic options
|
|
|
690 |
#
|
|
|
691 |
$io->Cmd( "/target:$link_target" );
|
|
|
692 |
$io->Cmd("/doc:$docFile") if ( $docFile ) ;
|
|
|
693 |
$io->Cmd( "/win32icon:\$(subst /,\\\\,$icon)" ) if $icon;
|
|
|
694 |
$io->Cmd( "/main:$entry" ) if $entry;
|
|
|
695 |
|
|
|
696 |
#
|
|
|
697 |
# Add in the Resource Files
|
|
|
698 |
# the source files
|
|
|
699 |
# the libraries
|
|
|
700 |
#
|
|
|
701 |
$io->Cmd( "/res:\$(subst /,\\\\,$_)" ) foreach @resources;
|
|
|
702 |
$io->Cmd( "/res:\$(subst /,\\\\,$_)" ) foreach @dtd;
|
|
|
703 |
$io->Cmd( "\$(subst /,\\\\,$_)" ) foreach @csource;
|
|
|
704 |
$io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
|
| 335 |
dpurdie |
705 |
$io->Newline();
|
| 227 |
dpurdie |
706 |
|
|
|
707 |
|
| 335 |
dpurdie |
708 |
#.. Dependency link,
|
|
|
709 |
# Create a library dependency file
|
|
|
710 |
# Create command file to build applicaton dependency list
|
|
|
711 |
# from the list of dependent libraries
|
| 227 |
dpurdie |
712 |
#
|
| 335 |
dpurdie |
713 |
# Create makefile directives to include the dependency
|
|
|
714 |
# list into the makefile.
|
| 227 |
dpurdie |
715 |
#
|
| 335 |
dpurdie |
716 |
$io->DepRules( $pLibs, \&ToolsetLibRecipe, $full );
|
|
|
717 |
$io->LDDEPEND();
|
| 227 |
dpurdie |
718 |
|
|
|
719 |
#
|
|
|
720 |
# Files to clean up
|
|
|
721 |
#
|
|
|
722 |
ToolsetGenerate( "$root.ld" );
|
|
|
723 |
ToolsetGenerate( "$root.pdb" );
|
|
|
724 |
ToolsetGenerate( $docFile ) if $docFile;
|
|
|
725 |
|
|
|
726 |
|
|
|
727 |
#.. Package up files that are a part of the program
|
|
|
728 |
#
|
|
|
729 |
PackageProgAddFiles ( $name, $full );
|
|
|
730 |
PackageProgAddFiles ( $name, "$root.pdb", "Class=debug" ) unless ( $no_pdb );
|
|
|
731 |
PackageProgAddFiles ( $name, $docFile, "Class=map" ) if ( $docFile );
|
|
|
732 |
}
|
|
|
733 |
|
|
|
734 |
###############################################################################
|
| 289 |
dpurdie |
735 |
# ToolsetSHLD( $name, \@args, \@objs, \@libraries, $ver )
|
| 227 |
dpurdie |
736 |
# This subroutine takes the user options and builds the rules
|
|
|
737 |
# required to link the program 'name'.
|
|
|
738 |
#
|
|
|
739 |
# Arguments:
|
|
|
740 |
# $name - Name of the target program
|
|
|
741 |
# $pArgs - Ref to an array of argumennts
|
|
|
742 |
# $pObjs - Ref to an array of object files
|
|
|
743 |
# $pLibs - Ref to an array of libraries
|
| 289 |
dpurdie |
744 |
# $ver - Library Version string
|
| 227 |
dpurdie |
745 |
#
|
|
|
746 |
# Output:
|
|
|
747 |
# Makefile recipes to create the DLL
|
|
|
748 |
# Will create both versioned and unversioned DLLs
|
|
|
749 |
#
|
|
|
750 |
# Notes:
|
|
|
751 |
# This Library Builder will handle its own dependancies
|
|
|
752 |
# It will also create rules and recipes to construct various
|
|
|
753 |
# parts directly from source
|
|
|
754 |
#
|
|
|
755 |
# This is SO close to the ToolsetLD function that its not funny
|
|
|
756 |
#
|
|
|
757 |
# Options:
|
|
|
758 |
# --Resource=file.resx
|
|
|
759 |
# --Icon=file
|
|
|
760 |
# --StrongNameKey=file
|
|
|
761 |
# --Doc
|
|
|
762 |
# --NoPDB
|
| 2931 |
dpurdie |
763 |
# --NoVersionDll
|
| 227 |
dpurdie |
764 |
# CSharpSourceFile
|
|
|
765 |
#
|
|
|
766 |
#
|
|
|
767 |
###############################################################################
|
|
|
768 |
sub ToolsetSHLD
|
|
|
769 |
{
|
|
|
770 |
#
|
|
|
771 |
# Note: Use globals to kill warnings from internal sub
|
|
|
772 |
# Use _ prefix so that they don't get saved in Makefile_x.cfg
|
|
|
773 |
# Init as they are global
|
|
|
774 |
#
|
| 289 |
dpurdie |
775 |
our ( $_name, $_pArgs, $_pObjs, $_pLibs, $_ver ) = @_;
|
| 227 |
dpurdie |
776 |
our ( @_reslist, @_resources, @_csource, @_dtd ) = ();
|
|
|
777 |
our $_no_pdb = $pdb_none;
|
|
|
778 |
our $_noaddlibs = 0;
|
|
|
779 |
our $_icon = undef;
|
|
|
780 |
our $_docFile = undef;
|
|
|
781 |
our $_snk = undef;
|
|
|
782 |
|
| 2931 |
dpurdie |
783 |
my $noVersionedDlls = $::ScmCompilerOpts{'NO_VERSIONED_DLLS'};
|
|
|
784 |
|
| 227 |
dpurdie |
785 |
#.. Parse arguments
|
|
|
786 |
#
|
|
|
787 |
foreach ( @$_pArgs ) {
|
| 4031 |
dpurdie |
788 |
if (/^--Resource=(.+)/i) { # Resource definition
|
| 227 |
dpurdie |
789 |
push @_reslist, MakeSrcResolve($1);
|
|
|
790 |
|
| 4031 |
dpurdie |
791 |
} elsif (/^--Dtd=(.+)/i) { # dtd definition
|
| 227 |
dpurdie |
792 |
push @_dtd, MakeSrcResolve($1);
|
|
|
793 |
|
| 4031 |
dpurdie |
794 |
} elsif (/^--Icon=(.+)/i) {
|
| 343 |
dpurdie |
795 |
Error ("$toolset_name SHLD: Only one Icon file allowed") if ( $_icon );
|
| 227 |
dpurdie |
796 |
$_icon = MakeSrcResolve($1);
|
|
|
797 |
|
| 4031 |
dpurdie |
798 |
} elsif (/^--StrongNameKey=(.+)/i) {
|
| 343 |
dpurdie |
799 |
Error ("$toolset_name SHLD: Only one SNK file allowed") if ( $_snk );
|
| 227 |
dpurdie |
800 |
$_snk = MakeSrcResolve($1);
|
|
|
801 |
|
| 4031 |
dpurdie |
802 |
} elsif (/^--Doc/i) {
|
| 227 |
dpurdie |
803 |
$_docFile = 1;
|
|
|
804 |
|
| 4031 |
dpurdie |
805 |
} elsif (/^--NoPDB$/i) {
|
| 227 |
dpurdie |
806 |
$_no_pdb = 1;
|
|
|
807 |
|
| 4031 |
dpurdie |
808 |
} elsif (/^--NoVersionDll/i) {
|
| 2931 |
dpurdie |
809 |
$noVersionedDlls = 1;
|
|
|
810 |
|
| 227 |
dpurdie |
811 |
} elsif ( !/^-/ ) {
|
|
|
812 |
push @_csource, MakeSrcResolve($_);
|
|
|
813 |
|
|
|
814 |
} else {
|
| 343 |
dpurdie |
815 |
Message( "$toolset_name SHLD: unknown option $_ -- ignored\n" );
|
| 227 |
dpurdie |
816 |
|
|
|
817 |
}
|
|
|
818 |
}
|
|
|
819 |
|
|
|
820 |
#
|
|
|
821 |
# Create Rules and Recipes to convert the .resx files to .resource files
|
|
|
822 |
#
|
|
|
823 |
foreach my $res ( @_reslist )
|
|
|
824 |
{
|
|
|
825 |
my ($res, $cs) = Toolset_genres ('$(OBJDIR)/' . $_name, $res );
|
|
|
826 |
|
|
|
827 |
UniquePush ( \@_resources, $res );
|
|
|
828 |
UniquePush ( \@_csource, $cs );
|
|
|
829 |
}
|
|
|
830 |
|
|
|
831 |
#
|
|
|
832 |
# Create Rules and Recipes to provide Assembly instructions
|
|
|
833 |
# for the creation of a StrongNameKey
|
|
|
834 |
#
|
|
|
835 |
if ( $_snk )
|
|
|
836 |
{
|
|
|
837 |
UniquePush ( \@_csource, Toolset_gensnk ($_name, $_snk ) );
|
|
|
838 |
}
|
|
|
839 |
|
|
|
840 |
#
|
|
|
841 |
# Build Rules
|
|
|
842 |
# $1 - Base Name
|
|
|
843 |
# $2 - Name of the output DLL
|
|
|
844 |
#
|
|
|
845 |
sub BuildSHLD
|
|
|
846 |
{
|
|
|
847 |
my ($name, $lib ) = @_;
|
|
|
848 |
my ($root, $full, $link_target);
|
|
|
849 |
|
|
|
850 |
#
|
|
|
851 |
# Determine the target output name
|
|
|
852 |
#
|
|
|
853 |
$root = "\$(LIBDIR)/$lib";
|
|
|
854 |
$full = "$root.$::so";
|
|
|
855 |
$link_target = "library";
|
|
|
856 |
$_docFile = "$full.xml" if ($_docFile);
|
|
|
857 |
|
| 335 |
dpurdie |
858 |
my ($io) = ToolsetPrinter::New();
|
|
|
859 |
my $dep = $io->SetShldTarget( $lib );
|
|
|
860 |
|
| 227 |
dpurdie |
861 |
#
|
|
|
862 |
# Create Rules and Recipes to create the Program
|
|
|
863 |
# This will be a combination of source, libraries and resources
|
|
|
864 |
#
|
|
|
865 |
my $me = MakeEntry::New (*MAKEFILE, $full );
|
|
|
866 |
$me->AddComment ("Build Shared Library: $name" );
|
|
|
867 |
$me->AddName ( $_docFile ) if ( $_docFile );
|
| 261 |
dpurdie |
868 |
$me->AddDependancy ( '$(SCM_MAKEFILE)' );
|
| 335 |
dpurdie |
869 |
$me->AddDependancy ( $dep );
|
| 227 |
dpurdie |
870 |
$me->AddDependancy ( @_resources );
|
|
|
871 |
$me->AddDependancy ( @_csource );
|
|
|
872 |
$me->AddDependancy ( @_dtd );
|
|
|
873 |
$me->AddDependancy ( $_icon );
|
|
|
874 |
$me->AddRecipe ( '$(CSC)' );
|
|
|
875 |
$me->Print();
|
|
|
876 |
|
|
|
877 |
|
|
|
878 |
#
|
|
|
879 |
#.. Compiler command file
|
|
|
880 |
# Now piece together a variable $(name_ld) which ends up in
|
|
|
881 |
# the command file linking the application.
|
|
|
882 |
#
|
|
|
883 |
|
|
|
884 |
$io->Label( "Linker commands", $name ); # label
|
|
|
885 |
$io->SetTag( "${lib}_ld" ); # macro tag
|
|
|
886 |
|
|
|
887 |
$io->Label( "Linker Command File", $lib ); # label
|
|
|
888 |
|
|
|
889 |
#
|
|
|
890 |
# Basic options
|
|
|
891 |
#
|
|
|
892 |
$io->Cmd( "/target:$link_target" );
|
|
|
893 |
$io->Cmd( "/doc:$_docFile") if ( $_docFile ) ;
|
|
|
894 |
$io->Cmd( "/win32icon:\$(subst /,\\\\,$_icon)" ) if $_icon;
|
|
|
895 |
|
|
|
896 |
#
|
|
|
897 |
# Add in the Resource Files
|
|
|
898 |
# the source files
|
|
|
899 |
# the libraries
|
|
|
900 |
#
|
|
|
901 |
$io->Cmd( "/res:\$(subst /,\\\\,$_)" ) foreach @_resources;
|
|
|
902 |
$io->Cmd( "/res:\$(subst /,\\\\,$_)" ) foreach @_dtd;
|
|
|
903 |
$io->Cmd( "\$(subst /,\\\\,$_)" ) foreach @_csource;
|
|
|
904 |
$io->LibList( $name, $_pLibs, \&ToolsetLibRecipe );
|
| 335 |
dpurdie |
905 |
$io->Newline();
|
| 227 |
dpurdie |
906 |
|
| 335 |
dpurdie |
907 |
#.. Dependency link,
|
|
|
908 |
# Create a library dependency file
|
|
|
909 |
# Create command file to build applicaton dependency list
|
|
|
910 |
# from the list of dependent libraries
|
| 227 |
dpurdie |
911 |
#
|
| 335 |
dpurdie |
912 |
# Create makefile directives to include the dependency
|
|
|
913 |
# list into the makefile.
|
| 227 |
dpurdie |
914 |
#
|
| 335 |
dpurdie |
915 |
$io->DepRules( $_pLibs, \&ToolsetLibRecipe, $full );
|
|
|
916 |
$io->SHLDDEPEND( $name, $lib );
|
| 227 |
dpurdie |
917 |
|
|
|
918 |
#
|
|
|
919 |
# Files to clean up
|
|
|
920 |
#
|
|
|
921 |
ToolsetGenerate( "$root.ld" );
|
|
|
922 |
ToolsetGenerate( "$root.pdb" );
|
|
|
923 |
ToolsetGenerate( $_docFile ) if $_docFile;
|
|
|
924 |
|
|
|
925 |
|
|
|
926 |
#.. Package up files that are a part of the Library
|
|
|
927 |
#
|
|
|
928 |
PackageShlibAddFiles ( $name, $full );
|
|
|
929 |
PackageShlibAddFiles ( $name, "$root.pdb", "Class=debug" ) unless ( $_no_pdb );
|
|
|
930 |
PackageShlibAddFiles ( $name, $_docFile , "Class=map" ) if ( $_docFile );
|
|
|
931 |
|
|
|
932 |
#
|
|
|
933 |
# Return the full name of the created DLL.
|
|
|
934 |
#
|
|
|
935 |
return $full;
|
|
|
936 |
}
|
|
|
937 |
|
|
|
938 |
#
|
|
|
939 |
# Generate DLLs
|
|
|
940 |
#
|
|
|
941 |
# a) Unversioned DLL $_name$(GBE_TYPE).dll
|
|
|
942 |
# b) Versioned DLL $_name$(GBE_TYPE).xx.xx.xx.dll
|
|
|
943 |
#
|
|
|
944 |
my $funver = BuildSHLD( "$_name", "$_name\$(GBE_TYPE)" );
|
| 2931 |
dpurdie |
945 |
unless ($noVersionedDlls)
|
|
|
946 |
{
|
|
|
947 |
my $fver = BuildSHLD( "$_name", "$_name\$(GBE_TYPE).$_ver" );
|
| 227 |
dpurdie |
948 |
|
| 2931 |
dpurdie |
949 |
#
|
|
|
950 |
# Create a dependancy between the version and unversioned DLLs
|
|
|
951 |
#
|
|
|
952 |
my $me = MakeEntry::New (*MAKEFILE, $fver );
|
|
|
953 |
$me->AddComment ("Link Version and Unversioned Images: $_name" );
|
|
|
954 |
$me->AddDependancy ( $funver );
|
|
|
955 |
$me->Print();
|
|
|
956 |
}
|
| 227 |
dpurdie |
957 |
}
|
|
|
958 |
|
|
|
959 |
########################################################################
|
|
|
960 |
#
|
|
|
961 |
# Generate a linker/depend library recipe. This is a helper function
|
|
|
962 |
# used within this toolset.
|
|
|
963 |
#
|
|
|
964 |
# Arguments:
|
|
|
965 |
# $io I/O stream
|
|
|
966 |
#
|
|
|
967 |
# $target Name of the target
|
|
|
968 |
#
|
|
|
969 |
# $lib Library specification
|
|
|
970 |
#
|
|
|
971 |
# $dp If building a depend list, the full target name.
|
|
|
972 |
#
|
|
|
973 |
########################################################################
|
|
|
974 |
|
|
|
975 |
sub ToolsetLibRecipe
|
|
|
976 |
{
|
|
|
977 |
my ($io, $target, $lib, $dp) = @_;
|
|
|
978 |
|
|
|
979 |
if ( !defined($dp) ) { # linker
|
|
|
980 |
$io->Cmd( "/reference:\$(subst /,\\\\,\$(strip $lib)).$::so" );
|
|
|
981 |
|
|
|
982 |
} else { # depend
|
| 255 |
dpurdie |
983 |
$io->Cmd( "$dp:\t@(vglob2,$lib.$::so,CS_LIB)" );
|
| 227 |
dpurdie |
984 |
}
|
|
|
985 |
}
|
|
|
986 |
|
|
|
987 |
########################################################################
|
|
|
988 |
#
|
|
|
989 |
# Generate a project from the provided project solution file
|
|
|
990 |
# This is aimed at .NET work
|
|
|
991 |
#
|
|
|
992 |
# Arguments : $name - Base name of the project
|
|
|
993 |
# $solution - Path to the solutionn file
|
|
|
994 |
# $pArgs - Project specific options
|
|
|
995 |
#
|
|
|
996 |
########################################################################
|
|
|
997 |
|
|
|
998 |
my $project_defines_done = 0;
|
|
|
999 |
sub ToolsetPROJECT
|
|
|
1000 |
{
|
|
|
1001 |
my( $name, $solution ,$pArgs ) = @_;
|
|
|
1002 |
my $buildcmd = 'devenv =DSW= /build =TYPE= /useenv /out =LOG=';
|
|
|
1003 |
my $cleancmd = 'devenv =DSW= /clean =TYPE= /useenv';
|
| 343 |
dpurdie |
1004 |
my $release = 'RELEASE';
|
|
|
1005 |
my $debug = 'DEBUG';
|
| 227 |
dpurdie |
1006 |
|
|
|
1007 |
#
|
|
|
1008 |
# Process options
|
|
|
1009 |
#
|
|
|
1010 |
foreach ( @$pArgs ) {
|
| 343 |
dpurdie |
1011 |
if ( m/^--TargetProd*=(.+)/ ) {
|
|
|
1012 |
$release = $1;
|
|
|
1013 |
|
|
|
1014 |
} elsif ( m/^--TargetDebug=(.+)/ ) {
|
|
|
1015 |
$debug = $1;
|
|
|
1016 |
|
|
|
1017 |
} else {
|
|
|
1018 |
Message( "$toolset_name PROJECT: unknown option $_ -- ignored\n" );
|
|
|
1019 |
}
|
| 227 |
dpurdie |
1020 |
}
|
|
|
1021 |
|
|
|
1022 |
my ($io) = ToolsetPrinter::New();
|
|
|
1023 |
|
|
|
1024 |
#
|
| 343 |
dpurdie |
1025 |
# Setup toolset specific difinitions. Once
|
| 227 |
dpurdie |
1026 |
#
|
|
|
1027 |
unless( $project_defines_done )
|
|
|
1028 |
{
|
|
|
1029 |
$project_defines_done = 1;
|
| 343 |
dpurdie |
1030 |
$io->PrtLn( 'project_target = $(if $(findstring 1,$(DEBUG)),$2,$1)' );
|
| 227 |
dpurdie |
1031 |
$io->Newline();
|
|
|
1032 |
}
|
|
|
1033 |
|
|
|
1034 |
#
|
|
|
1035 |
# Process the build and clean commands
|
|
|
1036 |
# Substitute arguments
|
|
|
1037 |
# =TYPE=
|
|
|
1038 |
# =LOG=
|
|
|
1039 |
# =DSW=
|
|
|
1040 |
#
|
| 343 |
dpurdie |
1041 |
$buildcmd =~ s~=TYPE=~"\$(call project_target,$release,$debug)"~g;
|
| 227 |
dpurdie |
1042 |
$buildcmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;
|
|
|
1043 |
$buildcmd =~ s~=DSW=~$solution~g;
|
|
|
1044 |
|
| 343 |
dpurdie |
1045 |
$cleancmd =~ s~=TYPE=~"\$(call project_target,$release,$debug)"~g;
|
| 227 |
dpurdie |
1046 |
$cleancmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;
|
|
|
1047 |
$cleancmd =~ s~=DSW=~$solution~g;
|
|
|
1048 |
|
|
|
1049 |
#
|
|
|
1050 |
# Generate the recipe to create the project
|
|
|
1051 |
# Use the set_<PLATFORM>.sh file to extend the DLL search path
|
|
|
1052 |
#
|
|
|
1053 |
$io->Label( "Build project", $name );
|
|
|
1054 |
$io->PrtLn( "Project_$name: $solution \$(INTERFACEDIR)/set_$::ScmPlatform.sh" );
|
|
|
1055 |
|
|
|
1056 |
$io->PrtLn( "\t\$(XX_PRE)( \$(rm) -f $name\$(GBE_TYPE).log; \\" );
|
|
|
1057 |
$io->PrtLn( "\t. \$(INTERFACEDIR)/set_$::ScmPlatform.sh; \\" );
|
| 255 |
dpurdie |
1058 |
$io->PrtLn( "\t\$(show_environment); \\" );
|
| 227 |
dpurdie |
1059 |
$io->PrtLn( "\t$buildcmd; \\" );
|
|
|
1060 |
$io->PrtLn( "\tret=\$\$?; \\" );
|
|
|
1061 |
$io->PrtLn( "\t\$(GBE_BIN)/cat $name\$(GBE_TYPE).log; \\" );
|
|
|
1062 |
$io->PrtLn( "\texit \$\$ret )" );
|
|
|
1063 |
$io->Newline();
|
|
|
1064 |
|
|
|
1065 |
#
|
|
|
1066 |
# Generate the recipe to clean the project
|
|
|
1067 |
#
|
|
|
1068 |
$io->Label( "Clean project", $name );
|
|
|
1069 |
$io->PrtLn( "ProjectClean_$name: $solution" );
|
|
|
1070 |
$io->PrtLn( "\t-\$(XX_PRE)$cleancmd" );
|
|
|
1071 |
$io->PrtLn( "\t-\$(XX_PRE)\$(rm) -f $name\$(GBE_TYPE).log" );
|
|
|
1072 |
$io->Newline();
|
|
|
1073 |
|
|
|
1074 |
}
|
|
|
1075 |
|
|
|
1076 |
#-------------------------------------------------------------------------------
|
|
|
1077 |
# Function : ToolsetTESTFRAMEWORK_NUNIT
|
|
|
1078 |
#
|
|
|
1079 |
# Description : Toolset specfic support for the NUNIT Test FrameWork
|
|
|
1080 |
# Accessed with RunTest ('*', --FrameWork=nunit, ... );
|
|
|
1081 |
#
|
|
|
1082 |
# Manipulates the pEntry structure to allow JATS to
|
|
|
1083 |
# construct a test entry to run Nunit tests
|
|
|
1084 |
#
|
|
|
1085 |
# Inputs : $pEntry - Unit Test Hash
|
|
|
1086 |
#
|
|
|
1087 |
# Returns : Modified Hash
|
|
|
1088 |
#
|
|
|
1089 |
sub ToolsetTESTFRAMEWORK_NUNIT
|
|
|
1090 |
{
|
|
|
1091 |
my ($pEntry) = @_;
|
|
|
1092 |
my $test_dll_name;
|
|
|
1093 |
my @copy_dlls;
|
|
|
1094 |
my %copy_dll_flags;
|
|
|
1095 |
|
|
|
1096 |
#
|
|
|
1097 |
# Extract base name of DLL under test
|
|
|
1098 |
# Thsi will not have any extension.
|
|
|
1099 |
#
|
|
|
1100 |
$test_dll_name = $pEntry->{'prog'};
|
|
|
1101 |
Error ("Nunit Framework. No TestDLL specified") unless $test_dll_name;
|
|
|
1102 |
|
|
|
1103 |
#
|
|
|
1104 |
# Process the FrameWork Options
|
|
|
1105 |
#
|
|
|
1106 |
foreach ( @{$pEntry->{'framework_opts'}} )
|
|
|
1107 |
{
|
|
|
1108 |
if ( m/^--Uses=(.+)/ ) {
|
|
|
1109 |
my ($dll, @opts) = split (',', $1 );
|
|
|
1110 |
push @copy_dlls, $dll;
|
|
|
1111 |
foreach ( @opts )
|
|
|
1112 |
{
|
|
|
1113 |
if ( m~^--NonJats~i ) {
|
|
|
1114 |
$copy_dll_flags{$dll}{'NonJats'} = 1;
|
|
|
1115 |
} elsif ( m~--Jats~ ) {
|
|
|
1116 |
$copy_dll_flags{$dll}{'NonJats'} = 0;
|
|
|
1117 |
} else {
|
|
|
1118 |
Error ("Nunit Framework. Unknown sub option to --Uses: $_");
|
|
|
1119 |
}
|
|
|
1120 |
}
|
|
|
1121 |
} else {
|
|
|
1122 |
Error ("Nunit Framework. Unknown option: $_");
|
|
|
1123 |
}
|
|
|
1124 |
}
|
|
|
1125 |
|
|
|
1126 |
#
|
|
|
1127 |
# Locate the Nunit essentials
|
| 261 |
dpurdie |
1128 |
# This list may change with each version of nunit
|
|
|
1129 |
# Look for a known file and use its contents
|
|
|
1130 |
# Format:
|
|
|
1131 |
# One file name per line
|
|
|
1132 |
# Line comments only
|
|
|
1133 |
# Comment marker is a #
|
|
|
1134 |
# First one MUST be the executable
|
| 227 |
dpurdie |
1135 |
#
|
| 261 |
dpurdie |
1136 |
my @nunit_files;
|
| 227 |
dpurdie |
1137 |
|
| 261 |
dpurdie |
1138 |
my $mfile = 'nunit-jats-manifest.txt';
|
|
|
1139 |
my $nunit_file = ToolExtensionProgram ( $mfile );
|
|
|
1140 |
Error ("Cannot find Nunit Jats Manifest: $mfile") unless ( $nunit_file );
|
|
|
1141 |
open (JM, $nunit_file ) || Error( "Cannot open file: $nunit_file", "Reason: $!" );
|
|
|
1142 |
while ( <JM> )
|
|
|
1143 |
{
|
|
|
1144 |
s~\s+$~~; # Remove trailing white space
|
|
|
1145 |
s~^\s+~~; # Remove Leading whitespace
|
|
|
1146 |
next unless ( $_ ); # Skip block lines
|
|
|
1147 |
next if ( m~^#~ ); # Skip comments
|
|
|
1148 |
Verbose ("Nunit File: $_");
|
|
|
1149 |
push @nunit_files, $_;
|
|
|
1150 |
}
|
|
|
1151 |
close JM;
|
|
|
1152 |
|
|
|
1153 |
#
|
|
|
1154 |
# Locate all the required files
|
|
|
1155 |
# The first one will be the console executable
|
|
|
1156 |
#
|
| 227 |
dpurdie |
1157 |
my @nunit_framework;
|
|
|
1158 |
foreach my $file ( @nunit_files )
|
|
|
1159 |
{
|
|
|
1160 |
my $path = ToolExtensionProgram ($file );
|
|
|
1161 |
Error ("Cannot locate nunit file: $file") unless ( $path );
|
|
|
1162 |
push @nunit_framework, $path;
|
|
|
1163 |
}
|
| 261 |
dpurdie |
1164 |
my $nunit_console = $nunit_framework[0];
|
|
|
1165 |
Error ("Nunit console executable not specified") unless ( $nunit_console );
|
| 227 |
dpurdie |
1166 |
|
|
|
1167 |
#
|
|
|
1168 |
# Locate the test DLL.
|
|
|
1169 |
# This will be created locally within this makefile
|
|
|
1170 |
# It will be a known shared library
|
|
|
1171 |
#
|
|
|
1172 |
Errror( "TestDLL does not appear to be locally created: $test_dll_name" )
|
| 289 |
dpurdie |
1173 |
unless ( $::SHLIBS->Get($test_dll_name) );
|
| 227 |
dpurdie |
1174 |
|
|
|
1175 |
#
|
|
|
1176 |
# Hard bit. Determine the name/path of the DLL under test
|
|
|
1177 |
# It will have been created within this makefile
|
|
|
1178 |
# This is not a physical file.
|
|
|
1179 |
#
|
|
|
1180 |
$test_dll_name = $test_dll_name . '$(GBE_TYPE).' . $::so;
|
|
|
1181 |
my $test_dll = '$(LIBDIR)/' . $test_dll_name;
|
|
|
1182 |
|
|
|
1183 |
#
|
|
|
1184 |
# Other hard bit
|
|
|
1185 |
# Locate the other dll's needed by this test
|
|
|
1186 |
# Need to use P in production and D in Debug unless otherwise specified
|
|
|
1187 |
# These might be in:
|
|
|
1188 |
# an external package
|
|
|
1189 |
# within the local directory
|
|
|
1190 |
# the current makefile
|
|
|
1191 |
# ie: We can only determine the location of the files at run-time
|
|
|
1192 |
#
|
|
|
1193 |
# The mechanism used is:
|
|
|
1194 |
# Create makefile recipe entries to
|
|
|
1195 |
# Use cmdfile to create a command file with copy command
|
|
|
1196 |
# Execute the command file
|
|
|
1197 |
#
|
|
|
1198 |
# Complications include:
|
|
|
1199 |
# The windows shell used does not honour 'set -e', so we need to
|
|
|
1200 |
# detect error conditions ourselves
|
|
|
1201 |
#
|
|
|
1202 |
my $ofile = "\$(TESTDIR)/$pEntry->{test_name}.cmd";
|
|
|
1203 |
push @{$pEntry->{'ShellRecipe'}}, "rm -f $ofile";
|
|
|
1204 |
|
|
|
1205 |
my @cmds;
|
| 363 |
dpurdie |
1206 |
push @cmds, "\$(cmdfile) -wk1W1o$ofile";
|
| 227 |
dpurdie |
1207 |
foreach my $dll ( @copy_dlls )
|
|
|
1208 |
{
|
|
|
1209 |
#
|
|
|
1210 |
# Generate in-line commands to locate and copy in the required
|
|
|
1211 |
# DLL's. The 'cmdfile' utility can be used to do this at runtime
|
|
|
1212 |
#
|
|
|
1213 |
my $dll_name = $dll;
|
|
|
1214 |
$dll_name .= '$(GBE_TYPE)' unless ( $copy_dll_flags{$dll}{'NonJats'} );
|
|
|
1215 |
|
| 363 |
dpurdie |
1216 |
push @cmds, '"' . "cp -f @(vglob2,$dll_name.$::so,PATH,/) \$(TESTDIR) || exit 98" . '\n"';
|
| 227 |
dpurdie |
1217 |
}
|
|
|
1218 |
push @cmds, "|| exit 99";
|
|
|
1219 |
push @{$pEntry->{'ShellRecipe'}}, \@cmds;
|
|
|
1220 |
push @{$pEntry->{'ShellRecipe'}}, ". $ofile";
|
|
|
1221 |
|
|
|
1222 |
|
|
|
1223 |
#
|
|
|
1224 |
# Add items to the Unit Test Hash
|
|
|
1225 |
# command - command to execute to run the test program
|
|
|
1226 |
# prog - test command/script that must be in the test dir
|
|
|
1227 |
# copyprog - Prog must be copied in
|
|
|
1228 |
# args - Arguments to the test
|
|
|
1229 |
# copyin - Array of files to copy into the test directory
|
|
|
1230 |
# copyonce - Array of files to copy only once
|
|
|
1231 |
# prereq - Prerequiste conditions
|
|
|
1232 |
# testdir - Symbolic name of the test directory
|
|
|
1233 |
# ShellRecipe - Recipe Bits to add
|
|
|
1234 |
#
|
|
|
1235 |
$pEntry->{'command'} = $nunit_console . ' ' . $test_dll_name;
|
|
|
1236 |
unshift @{$pEntry->{args}}, "/xml=$pEntry->{test_name}.xml";
|
|
|
1237 |
$pEntry->{'prog'} = $test_dll_name;
|
|
|
1238 |
$pEntry->{'copyprog'} = 0;
|
|
|
1239 |
push @{$pEntry->{'copyin'}}, $test_dll;
|
| 261 |
dpurdie |
1240 |
push @{$pEntry->{'copyonce'}}, @nunit_framework;
|
| 227 |
dpurdie |
1241 |
$pEntry->{'testdir'} = 'TESTDIR';
|
|
|
1242 |
|
|
|
1243 |
#
|
|
|
1244 |
# Create the Test Directory
|
|
|
1245 |
# Tests will be done in a .NUNIT subdir
|
|
|
1246 |
#
|
|
|
1247 |
MkdirRule( "\$(TESTDIR)", 'TESTDIR', '--Path=$(GBE_PLATFORM)$(GBE_TYPE).NUNIT', '--RemoveAll' );
|
|
|
1248 |
|
|
|
1249 |
#
|
|
|
1250 |
# Files created by the Unit Test
|
|
|
1251 |
#
|
|
|
1252 |
ToolsetGenerate ( "\$(TESTDIR)/$pEntry->{test_name}.xml" );
|
|
|
1253 |
ToolsetGenerate ( $ofile );
|
|
|
1254 |
|
|
|
1255 |
}
|
|
|
1256 |
|
|
|
1257 |
#.. Successful termination
|
|
|
1258 |
1;
|
|
|
1259 |
|