Revert back to Visual Studio's default implicit linking; add NoImplicitLink flag to disable

This commit is contained in:
Jason Perkins 2012-11-30 14:05:19 -05:00
parent 732dd23d2e
commit cc6e53314f
12 changed files with 1502 additions and 1165 deletions

View File

@ -23,6 +23,7 @@
* Added forceinclude() to specify forced include files
* Visual Studio C# projects now support architectures
* Visual Studio C# projects now support pre- and post-build commands
* Added NoImplicitLink flag to force explicit linking from Visual Studio
-------

View File

@ -8,6 +8,7 @@
local vstudio = premake.vstudio
local solution = premake.solution
local project = premake5.project
local config = premake5.config
--
@ -243,6 +244,29 @@
end
--
-- If a dependency of a project configuration is excluded from that particular
-- build configuration or platform, Visual Studio will still try to link it.
-- This function detects that case, so that the individual actions can work
-- around it by switching to external linking.
--
-- @param cfg
-- The configuration to test.
-- @return
-- True if the configuration excludes one or more dependencies.
--
function vstudio.needsExplicitLink(cfg)
local ex = cfg.flags.NoImplicitLink
if not ex then
local prjdeps = project.getdependencies(cfg.project)
local cfgdeps = config.getlinks(cfg, "dependencies", "object")
ex = #prjdeps ~= #cfgdeps
end
return ex
end
--
-- Returns the Visual Studio project configuration identifier corresponding
-- to the given Premake configuration.

File diff suppressed because it is too large Load Diff

View File

@ -331,6 +331,8 @@
--
function vc2010.link(cfg)
local explicit = vstudio.needsExplicitLink(cfg)
_p(2,'<Link>')
local subsystem = iif(cfg.kind == premake.CONSOLEAPP, "Console", "Windows")
@ -344,7 +346,7 @@
end
if cfg.kind ~= premake.STATICLIB then
vc2010.link_dynamic(cfg)
vc2010.link_dynamic(cfg, explicit)
end
_p(2,'</Link>')
@ -356,13 +358,15 @@
-- Left to its own devices, VS will happily link against a project dependency
-- that has been excluded from the build. As a workaround, disable dependency
-- linking and list all siblings explicitly
_p(2,'<ProjectReference>')
_p(3,'<LinkLibraryDependencies>false</LinkLibraryDependencies>')
_p(2,'</ProjectReference>')
if explicit then
_p(2,'<ProjectReference>')
_p(3,'<LinkLibraryDependencies>false</LinkLibraryDependencies>')
_p(2,'</ProjectReference>')
end
end
function vc2010.link_dynamic(cfg)
vc2010.additionalDependencies(cfg)
function vc2010.link_dynamic(cfg, explicit)
vc2010.additionalDependencies(cfg, explicit)
vc2010.additionalLibraryDirectories(cfg)
if cfg.kind == premake.SHAREDLIB then
@ -550,19 +554,20 @@
-- Write out the linker's additionalDependencies element.
--
function vc2010.additionalDependencies(cfg)
function vc2010.additionalDependencies(cfg, explicit)
local links
-- check to see if this project uses an external toolset. If so, let the
-- toolset define the format of the links
local toolset = premake.vstudio.vc200x.toolset(cfg)
if toolset then
links = toolset.getlinks(cfg, false)
links = toolset.getlinks(cfg, not explicit)
else
-- VS always tries to link against project dependencies, even when those
-- projects are excluded from the build. To work around, linking dependent
-- projects is disabled, and sibling projects link explicitly
links = config.getlinks(cfg, "all", "fullpath")
local scope = iif(explicit, "all", "system")
links = config.getlinks(cfg, scope, "fullpath")
end
if #links > 0 then

View File

@ -562,6 +562,7 @@
"NoEditAndContinue",
"NoExceptions",
"NoFramePointer",
"NoImplicitLink",
"NoImportLib",
"NoIncrementalLink",
"NoManifest",

View File

