1--
2-- tests/test_msc.lua
3-- Automated test suite for the Microsoft C toolset interface.
4-- Copyright (c) 2012-2013 Jason Perkins and the Premake project
5--
6
7	local p = premake
8	local suite = test.declare("tools_msc")
9
10	local msc = p.tools.msc
11
12
13--
14-- Setup/teardown
15--
16
17	local wks, prj, cfg
18
19	function suite.setup()
20		wks, prj = test.createWorkspace()
21		kind "SharedLib"
22	end
23
24	local function prepare()
25		cfg = test.getconfig(prj, "Debug")
26	end
27
28
29--
30-- Check the optimization flags.
31--
32
33	function suite.cflags_onNoOptimize()
34		optimize "Off"
35		prepare()
36		test.contains("/Od", msc.getcflags(cfg))
37	end
38
39	function suite.cflags_onOptimize()
40		optimize "On"
41		prepare()
42		test.contains("/Ot", msc.getcflags(cfg))
43	end
44
45	function suite.cflags_onOptimizeSize()
46		optimize "Size"
47		prepare()
48		test.contains("/O1", msc.getcflags(cfg))
49	end
50
51	function suite.cflags_onOptimizeSpeed()
52		optimize "Speed"
53		prepare()
54		test.contains("/O2", msc.getcflags(cfg))
55	end
56
57	function suite.cflags_onOptimizeFull()
58		optimize "Full"
59		prepare()
60		test.contains("/Ox", msc.getcflags(cfg))
61	end
62
63	function suite.cflags_onOptimizeDebug()
64		optimize "Debug"
65		prepare()
66		test.contains("/Od", msc.getcflags(cfg))
67	end
68
69	function suite.cflags_onNoFramePointers()
70		flags "NoFramePointer"
71		prepare()
72		test.contains("/Oy", msc.getcflags(cfg))
73	end
74
75	function suite.ldflags_onLinkTimeOptimizations()
76		flags "LinkTimeOptimization"
77		prepare()
78		test.contains("/GL", msc.getldflags(cfg))
79	end
80
81	function suite.cflags_onStringPoolingOn()
82		stringpooling "On"
83		prepare()
84		test.contains("/GF", msc.getcflags(cfg))
85	end
86
87	function suite.cflags_onStringPoolingOff()
88		stringpooling "Off"
89		prepare()
90		test.contains("/GF-", msc.getcflags(cfg))
91	end
92
93	function suite.cflags_onStringPoolingNotSpecified()
94		prepare()
95		test.excludes("/GF", msc.getcflags(cfg))
96		test.excludes("/GF-", msc.getcflags(cfg))
97	end
98
99	function suite.cflags_onFloatingPointExceptionsOn()
100		floatingpointexceptions "On"
101		prepare()
102		test.contains("/fp:except", msc.getcflags(cfg))
103	end
104
105	function suite.cflags_onFloatingPointExceptionsOff()
106		floatingpointexceptions "Off"
107		prepare()
108		test.contains("/fp:except-", msc.getcflags(cfg))
109	end
110
111	function suite.cflags_onFloatingPointExceptionsNotSpecified()
112		prepare()
113		test.excludes("/fp:except", msc.getcflags(cfg))
114		test.excludes("/fp:except-", msc.getcflags(cfg))
115	end
116
117	function suite.cflags_onFunctionLevelLinkingOn()
118		functionlevellinking "On"
119		prepare()
120		test.contains("/Gy", msc.getcflags(cfg))
121	end
122
123	function suite.cflags_onFunctionLevelLinkingOff()
124		functionlevellinking "Off"
125		prepare()
126		test.contains("/Gy-", msc.getcflags(cfg))
127	end
128
129	function suite.cflags_onFunctionLevelLinkingNotSpecified()
130		prepare()
131		test.excludes("/Gy", msc.getcflags(cfg))
132		test.excludes("/Gy-", msc.getcflags(cfg))
133	end
134
135	function suite.cflags_onIntrinsicsOn()
136		intrinsics "On"
137		prepare()
138		test.contains("/Oi", msc.getcflags(cfg))
139	end
140
141--
142-- Check the translation of symbols.
143--
144
145	function suite.cflags_onDefaultSymbols()
146		prepare()
147		test.excludes({ "/Z7" }, msc.getcflags(cfg))
148	end
149
150	function suite.cflags_onNoSymbols()
151		symbols "Off"
152		prepare()
153		test.excludes({ "/Z7" }, msc.getcflags(cfg))
154	end
155
156	function suite.cflags_onSymbols()
157		symbols "On"
158		prepare()
159		test.contains({ "/Z7" }, msc.getcflags(cfg))
160	end
161
162
163--
164-- Check handling of debugging support.
165--
166
167	function suite.ldflags_onSymbols()
168		symbols "On"
169		prepare()
170		test.contains("/DEBUG", msc.getldflags(cfg))
171	end
172
173
174--
175-- Check handling warnings and errors.
176--
177
178	function suite.cflags_OnNoWarnings()
179		warnings "Off"
180		prepare()
181		test.contains("/W0", msc.getcflags(cfg))
182	end
183
184	function suite.cflags_OnHighWarnings()
185		warnings "High"
186		prepare()
187		test.contains("/W4", msc.getcflags(cfg))
188	end
189
190	function suite.cflags_OnExtraWarnings()
191		warnings "Extra"
192		prepare()
193		test.contains("/W4", msc.getcflags(cfg))
194	end
195
196	function suite.cflags_OnFatalWarnings()
197		flags "FatalWarnings"
198		prepare()
199		test.contains("/WX", msc.getcflags(cfg))
200	end
201
202	function suite.cflags_onSpecificWarnings()
203		enablewarnings { "enable" }
204		disablewarnings { "disable" }
205		fatalwarnings { "fatal" }
206		prepare()
207		test.contains({ '/wd"disable"', '/we"fatal"' }, msc.getcflags(cfg))
208	end
209
210	function suite.ldflags_OnFatalWarnings()
211		flags "FatalWarnings"
212		prepare()
213		test.contains("/WX", msc.getldflags(cfg))
214	end
215
216
217--
218-- Check handling of library search paths.
219--
220
221	function suite.libdirs_onLibdirs()
222		libdirs { "../libs" }
223		prepare()
224		test.contains('/LIBPATH:"../libs"', msc.getLibraryDirectories(cfg))
225	end
226
227
228--
229-- Check handling of forced includes.
230--
231
232	function suite.forcedIncludeFiles()
233		forceincludes { "include/sys.h" }
234		prepare()
235		test.contains('/FIinclude/sys.h', msc.getforceincludes(cfg))
236	end
237
238
239--
240-- Check handling of floating point modifiers.
241--
242
243	function suite.cflags_onFloatingPointFast()
244		floatingpoint "Fast"
245		prepare()
246		test.contains("/fp:fast", msc.getcflags(cfg))
247	end
248
249	function suite.cflags_onFloatingPointStrict()
250		floatingpoint "Strict"
251		prepare()
252		test.contains("/fp:strict", msc.getcflags(cfg))
253	end
254
255	function suite.cflags_onSSE()
256		vectorextensions "SSE"
257		prepare()
258		test.contains("/arch:SSE", msc.getcflags(cfg))
259	end
260
261	function suite.cflags_onSSE2()
262		vectorextensions "SSE2"
263		prepare()
264		test.contains("/arch:SSE2", msc.getcflags(cfg))
265	end
266
267	function suite.cflags_onAVX()
268		vectorextensions "AVX"
269		prepare()
270		test.contains("/arch:AVX", msc.getcflags(cfg))
271	end
272
273	function suite.cflags_onAVX2()
274		vectorextensions "AVX2"
275		prepare()
276		test.contains("/arch:AVX2", msc.getcflags(cfg))
277	end
278
279
280--
281-- Check the defines and undefines.
282--
283
284	function suite.defines()
285		defines "DEF"
286		prepare()
287		test.contains({ '/D"DEF"' }, msc.getdefines(cfg.defines, cfg))
288	end
289
290	function suite.undefines()
291		undefines "UNDEF"
292		prepare()
293		test.contains({ '/U"UNDEF"' }, msc.getundefines(cfg.undefines))
294	end
295
296
297--
298-- Check compilation options.
299--
300
301	function suite.cflags_onNoMinimalRebuild()
302		flags "NoMinimalRebuild"
303		prepare()
304		test.contains("/Gm-", msc.getcflags(cfg))
305	end
306
307	function suite.cflags_onMultiProcessorCompile()
308		flags "MultiProcessorCompile"
309		prepare()
310		test.contains("/MP", msc.getcflags(cfg))
311	end
312
313
314--
315-- Check handling of C++ language features.
316--
317
318	function suite.cxxflags_onExceptions()
319		exceptionhandling "on"
320		prepare()
321		test.contains("/EHsc", msc.getcxxflags(cfg))
322	end
323
324	function suite.cxxflags_onSEH()
325		exceptionhandling "SEH"
326		prepare()
327		test.contains("/EHa", msc.getcxxflags(cfg))
328	end
329
330	function suite.cxxflags_onNoExceptions()
331		exceptionhandling "Off"
332		prepare()
333		test.missing("/EHsc", msc.getcxxflags(cfg))
334	end
335
336	function suite.cxxflags_onNoRTTI()
337		rtti "Off"
338		prepare()
339		test.contains("/GR-", msc.getcxxflags(cfg))
340	end
341
342
343--
344-- Check handling of additional linker options.
345--
346
347	function suite.ldflags_onOmitDefaultLibrary()
348		flags "OmitDefaultLibrary"
349		prepare()
350		test.contains("/NODEFAULTLIB", msc.getldflags(cfg))
351	end
352
353	function suite.ldflags_onNoIncrementalLink()
354		flags "NoIncrementalLink"
355		prepare()
356		test.contains("/INCREMENTAL:NO", msc.getldflags(cfg))
357	end
358
359	function suite.ldflags_onNoManifest()
360		flags "NoManifest"
361		prepare()
362		test.contains("/MANIFEST:NO", msc.getldflags(cfg))
363	end
364
365	function suite.ldflags_onDLL()
366		kind "SharedLib"
367		prepare()
368		test.contains("/DLL", msc.getldflags(cfg))
369	end
370
371
372
373--
374-- Check handling of CLR settings.
375--
376
377	function suite.cflags_onClrOn()
378		clr "On"
379		prepare()
380		test.contains("/clr", msc.getcflags(cfg))
381	end
382
383	function suite.cflags_onClrUnsafe()
384		clr "Unsafe"
385		prepare()
386		test.contains("/clr", msc.getcflags(cfg))
387	end
388
389	function suite.cflags_onClrSafe()
390		clr "Safe"
391		prepare()
392		test.contains("/clr:safe", msc.getcflags(cfg))
393	end
394
395	function suite.cflags_onClrPure()
396		clr "Pure"
397		prepare()
398		test.contains("/clr:pure", msc.getcflags(cfg))
399	end
400
401
402--
403-- Check handling of character set switches
404--
405
406	function suite.cflags_onCharSetDefault()
407		prepare()
408		test.contains('/D"_UNICODE"', msc.getdefines(cfg.defines, cfg))
409	end
410
411	function suite.cflags_onCharSetUnicode()
412		characterset "Unicode"
413		prepare()
414		test.contains('/D"_UNICODE"', msc.getdefines(cfg.defines, cfg))
415	end
416
417	function suite.cflags_onCharSetMBCS()
418		characterset "MBCS"
419		prepare()
420		test.contains('/D"_MBCS"', msc.getdefines(cfg.defines, cfg))
421	end
422
423	function suite.cflags_onCharSetASCII()
424		characterset "ASCII"
425		prepare()
426		test.excludes({'/D"_MBCS"', '/D"_UNICODE"'}, msc.getdefines(cfg.defines, cfg))
427	end
428
429
430--
431-- Check handling of system search paths.
432--
433
434	function suite.includeDirs_onSysIncludeDirs()
435		sysincludedirs { "/usr/local/include" }
436		prepare()
437		test.contains("-I/usr/local/include", msc.getincludedirs(cfg, cfg.includedirs, cfg.sysincludedirs))
438	end
439
440	function suite.libDirs_onSysLibDirs()
441		syslibdirs { "/usr/local/lib" }
442		prepare()
443		test.contains('/LIBPATH:"/usr/local/lib"', msc.getLibraryDirectories(cfg))
444	end
445
446--
447-- Check handling of ignore default libraries
448--
449
450	function suite.ignoreDefaultLibraries_WithExtensions()
451		ignoredefaultlibraries { "lib1.lib" }
452		prepare()
453		test.contains('/NODEFAULTLIB:lib1.lib', msc.getldflags(cfg))
454	end
455
456	function suite.ignoreDefaultLibraries_WithoutExtensions()
457		ignoredefaultlibraries { "lib1" }
458		prepare()
459		test.contains('/NODEFAULTLIB:lib1.lib', msc.getldflags(cfg))
460	end
461
462
463--
464-- Check handling of shared C/C++ flags.
465--
466
467	function suite.mixedToolFlags_onCFlags()
468		flags { "FatalCompileWarnings" }
469		prepare()
470		test.isequal({ "/WX", "/MD" }, msc.getcflags(cfg))
471	end
472
473	function suite.mixedToolFlags_onCxxFlags()
474		flags { "FatalCompileWarnings" }
475		prepare()
476		test.isequal({ "/WX", "/MD", "/EHsc" }, msc.getcxxflags(cfg))
477	end
478