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.cflags_onOmitFramePointer()
76		omitframepointer "On"
77		prepare()
78		test.contains("/Oy", msc.getcflags(cfg))
79	end
80
81	function suite.cflags_onNoOmitFramePointers()
82		omitframepointer "Off"
83		prepare()
84		test.excludes("/Oy", msc.getcflags(cfg))
85	end
86
87	function suite.cflags_onLinkTimeOptimizations()
88		flags "LinkTimeOptimization"
89		prepare()
90		test.contains("/GL", msc.getcflags(cfg))
91	end
92
93	function suite.ldflags_onLinkTimeOptimizations()
94		flags "LinkTimeOptimization"
95		prepare()
96		test.contains("/LTCG", msc.getldflags(cfg))
97	end
98
99	function suite.cflags_onStringPoolingOn()
100		stringpooling "On"
101		prepare()
102		test.contains("/GF", msc.getcflags(cfg))
103	end
104
105	function suite.cflags_onStringPoolingOff()
106		stringpooling "Off"
107		prepare()
108		test.contains("/GF-", msc.getcflags(cfg))
109	end
110
111	function suite.cflags_onStringPoolingNotSpecified()
112		prepare()
113		test.excludes("/GF", msc.getcflags(cfg))
114		test.excludes("/GF-", msc.getcflags(cfg))
115	end
116
117	function suite.cflags_onFloatingPointExceptionsOn()
118		floatingpointexceptions "On"
119		prepare()
120		test.contains("/fp:except", msc.getcflags(cfg))
121	end
122
123	function suite.cflags_onFloatingPointExceptionsOff()
124		floatingpointexceptions "Off"
125		prepare()
126		test.contains("/fp:except-", msc.getcflags(cfg))
127	end
128
129	function suite.cflags_onFloatingPointExceptionsNotSpecified()
130		prepare()
131		test.excludes("/fp:except", msc.getcflags(cfg))
132		test.excludes("/fp:except-", msc.getcflags(cfg))
133	end
134
135	function suite.cflags_onFunctionLevelLinkingOn()
136		functionlevellinking "On"
137		prepare()
138		test.contains("/Gy", msc.getcflags(cfg))
139	end
140
141	function suite.cflags_onFunctionLevelLinkingOff()
142		functionlevellinking "Off"
143		prepare()
144		test.contains("/Gy-", msc.getcflags(cfg))
145	end
146
147	function suite.cflags_onFunctionLevelLinkingNotSpecified()
148		prepare()
149		test.excludes("/Gy", msc.getcflags(cfg))
150		test.excludes("/Gy-", msc.getcflags(cfg))
151	end
152
153	function suite.cflags_onIntrinsicsOn()
154		intrinsics "On"
155		prepare()
156		test.contains("/Oi", msc.getcflags(cfg))
157	end
158
159--
160-- Check the translation of symbols.
161--
162
163	function suite.cflags_onDefaultSymbols()
164		prepare()
165		test.excludes({ "/Z7" }, msc.getcflags(cfg))
166	end
167
168	function suite.cflags_onNoSymbols()
169		symbols "Off"
170		prepare()
171		test.excludes({ "/Z7" }, msc.getcflags(cfg))
172	end
173
174	function suite.cflags_onSymbols()
175		symbols "On"
176		prepare()
177		test.contains({ "/Z7" }, msc.getcflags(cfg))
178	end
179
180
181--
182-- Check the translation of unsignedchar.
183--
184
185	function suite.sharedflags_onUnsignedCharOn()
186		unsignedchar "On"
187		prepare()
188		test.contains({ "/J" }, msc.getcflags(cfg))
189		test.contains({ "/J" }, msc.getcxxflags(cfg))
190	end
191
192	function suite.sharedflags_onUnsignedCharOff()
193		unsignedchar "Off"
194		prepare()
195		test.excludes({ "/J" }, msc.getcflags(cfg))
196		test.excludes({ "/J" }, msc.getcxxflags(cfg))
197	end
198
199
200--
201-- Check handling of debugging support.
202--
203
204	function suite.ldflags_onSymbols()
205		symbols "On"
206		prepare()
207		test.contains("/DEBUG", msc.getldflags(cfg))
208	end
209
210
211--
212-- Check handling warnings and errors.
213--
214
215	function suite.cflags_OnNoWarnings()
216		warnings "Off"
217		prepare()
218		test.contains("/W0", msc.getcflags(cfg))
219	end
220
221	function suite.cflags_OnHighWarnings()
222		warnings "High"
223		prepare()
224		test.contains("/W4", msc.getcflags(cfg))
225	end
226
227	function suite.cflags_OnExtraWarnings()
228		warnings "Extra"
229		prepare()
230		test.contains("/W4", msc.getcflags(cfg))
231	end
232
233	function suite.cflags_OnEverythingWarnings()
234		warnings "Everything"
235		prepare()
236		test.contains("/Wall", msc.getcflags(cfg))
237	end
238
239	function suite.cflags_OnFatalWarnings()
240		flags "FatalWarnings"
241		prepare()
242		test.contains("/WX", msc.getcflags(cfg))
243	end
244
245	function suite.cflags_onSpecificWarnings()
246		enablewarnings { "enable" }
247		disablewarnings { "disable" }
248		fatalwarnings { "fatal" }
249		prepare()
250		test.contains({ '/w1"enable"', '/wd"disable"', '/we"fatal"' }, msc.getcflags(cfg))
251	end
252
253	function suite.ldflags_OnFatalWarnings()
254		flags "FatalWarnings"
255		prepare()
256		test.contains("/WX", msc.getldflags(cfg))
257	end
258
259
260--
261-- Check handling of library search paths.
262--
263
264	function suite.libdirs_onLibdirs()
265		libdirs { "../libs" }
266		prepare()
267		test.contains('/LIBPATH:"../libs"', msc.getLibraryDirectories(cfg))
268	end
269
270
271--
272-- Check handling of forced includes.
273--
274
275	function suite.forcedIncludeFiles()
276		forceincludes { "include/sys.h" }
277		prepare()
278		test.contains('/FIinclude/sys.h', msc.getforceincludes(cfg))
279	end
280
281
282--
283-- Check handling of floating point modifiers.
284--
285
286	function suite.cflags_onFloatingPointFast()
287		floatingpoint "Fast"
288		prepare()
289		test.contains("/fp:fast", msc.getcflags(cfg))
290	end
291
292	function suite.cflags_onFloatingPointStrict()
293		floatingpoint "Strict"
294		prepare()
295		test.contains("/fp:strict", msc.getcflags(cfg))
296	end
297
298	function suite.cflags_onSSE()
299		vectorextensions "SSE"
300		prepare()
301		test.contains("/arch:SSE", msc.getcflags(cfg))
302	end
303
304	function suite.cflags_onSSE2()
305		vectorextensions "SSE2"
306		prepare()
307		test.contains("/arch:SSE2", msc.getcflags(cfg))
308	end
309
310	function suite.cflags_onAVX()
311		vectorextensions "AVX"
312		prepare()
313		test.contains("/arch:AVX", msc.getcflags(cfg))
314	end
315
316	function suite.cflags_onAVX2()
317		vectorextensions "AVX2"
318		prepare()
319		test.contains("/arch:AVX2", msc.getcflags(cfg))
320	end
321
322
323--
324-- Check the defines and undefines.
325--
326
327	function suite.defines()
328		defines "DEF"
329		prepare()
330		test.contains({ '/D"DEF"' }, msc.getdefines(cfg.defines, cfg))
331	end
332
333	function suite.undefines()
334		undefines "UNDEF"
335		prepare()
336		test.contains({ '/U"UNDEF"' }, msc.getundefines(cfg.undefines))
337	end
338
339
340--
341-- Check compilation options.
342--
343
344	function suite.cflags_onNoMinimalRebuild()
345		flags "NoMinimalRebuild"
346		prepare()
347		test.contains("/Gm-", msc.getcflags(cfg))
348	end
349
350	function suite.cflags_onMultiProcessorCompile()
351		flags "MultiProcessorCompile"
352		prepare()
353		test.contains("/MP", msc.getcflags(cfg))
354	end
355
356
357--
358-- Check handling of C++ language features.
359--
360
361	function suite.cxxflags_onExceptions()
362		exceptionhandling "on"
363		prepare()
364		test.contains("/EHsc", msc.getcxxflags(cfg))
365	end
366
367	function suite.cxxflags_onSEH()
368		exceptionhandling "SEH"
369		prepare()
370		test.contains("/EHa", msc.getcxxflags(cfg))
371	end
372
373	function suite.cxxflags_onNoExceptions()
374		exceptionhandling "Off"
375		prepare()
376		test.missing("/EHsc", msc.getcxxflags(cfg))
377	end
378
379	function suite.cxxflags_onNoRTTI()
380		rtti "Off"
381		prepare()
382		test.contains("/GR-", msc.getcxxflags(cfg))
383	end
384
385
386--
387-- Check handling of additional linker options.
388--
389
390	function suite.ldflags_onOmitDefaultLibrary()
391		flags "OmitDefaultLibrary"
392		prepare()
393		test.contains("/NODEFAULTLIB", msc.getldflags(cfg))
394	end
395
396	function suite.ldflags_onNoIncrementalLink()
397		flags "NoIncrementalLink"
398		prepare()
399		test.contains("/INCREMENTAL:NO", msc.getldflags(cfg))
400	end
401
402	function suite.ldflags_onNoManifest()
403		flags "NoManifest"
404		prepare()
405		test.contains("/MANIFEST:NO", msc.getldflags(cfg))
406	end
407
408	function suite.ldflags_onDLL()
409		kind "SharedLib"
410		prepare()
411		test.contains("/DLL", msc.getldflags(cfg))
412	end
413
414
415
416--
417-- Check handling of CLR settings.
418--
419
420	function suite.cflags_onClrOn()
421		clr "On"
422		prepare()
423		test.contains("/clr", msc.getcflags(cfg))
424	end
425
426	function suite.cflags_onClrUnsafe()
427		clr "Unsafe"
428		prepare()
429		test.contains("/clr", msc.getcflags(cfg))
430	end
431
432	function suite.cflags_onClrSafe()
433		clr "Safe"
434		prepare()
435		test.contains("/clr:safe", msc.getcflags(cfg))
436	end
437
438	function suite.cflags_onClrPure()
439		clr "Pure"
440		prepare()
441		test.contains("/clr:pure", msc.getcflags(cfg))
442	end
443
444
445--
446-- Check handling of character set switches
447--
448
449	function suite.cflags_onCharSetDefault()
450		prepare()
451		test.contains('/D"_UNICODE"', msc.getdefines(cfg.defines, cfg))
452	end
453
454	function suite.cflags_onCharSetUnicode()
455		characterset "Unicode"
456		prepare()
457		test.contains('/D"_UNICODE"', msc.getdefines(cfg.defines, cfg))
458	end
459
460	function suite.cflags_onCharSetMBCS()
461		characterset "MBCS"
462		prepare()
463		test.contains('/D"_MBCS"', msc.getdefines(cfg.defines, cfg))
464	end
465
466	function suite.cflags_onCharSetASCII()
467		characterset "ASCII"
468		prepare()
469		test.excludes({'/D"_MBCS"', '/D"_UNICODE"'}, msc.getdefines(cfg.defines, cfg))
470	end
471
472
473--
474-- Check handling of system search paths.
475--
476
477	function suite.includeDirs_onSysIncludeDirs()
478		sysincludedirs { "/usr/local/include" }
479		prepare()
480		test.contains("-I/usr/local/include", msc.getincludedirs(cfg, cfg.includedirs, cfg.sysincludedirs))
481	end
482
483	function suite.libDirs_onSysLibDirs()
484		syslibdirs { "/usr/local/lib" }
485		prepare()
486		test.contains('/LIBPATH:"/usr/local/lib"', msc.getLibraryDirectories(cfg))
487	end
488
489--
490-- Check handling of ignore default libraries
491--
492
493	function suite.ignoreDefaultLibraries_WithExtensions()
494		ignoredefaultlibraries { "lib1.lib" }
495		prepare()
496		test.contains('/NODEFAULTLIB:lib1.lib', msc.getldflags(cfg))
497	end
498
499	function suite.ignoreDefaultLibraries_WithoutExtensions()
500		ignoredefaultlibraries { "lib1" }
501		prepare()
502		test.contains('/NODEFAULTLIB:lib1.lib', msc.getldflags(cfg))
503	end
504
505
506--
507-- Check handling of shared C/C++ flags.
508--
509
510	function suite.mixedToolFlags_onCFlags()
511		flags { "FatalCompileWarnings" }
512		prepare()
513		test.isequal({ "/WX", "/MD" }, msc.getcflags(cfg))
514	end
515
516	function suite.mixedToolFlags_onCxxFlags()
517		flags { "FatalCompileWarnings" }
518		prepare()
519		test.isequal({ "/WX", "/MD", "/EHsc" }, msc.getcxxflags(cfg))
520	end
521
522
523	--
524	-- Check handling of Run-Time Library flags.
525	--
526
527	function suite.cflags_onStaticRuntime()
528		staticruntime "On"
529		prepare()
530		test.isequal({ "/MT" }, msc.getcflags(cfg))
531	end
532
533	function suite.cflags_onDynamicRuntime()
534		staticruntime "Off"
535		prepare()
536		test.isequal({ "/MD" }, msc.getcflags(cfg))
537	end
538
539	function suite.cflags_onStaticRuntimeAndDebug()
540		staticruntime "On"
541		runtime "Debug"
542		prepare()
543		test.isequal({ "/MTd" }, msc.getcflags(cfg))
544	end
545
546	function suite.cflags_onDynamicRuntimeAndDebug()
547		staticruntime "Off"
548		runtime "Debug"
549		prepare()
550		test.isequal({ "/MDd" }, msc.getcflags(cfg))
551	end
552
553	function suite.cflags_onStaticRuntimeAndSymbols()
554		staticruntime "On"
555		symbols "On"
556		prepare()
557		test.isequal({ "/MTd", "/Z7" }, msc.getcflags(cfg))
558	end
559
560	function suite.cflags_onDynamicRuntimeAndSymbols()
561		staticruntime "Off"
562		symbols "On"
563		prepare()
564		test.isequal({ "/MDd", "/Z7" }, msc.getcflags(cfg))
565	end
566
567	function suite.cflags_onDynamicRuntimeAndReleaseAndSymbols()
568		staticruntime "Off"
569		runtime "Release"
570		symbols "On"
571		prepare()
572		test.isequal({ "/MD", "/Z7" }, msc.getcflags(cfg))
573	end
574