diff --git a/src/actions/vstudio/vs2010.lua b/src/actions/vstudio/vs2010.lua
index 54d004db..b47597da 100644
--- a/src/actions/vstudio/vs2010.lua
+++ b/src/actions/vstudio/vs2010.lua
@@ -43,7 +43,12 @@
premake.generate(prj, ".csproj.user", vstudio.cs2005.generate_user)
elseif premake.project.iscpp(prj) then
premake.generate(prj, ".vcxproj", vstudio.vc2010.generate)
- premake.generate(prj, ".vcxproj.user", vstudio.vc2010.generateUser)
+
+ -- Skip generation of empty user files
+ local user = p.capture(function() vstudio.vc2010.generateUser(prj) end)
+ if #user > 0 then
+ p.generate(prj, ".vcxproj.user", function() p.out(user) end)
+ end
-- Only generate a filters file if the source tree actually has subfolders
if tree.hasbranches(project.getsourcetree(prj)) then
diff --git a/src/actions/vstudio/vs2010_vcxproj_user.lua b/src/actions/vstudio/vs2010_vcxproj_user.lua
index 4cc462f1..de428c92 100755
--- a/src/actions/vstudio/vs2010_vcxproj_user.lua
+++ b/src/actions/vstudio/vs2010_vcxproj_user.lua
@@ -1,7 +1,7 @@
--
-- vs2010_vcxproj_user.lua
-- Generate a Visual Studio 201x C/C++ project .user file
--- Copyright (c) 2011-2013 Jason Perkins and the Premake project
+-- Copyright (c) 2011-2015 Jason Perkins and the Premake project
--
local p = premake
@@ -13,18 +13,43 @@
--
--- Generate a Visual Studio 201x C++ user file, with support for the new platforms API.
+-- Generate a Visual Studio 201x C++ user file.
--
+ m.elements.user = function(cfg)
+ return {
+ m.debugSettings,
+ }
+ end
+
function m.generateUser(prj)
- m.xmlDeclaration()
- m.userProject()
+ -- Only want output if there is something to configure
+ local contents = {}
+ local generate = false
+
for cfg in project.eachconfig(prj) do
- p.push('', m.condition(cfg))
- m.debugSettings(cfg)
- p.pop('')
+ contents[cfg] = p.capture(function()
+ p.push(2)
+ p.callArray(m.elements.user, cfg)
+ p.pop(2)
+ end)
+ if #contents[cfg] > 0 then
+ generate = true
+ end
+ end
+
+ if generate then
+ m.xmlDeclaration()
+ m.userProject()
+ for cfg in project.eachconfig(prj) do
+ p.push('', m.condition(cfg))
+ if #contents[cfg] > 0 then
+ p.outln(contents[cfg])
+ end
+ p.pop('')
+ end
+ p.out('')
end
- _p('')
end
diff --git a/tests/_tests.lua b/tests/_tests.lua
index 08deae23..6e9702c8 100644
--- a/tests/_tests.lua
+++ b/tests/_tests.lua
@@ -116,6 +116,7 @@ return {
"actions/vstudio/vc2010/test_project_configs.lua",
"actions/vstudio/vc2010/test_project_refs.lua",
"actions/vstudio/vc2010/test_prop_sheet.lua",
+ "actions/vstudio/vc2010/test_user_file.lua",
"actions/vstudio/vc2010/test_resource_compile.lua",
"actions/vstudio/vc2010/test_rule_vars.lua",
diff --git a/tests/actions/vstudio/vc2010/test_user_file.lua b/tests/actions/vstudio/vc2010/test_user_file.lua
new file mode 100644
index 00000000..ba935cab
--- /dev/null
+++ b/tests/actions/vstudio/vc2010/test_user_file.lua
@@ -0,0 +1,49 @@
+--
+-- tests/actions/vstudio/vc2010/test_user_file.lua
+-- Verify handling of empty and non-empty .user files for VC'201x.
+-- Copyright (c) 2015 Jason Perkins and the Premake project
+--
+
+ local suite = test.declare("vstudio_vs2010_user_file")
+ local vc2010 = premake.vstudio.vc2010
+ local project = premake.project
+
+
+--
+-- Setup
+--
+
+ local sln
+
+ function suite.setup()
+ _ACTION = "vs2010"
+ sln = test.createsolution()
+ end
+
+ local function prepare()
+ local prj = test.getproject(sln, 1)
+ vc2010.generateUser(prj)
+ end
+
+
+--
+-- If no debugger settings have been specified, then the .user
+-- file should not be written at all.
+--
+
+ function suite.noOutput_onNoSettings()
+ prepare()
+ test.isemptycapture()
+ end
+
+
+--
+-- If a debugger setting has been specified, output.
+--
+
+ function suite.doesOutput_onDebugSettings()
+ debugcommand "bin/emulator.exe"
+ prepare()
+ test.hasoutput()
+ end
+
diff --git a/tests/testfx.lua b/tests/testfx.lua
index ace5b256..5024bc76 100644
--- a/tests/testfx.lua
+++ b/tests/testfx.lua
@@ -121,6 +121,14 @@
end
+ function test.hasoutput()
+ local actual = premake.captured()
+ if actual == "" then
+ test.fail("expected output, received none");
+ end
+ end
+
+
function test.isemptycapture()
local actual = premake.captured()
if actual ~= "" then