Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Projects generated for VS2017 fail [C1052] to do partial rebuild due to ProgramDataBaseFileName element #9

Open
assarbad opened this issue Jul 19, 2017 · 2 comments

Comments

@assarbad
Copy link

The file src\actions\vstudio\vs2010_vcxproj.lua contains this:

		if cfg.flags.Symbols then
			_p(3,'<ProgramDataBaseFileName>$(OutDir)%s.pdb</ProgramDataBaseFileName>'
				, path.getbasename(cfg.buildtarget.name))
		end

There are two issues with this. For starters instead of retrieving the base name, the code should arguably make use of the $(TargetName) macro. If possible incompatibilities of pre-VS2010 versus VS2010+ are of concern here, one could implement a shallow function using a map (Lua table) to transform macro names (see bottom). So arguably it should have read:

		if cfg.flags.Symbols then
			_p(3,'<ProgramDataBaseFileName>$(OutDir)$(TargetName)</ProgramDataBaseFileName>')
		end

The second issue is the bigger one. There are two PDBs usually involved during compilation. One by the linker and one by the compiler. This explains why we receive a C1052 error.

The instance of <ProgramDataBaseFileName /> is meant to be the compiler one (inside <ClCompile />). However, its default value is normally $(IntDir)vc$(PlatformToolsetVersion).pdb (as per the above linked MSDN resource).

So when Premake sets it to what amounts to $(OutDir)$(TargetName) that clashes with the implicit value used for the linker PDB. That's why if I change a single source file - e.g. during debugging - and then press F5, instead of compiling, linking and debugging, I get the above mentioned error C1052.

The solution is to leave out the <ProgramDataBaseFileName /> element altogether and have it use its default. However, when looking for flags.Symbols in aforementioned .lua file, there's a second instance with a similar condition. That one positively must stay for otherwise we can't control whether a PDB file gets generated at all.

Best regards,

Oliver

PS: I found a mention of this issue over here. What struck me as odd, at best, was the lack of mentioning @starkos in the copyright notice of the README for that project, albeit claiming to be (and visibly being) a fork of Premake4.
PPS: I've made use of the following function to translate macro names in my own premake4.lua files for quite some time now:

local function transformMN(input) -- transform the macro names for older Visual Studio versions
    local new_map   = { vs2002 = 0, vs2003 = 0, vs2005 = 0, vs2008 = 0 }
    local replacements = { Platform = "PlatformName", Configuration = "ConfigurationName" }
    if new_map[action] ~= nil then
        for k,v in pairs(replacements) do
            if input:find(k) then
                input = input:gsub(k, v)
            end
        end
    end
    return input
end
@assarbad
Copy link
Author

assarbad commented Jul 19, 2017

Here's a fix which can be applied via your own premake4.lua (as opposed to patching Premake4 and building it again) which I also added into the Wiki.

Fix issue #9 (error C1052 due to name clash of compiler and linker PDB)

Problem: When compiling a project again after changing a source file, without doing a full rebuild, the compiler tells us about error C1052. The cause for this is that Premake4 names the compiler's PDB file by the name the linker's PDB file defaults to. This effectively causes the linker to overwrite the PDB of the compiler and upon the next compilation the compiler chokes, because the linker's PDB file is incomatible.

Solution: We can easily fix the problem by patching premake.vs2010_vcxproj. We capture the output of the original function (making sure to save and restore possible nested captures) and then remove the <ProgramDataBaseFileName /> element from the output, effectively forcing it to use the default name again.

do
    -- Premake4 sets the PDB file name for the compiler's PDB to the default
    -- value used by the linker's PDB. This causes error C1052 on VS2017. Fix it.
    local orig_premake_vs2010_vcxproj = premake.vs2010_vcxproj
    premake.vs2010_vcxproj = function(prj)
        local old_captured = io.captured -- save io.captured state
        io.capture() -- this sets io.captured = ''
        orig_premake_vs2010_vcxproj(prj)
        local captured = io.endcapture()
        assert(captured ~= nil)
        captured = captured:gsub("%s+<ProgramDataBaseFileName>[^<]+</ProgramDataBaseFileName>", "")
        if old_captured ~= nil then
            io.captured = old_captured .. captured -- restore outer captured state, if any
        else
            io.write(captured)
        end
    end
end

Note: this only fixes the behavior for VS201x versions, but I never encountered the issue on earlier versions of VS, so I'll - until proven otherwise - assume that this is a non-issue on pre-VS2010 versions.

@starkos
Copy link
Member

starkos commented Jul 19, 2017

You might want to take a look at what Premake5 is doing here as well, as I know there were a number of PDB related fixes since the last 4.x release.

If you submit a PR to fix this in the Premake 4 code I would be happy to merge it for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants