1--
2-- tests/actions/vstudio/vc2010/test_link.lua
3-- Validate linking and project references in Visual Studio 2010 C/C++ projects.
4-- Copyright (c) 2011-2013 Jason Perkins and the Premake project
5--
6
7	local p = premake
8	local suite = test.declare("vs2010_link")
9	local vc2010 = p.vstudio.vc2010
10	local project = p.project
11
12
13--
14-- Setup
15--
16
17	local wks, prj
18
19	function suite.setup()
20		p.action.set("vs2010")
21		wks, prj = test.createWorkspace()
22		kind "SharedLib"
23	end
24
25	local function prepare(platform)
26		local cfg = test.getconfig(prj, "Debug", platform)
27		vc2010.linker(cfg)
28	end
29
30
31--
32-- Check the basic element structure with default settings.
33--
34
35	function suite.defaultSettings()
36		kind "SharedLib"
37		prepare()
38		test.capture [[
39<Link>
40	<SubSystem>Windows</SubSystem>
41	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
42</Link>
43		]]
44	end
45
46
47--
48-- Check the basic element structure with a release build.
49--
50
51	function suite.defaultSettings_onOptimize()
52		optimize "On"
53		prepare()
54		test.capture [[
55<Link>
56	<SubSystem>Windows</SubSystem>
57	<EnableCOMDATFolding>true</EnableCOMDATFolding>
58	<OptimizeReferences>true</OptimizeReferences>
59	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
60</Link>
61		]]
62	end
63
64
65--
66-- Check subsystem values with each project kind.
67--
68
69	function suite.subsystem_onConsoleApp()
70		kind "ConsoleApp"
71		prepare()
72		test.capture [[
73<Link>
74	<SubSystem>Console</SubSystem>
75		]]
76	end
77
78	function suite.subsystem_onWindowedApp()
79		kind "WindowedApp"
80		prepare()
81		test.capture [[
82<Link>
83	<SubSystem>Windows</SubSystem>
84		]]
85	end
86
87	function suite.subsystem_onSharedLib()
88		kind "SharedLib"
89		prepare()
90		test.capture [[
91<Link>
92	<SubSystem>Windows</SubSystem>
93	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
94</Link>
95		]]
96	end
97
98	function suite.subsystem_onStaticLib()
99		kind "StaticLib"
100		prepare()
101		test.capture [[
102<Link>
103	<SubSystem>Windows</SubSystem>
104</Link>
105		]]
106	end
107
108
109--
110-- Test the handling of the entrypoint API.
111--
112	function suite.onEntryPoint()
113		kind "ConsoleApp"
114		entrypoint "foobar"
115		prepare()
116		test.capture [[
117<Link>
118	<SubSystem>Console</SubSystem>
119	<EntryPointSymbol>foobar</EntryPointSymbol>
120</Link>
121		]]
122	end
123
124
125--
126-- Test the handling of the NoImplicitLink flag.
127--
128
129	function suite.linkDependencies_onNoImplicitLink()
130		flags "NoImplicitLink"
131		prepare()
132		test.capture [[
133<Link>
134	<SubSystem>Windows</SubSystem>
135	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
136</Link>
137<ProjectReference>
138	<LinkLibraryDependencies>false</LinkLibraryDependencies>
139</ProjectReference>
140		]]
141	end
142
143--
144-- Test the handling of the Symbols flag.
145--
146
147	function suite.generateDebugInfo_onSymbolsOn_on2010()
148		p.action.set("vs2010")
149		symbols "On"
150		prepare()
151		test.capture [[
152<Link>
153	<SubSystem>Windows</SubSystem>
154	<GenerateDebugInformation>true</GenerateDebugInformation>
155		]]
156	end
157
158	function suite.generateDebugInfo_onSymbolsFastLink_on2010()
159		p.action.set("vs2010")
160		symbols "FastLink"
161		prepare()
162		test.capture [[
163<Link>
164	<SubSystem>Windows</SubSystem>
165	<GenerateDebugInformation>true</GenerateDebugInformation>
166		]]
167	end
168
169	function suite.generateDebugInfo_onSymbolsFull_on2010()
170		p.action.set("vs2010")
171		symbols "Full"
172		prepare()
173		test.capture [[
174<Link>
175	<SubSystem>Windows</SubSystem>
176	<GenerateDebugInformation>true</GenerateDebugInformation>
177		]]
178	end
179
180	function suite.generateDebugInfo_onSymbolsOn_on2015()
181		p.action.set("vs2015")
182		symbols "On"
183		prepare()
184		test.capture [[
185<Link>
186	<SubSystem>Windows</SubSystem>
187	<GenerateDebugInformation>true</GenerateDebugInformation>
188		]]
189	end
190
191	function suite.generateDebugInfo_onSymbolsFastLink_on2015()
192		p.action.set("vs2015")
193		symbols "FastLink"
194		prepare()
195		test.capture [[
196<Link>
197	<SubSystem>Windows</SubSystem>
198	<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
199	<GenerateDebugInformation>DebugFastLink</GenerateDebugInformation>
200		]]
201	end
202
203	function suite.generateDebugInfo_onSymbolsFull_on2015()
204		p.action.set("vs2015")
205		symbols "Full"
206		prepare()
207		test.capture [[
208<Link>
209	<SubSystem>Windows</SubSystem>
210	<GenerateDebugInformation>true</GenerateDebugInformation>
211		]]
212	end
213
214	function suite.generateDebugInfo_onSymbolsFull_on2017()
215		p.action.set("vs2017")
216		symbols "Full"
217		prepare()
218		test.capture [[
219<Link>
220	<SubSystem>Windows</SubSystem>
221	<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
222		]]
223	end
224
225--
226-- Any system libraries specified in links() should be listed as
227-- additional dependencies.
228--
229
230	function suite.additionalDependencies_onSystemLinks()
231		links { "lua", "zlib" }
232		prepare()
233		test.capture [[
234<Link>
235	<SubSystem>Windows</SubSystem>
236	<AdditionalDependencies>lua.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
237		]]
238	end
239
240	function suite.additionalDependencies_onSystemLinksStatic()
241		kind "StaticLib"
242		links { "lua", "zlib" }
243		prepare()
244		test.capture [[
245<Link>
246	<SubSystem>Windows</SubSystem>
247</Link>
248<Lib>
249	<AdditionalDependencies>lua.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
250</Lib>
251		]]
252	end
253
254
255--
256-- Any system libraries specified in links() with valid extensions should
257-- be listed with those extensions.
258--
259
260	function suite.additionalDependencies_onSystemLinksExtensions()
261		links { "lua.obj", "zlib.lib" }
262		prepare()
263		test.capture [[
264<Link>
265	<SubSystem>Windows</SubSystem>
266	<AdditionalDependencies>lua.obj;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
267		]]
268	end
269
270	function suite.additionalDependencies_onSystemLinksExtensionsStatic()
271		kind "StaticLib"
272		links { "lua.obj", "zlib.lib" }
273		prepare()
274		test.capture [[
275<Link>
276	<SubSystem>Windows</SubSystem>
277</Link>
278<Lib>
279	<AdditionalDependencies>lua.obj;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
280</Lib>
281		]]
282	end
283
284
285--
286-- Any system libraries specified in links() with multiple dots should
287-- only have .lib appended to the end when no valid extension is found
288--
289
290	function suite.additionalDependencies_onSystemLinksExtensionsMultipleDots()
291		links { "lua.5.3.lib", "lua.5.4" }
292		prepare()
293		test.capture [[
294<Link>
295	<SubSystem>Windows</SubSystem>
296	<AdditionalDependencies>lua.5.3.lib;lua.5.4.lib;%(AdditionalDependencies)</AdditionalDependencies>
297		]]
298	end
299
300	function suite.additionalDependencies_onSystemLinksExtensionsMultipleDotsStatic()
301		kind "StaticLib"
302		links { "lua.5.3.lib", "lua.5.4" }
303		prepare()
304		test.capture [[
305<Link>
306	<SubSystem>Windows</SubSystem>
307</Link>
308<Lib>
309	<AdditionalDependencies>lua.5.3.lib;lua.5.4.lib;%(AdditionalDependencies)</AdditionalDependencies>
310</Lib>
311		]]
312	end
313
314
315--
316-- Additional library directories should be specified, relative to the project.
317--
318
319	function suite.additionalLibraryDirectories_onLibDirs()
320		libdirs { "../lib", "../lib64" }
321		prepare()
322		test.capture [[
323<Link>
324	<SubSystem>Windows</SubSystem>
325	<AdditionalLibraryDirectories>..\lib;..\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
326		]]
327	end
328
329
330--
331-- Sibling projects do not need to be listed in additional dependencies, as Visual
332-- Studio will link them implicitly.
333--
334
335	function suite.excludeSiblings()
336		links { "MyProject2" }
337		test.createproject(wks)
338		kind "SharedLib"
339		prepare()
340		test.capture [[
341<Link>
342	<SubSystem>Windows</SubSystem>
343	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
344</Link>
345		]]
346	end
347
348
349--
350-- If the NoImplicitLink flag is set, all dependencies should be listed explicitly.
351--
352
353	function suite.includeSiblings_onNoImplicitLink()
354		flags { "NoImplicitLink" }
355		links { "MyProject2" }
356		test.createproject(wks)
357		kind "SharedLib"
358		prepare()
359		test.capture [[
360<Link>
361	<SubSystem>Windows</SubSystem>
362	<AdditionalDependencies>bin\Debug\MyProject2.lib;%(AdditionalDependencies)</AdditionalDependencies>
363	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
364</Link>
365<ProjectReference>
366	<LinkLibraryDependencies>false</LinkLibraryDependencies>
367</ProjectReference>
368		]]
369	end
370
371
372--
373-- Static libraries do not link dependencies directly, to maintain
374-- compatibility with GCC and others.
375--
376
377	function suite.additionalDependencies_onSystemLinksAndStaticLib()
378		kind "StaticLib"
379		links { "lua", "zlib" }
380		libdirs { "../lib", "../lib64" }
381		prepare()
382		test.capture [[
383<Link>
384	<SubSystem>Windows</SubSystem>
385</Link>
386		]]
387	end
388
389
390--
391-- Check handling of the import library settings.
392--
393
394	function suite.importLibrary_onImpLibDir()
395		implibdir "../lib"
396		prepare()
397		test.capture [[
398<Link>
399	<SubSystem>Windows</SubSystem>
400	<ImportLibrary>..\lib\MyProject.lib</ImportLibrary>
401</Link>
402		]]
403	end
404
405
406
407--
408-- Check handling of additional options.
409--
410
411	function suite.additionalOptions_onNonStaticLib()
412		kind "SharedLib"
413		linkoptions { "/kupo" }
414		prepare()
415		test.capture [[
416<Link>
417	<SubSystem>Windows</SubSystem>
418	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
419	<AdditionalOptions>/kupo %(AdditionalOptions)</AdditionalOptions>
420		]]
421	end
422
423	function suite.additionalOptions_onStaticLib()
424		kind "StaticLib"
425		linkoptions { "/kupo" }
426		prepare()
427		test.capture [[
428<Link>
429	<SubSystem>Windows</SubSystem>
430</Link>
431<Lib>
432	<AdditionalOptions>/kupo %(AdditionalOptions)</AdditionalOptions>
433</Lib>
434		]]
435	end
436
437
438--
439-- Enable reference optimizing if Optimize flag is specified.
440--
441
442	function suite.optimizeReferences_onOptimizeFlag()
443		optimize "On"
444		prepare()
445		test.capture [[
446<Link>
447	<SubSystem>Windows</SubSystem>
448	<EnableCOMDATFolding>true</EnableCOMDATFolding>
449	<OptimizeReferences>true</OptimizeReferences>
450		]]
451	end
452
453
454--
455-- Correctly handle module definition (.def) files.
456--
457
458	function suite.recognizesModuleDefinitionFile()
459		files { "hello.cpp", "hello.def" }
460		prepare()
461		test.capture [[
462<Link>
463	<SubSystem>Windows</SubSystem>
464	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
465	<ModuleDefinitionFile>hello.def</ModuleDefinitionFile>
466</Link>
467		]]
468	end
469
470
471--
472-- Managed assembly references should not be listed in additional dependencies.
473--
474
475	function suite.ignoresAssemblyReferences()
476		links { "kernel32", "System.dll", "System.Data.dll" }
477		prepare()
478		test.capture [[
479<Link>
480	<SubSystem>Windows</SubSystem>
481	<AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
482		]]
483	end
484
485
486--
487-- Xbox 360 doesn't list a subsystem or entry point.
488--
489
490	function suite.onXbox360()
491		kind "ConsoleApp"
492		system "Xbox360"
493		prepare()
494		test.capture [[
495		]]
496	end
497
498--
499-- Xbox 360 uses .lib for library extensions
500--
501	function suite.libAdded_onXbox360SystemLibs()
502		kind "ConsoleApp"
503		system "Xbox360"
504		links { "user32" }
505		prepare()
506		test.capture [[
507<Link>
508	<AdditionalDependencies>user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
509</Link>
510		]]
511	end
512
513
514--
515-- Check handling of warning flags.
516--
517
518	function suite.fatalWarnings_onDynamicLink()
519		kind "ConsoleApp"
520		flags { "FatalLinkWarnings" }
521		prepare()
522		test.capture [[
523<Link>
524	<SubSystem>Console</SubSystem>
525	<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
526		]]
527	end
528
529	function suite.fatalWarnings_onStaticLink()
530		kind "StaticLib"
531		flags { "FatalLinkWarnings" }
532		prepare()
533		test.capture [[
534<Link>
535	<SubSystem>Windows</SubSystem>
536</Link>
537<Lib>
538	<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
539</Lib>
540		]]
541	end
542
543
544--
545-- Test generating .map files.
546--
547
548	function suite.generateMapFile_onMapsFlag()
549		flags { "Maps" }
550		prepare()
551		test.capture [[
552<Link>
553	<SubSystem>Windows</SubSystem>
554	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
555	<GenerateMapFile>true</GenerateMapFile>
556</Link>
557		]]
558	end
559
560--
561-- Test ignoring default libraries with extensions specified.
562--
563
564	function suite.ignoreDefaultLibraries_WithExtensions()
565		ignoredefaultlibraries { "lib1.lib", "lib2.obj" }
566		prepare()
567		test.capture [[
568<Link>
569	<SubSystem>Windows</SubSystem>
570	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
571	<IgnoreSpecificDefaultLibraries>lib1.lib;lib2.obj</IgnoreSpecificDefaultLibraries>
572</Link>
573		]]
574	end
575
576--
577-- Test ignoring default libraries without extensions specified.
578--
579
580	function suite.ignoreDefaultLibraries_WithExtensions()
581		ignoredefaultlibraries { "lib1", "lib2.obj" }
582		prepare()
583		test.capture [[
584<Link>
585	<SubSystem>Windows</SubSystem>
586	<ImportLibrary>bin\Debug\MyProject.lib</ImportLibrary>
587	<IgnoreSpecificDefaultLibraries>lib1.lib;lib2.obj</IgnoreSpecificDefaultLibraries>
588</Link>
589		]]
590	end
591