@ -385,18 +385,19 @@
--
function project.getdependencies(prj)
local result = {}
for cfg in project.eachconfig(prj) do
for _, link in ipairs(cfg.links) do
local dep = premake.solution.findproject(cfg.solution, link)
if dep and not table.contains(result, dep) then
table.insert(result, dep)
if not prj.dependencies then
local result = {}
for cfg in project.eachconfig(prj) do
for _, link in ipairs(cfg.links) do
local dep = premake.solution.findproject(cfg.solution, link)
if dep and not table.contains(result, dep) then
table.insert(result, dep)
end
end
end
prj.dependencies = result
end
return result
return prj.dependencies
end

View File

@ -0,0 +1,98 @@
--
-- tests/actions/vstudio/vc200x/test_excluded_configs.lua
-- Check handling of configurations which have been excluded from the build.
-- Copyright (c) 2012 Jason Perkins and the Premake project
--
T.vs200x_excluded_configs = {}
local suite = T.vs200x_excluded_configs
local vc200x = premake.vstudio.vc200x
--
-- Setup/teardown
--
local sln, prj
function suite.setup()
_ACTION = "vs2008"
sln = solution("MySolution")
configurations { "Debug", "Release" }
platforms { "Zeus", "Ares" }
language "C++"
prj = project("MyProject")
kind "ConsoleApp"
links { "MyProject2", "MyProject3" }
project("MyProject2")
kind "StaticLib"
project("MyProject3")
kind "StaticLib"
removeplatforms { "Ares" }
end
local function prepare(platform)
local cfg = premake5.project.getconfig(prj, "Debug", platform)
vc200x.VCLinkerTool_ng(cfg)
end
--
-- If a sibling is included in one configuration and excluded from
-- another, the included configuration should link as normal.
--
function suite.normalLink_onIncludedConfig()
prepare("Zeus")
test.capture [[
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\MyProject.exe"
]]
end
function suite.normalLink_onIncludedConfig_externalTool()
solution("MySolution")
system "PS3"
prepare("Zeus")
test.capture [[
<Tool
Name="VCLinkerTool"
AdditionalOptions="-s"
OutputFile="$(OutDir)\MyProject.elf"
]]
end
--
-- If a sibling is included in one configuration and excluded from
-- another, the excluded configuration should force explicit linking
-- and not list the excluded library.
--
function suite.explicitLink_onExcludedConfig()
prepare("Ares")
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalDependencies="MyProject2.lib"
]]
end
function suite.explicitLink_onExcludedConfig_externalTool()
solution("MySolution")
system "PS3"
prepare("Ares")
test.capture [[
<Tool
Name="VCLinkerTool"
AdditionalOptions="-s"
AdditionalDependencies="libMyProject2.a"
]]
end

View File

@ -17,6 +17,7 @@
function suite.setup()
_ACTION = "vs2008"
sln, prj = test.createsolution()
kind "ConsoleApp"
system "PS3"
end
@ -71,7 +72,6 @@
--
function suite.additionalDependencies_onSystemLibs()
kind "ConsoleApp"
links { "fs_stub", "net_stub" }
prepare()
test.capture [[
@ -81,3 +81,47 @@
AdditionalDependencies="-lfs_stub -lnet_stub"
]]
end
--
-- Sibling dependencies should not appear in the list of links;
-- Visual Studio will add those automatically.
--
function suite.excludesSiblings()
links { "MyProject2" }
project ("MyProject2")
system "PS3"
kind "StaticLib"
language "C++"
prepare()
test.capture [[
<Tool
Name="VCLinkerTool"
AdditionalOptions="-s"
OutputFile="$(OutDir)\MyProject.elf"
]]
end
--
-- Sibling dependencies should appear in the list of links if
-- the NoImplicitLinks flag is set.
--
function suite.includesSiblings_onNoExplicitLink()
flags { "NoImplicitLink" }
links { "MyProject2" }
project ("MyProject2")
system "PS3"
kind "StaticLib"
language "C++"
prepare()
test.capture [[
<Tool
Name="VCLinkerTool"
AdditionalOptions="-s"
AdditionalDependencies="libMyProject2.a"
]]
end

View File

@ -36,7 +36,6 @@
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
OutputFile="$(OutDir)\MyProject.exe"
LinkIncremental="2"
GenerateDebugInformation="false"
@ -58,7 +57,6 @@
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
OutputFile="$(OutDir)\MyProject.exe"
LinkIncremental="2"
GenerateDebugInformation="false"
@ -80,7 +78,6 @@
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
OutputFile="$(OutDir)\MyProject.dll"
LinkIncremental="2"
GenerateDebugInformation="false"
@ -118,7 +115,6 @@
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
OutputFile="$(OutDir)\MyProject.exe"
LinkIncremental="2"
GenerateDebugInformation="true"
@ -138,7 +134,6 @@
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
OutputFile="$(OutDir)\MyProject.exe"
LinkIncremental="2"
GenerateDebugInformation="true"
@ -160,7 +155,6 @@
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
OutputFile="$(OutDir)\MyProject.exe"
LinkIncremental="2"
ModuleDefinitionFile="MyProject.def"
@ -178,7 +172,6 @@
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
OutputFile="$(OutDir)\MyProject.exe"
LinkIncremental="1"
]]
@ -203,6 +196,61 @@
end
--
-- Links to system libraries should appear in the list, properly decorated.
--
function suite.includesSystemLibs()
links { "GL", "GLU" }
prepare()
test.capture [[
<Tool
Name="VCLinkerTool"
AdditionalDependencies="GL.lib GLU.lib"
]]
end
--
-- Links to sibling projects should not appear in the list; Visual Studio
-- will link to those automatically.
--
function suite.excludesSiblings()
links { "MyProject2" }
project ("MyProject2")
kind "StaticLib"
language "C++"
prepare()
test.capture [[
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\MyProject.exe"
]]
end
--
-- If the NoImplicitLinking flag is set, sibling projects should
-- then be added to the list.
--
function suite.includesSiblings_onNoImplicitLink()
flags { "NoImplicitLink" }
links { "MyProject2" }
project ("MyProject2")
kind "StaticLib"
language "C++"
prepare()
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalDependencies="MyProject2.lib"
]]
end
--
-- Libraries with spaces in the name must be wrapped in quotes.
--
@ -213,8 +261,6 @@
test.capture [[
<Tool
Name="VCLinkerTool"
LinkLibraryDependencies="false"
AdditionalDependencies="&quot;My Lib.lib&quot;"
]]
end

View File

@ -0,0 +1,111 @@
--
-- tests/actions/vstudio/vc2010/test_excluded_configs.lua
-- Check handling of configurations which have been excluded from the build.
-- Copyright (c) 2012 Jason Perkins and the Premake project
--
T.vs2010_excluded_configs = {}
local suite = T.vs2010_excluded_configs
local vc2010 = premake.vstudio.vc2010
--
-- Setup/teardown
--
local sln, prj
function suite.setup()
_ACTION = "vs2010"
sln = solution("MySolution")
configurations { "Debug", "Release" }
platforms { "Zeus", "Ares" }
language "C++"
prj = project("MyProject")
kind "ConsoleApp"
links { "MyProject2", "MyProject3" }
project("MyProject2")
kind "StaticLib"
project("MyProject3")
kind "StaticLib"
removeplatforms { "Ares" }
end
local function prepare(platform)
local cfg = premake5.project.getconfig(prj, "Debug", platform)
vc2010.link(cfg)
end
--
-- If a sibling is included in one configuration and excluded from
-- another, the included configuration should link as normal.
--
function suite.normalLink_onIncludedConfig()
prepare("Zeus")
test.capture [[
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
</Link>
]]
end
function suite.normalLink_onIncludedConfig_externalTool()
solution("MySolution")
system "PS3"
prepare("Zeus")
test.capture [[
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
</Link>
]]
end
--
-- If a sibling is included in one configuration and excluded from
-- another, the excluded configuration should force explicit linking
-- and not list the excluded library.
--
function suite.explicitLink_onExcludedConfig()
prepare("Ares")
test.capture [[
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>MyProject2.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
</Link>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
</ProjectReference>
]]
end
function suite.explicitLink_onExcludedConfig_externalTool()
solution("MySolution")
system "PS3"
prepare("Ares")
test.capture [[
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>libMyProject2.a;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
</Link>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
</ProjectReference>
]]
end

View File

@ -41,9 +41,6 @@
<GenerateDebugInformation>false</GenerateDebugInformation>
<ImportLibrary>MyProject.lib</ImportLibrary>
</Link>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
</ProjectReference>
]]
end
@ -117,6 +114,25 @@
end
--
-- Test the handling of the NoImplicitLink flag.
--
function suite.linkDependencies_onNoImplicitLink()
flags "NoImplicitLink"
prepare()
test.capture [[
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ImportLibrary>MyProject.lib</ImportLibrary>
</Link>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
</ProjectReference>
]]
end
--
-- Test the handling of the Symbols flag.
--
@ -166,12 +182,30 @@
--
-- Let to its own devices, VS will attempt to link against dependencies
-- that have been excluded from the build. To work around this, dependency
-- linking is turned off, and siblings are linked explicitly instead.
-- Sibling projects do not need to be listed in additional dependencies, as Visual
-- Studio will link them implicitly.
--
function suite.includeSiblings_onOnlySiblingProjectLinks()
function suite.excludeSiblings()
links { "MyProject2" }
test.createproject(sln)
kind "SharedLib"
prepare()
test.capture [[
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ImportLibrary>MyProject.lib</ImportLibrary>
]]
end
--
-- If the NoImplicitLink flag is set, all dependencies should be listed explicitly.
--
function suite.includeSiblings_onNoImplicitLink()
flags { "NoImplicitLink" }
links { "MyProject2" }
test.createproject(sln)
kind "SharedLib"
@ -181,33 +215,11 @@
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>MyProject2.lib;%(AdditionalDependencies)</AdditionalDependencies>
]]
end
function suite.includeSiblings_OnMixedLinks()
links { "MyProject2", "kernel32" }
test.createproject(sln)
kind "SharedLib"
prepare()
test.capture [[
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>MyProject2.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
]]
end
function suite.excludeSibling_OnExcludedConfig()
links { "MyProject2", "kernel32" }
test.createproject(sln)
kind "SharedLib"
removeconfigurations { "Debug" }
prepare()
test.capture [[
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImportLibrary>MyProject.lib</ImportLibrary>
</Link>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
</ProjectReference>
]]
end
@ -314,23 +326,3 @@
<AdditionalDependencies>-lfs_stub;-lnet_stub;%(AdditionalDependencies)</AdditionalDependencies>
]]
end
--
-- On the PS3, sibling libraries should be linked directly.
--
function suite.includeSiblings_onPS3SiblingLinks()
system "PS3"
links { "MyProject2" }
test.createproject(sln)
kind "StaticLib"
system "PS3"
prepare()
test.capture [[
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>libMyProject2.a;%(AdditionalDependencies)</AdditionalDependencies>
]]
end

View File

@ -108,6 +108,7 @@
dofile("actions/vstudio/vc200x/test_compiler_block.lua")
dofile("actions/vstudio/vc200x/test_configuration.lua")
dofile("actions/vstudio/vc200x/test_debug_settings.lua")
dofile("actions/vstudio/vc200x/test_excluded_configs.lua")
dofile("actions/vstudio/vc200x/test_external_compiler.lua")
dofile("actions/vstudio/vc200x/test_external_linker.lua")
dofile("actions/vstudio/vc200x/test_files.lua")
@ -122,6 +123,7 @@
dofile("actions/vstudio/vc2010/test_compile_settings.lua")
dofile("actions/vstudio/vc2010/test_config_props.lua")
dofile("actions/vstudio/vc2010/test_debug_settings.lua")
dofile("actions/vstudio/vc2010/test_excluded_configs.lua")
dofile("actions/vstudio/vc2010/test_globals.lua")
dofile("actions/vstudio/vc2010/test_header.lua")
dofile("actions/vstudio/vc2010/test_files.lua")