Win32 configuration filter matches Win64 as well
This passes (added to core\modules\vstudio\tests\vc2010\test_files.lua):
function suite.excludedFromBuild_onConfigExcludedFile()
configurations { "Debug", "Release" }
platforms { "Win64", "Win32" }
files { "hello.cpp" }
configuration "Win64"
removefiles { "hello.cpp" }
prj = test.getproject(wks, 1)
vc2010.files(prj)
test.capture [[
<ItemGroup>
<ClCompile Include="hello.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Win64|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Win64|x64'">true</ExcludedFromBuild>
</ClCompile>
</ItemGroup>
]]
End
However, if it's filtered for Win32, then hello.cpp is removed for both configs (generated block is empty). So, this fails:
function suite.excludedFromBuild_onConfigExcludedFile()
configurations { "Debug", "Release" }
platforms { "Win64", "Win32" }
files { "hello.cpp" }
configuration "Win32"
removefiles { "hello.cpp" }
prj = test.getproject(wks, 1)
vc2010.files(prj)
test.capture [[
<ItemGroup>
<ClCompile Include="hello.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Win32|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release Win32|x64'">true</ExcludedFromBuild>
</ClCompile>
</ItemGroup>
]]
End
If however Win32 is substituted for, say, "Win33" (in config declarations too), then it filters fine for that, and only "Win33" configs are excluded.
Forgot to mention that this breaks any builds having for instance this:
configuration { "Win32*" } files { "win32/*.cpp" }
As it adds those win32 files to the win64 config too!
That test case you have says Debug Win32|x64 it should probably be Debug|Win32, does that resolve the problem? (Same applies for the Release line)
Regarding the Win32 files issue, do you still encounter this problem if you use filter? Also, I'd recommend using x64 instead of Win64, it's not as symmetrical but it does work.
Thanks for replying. Yes, indeed, filter "platforms:Win32" would have helped, but I have a bunch of old premake projects with configuration "Win32" that would be difficult to change, and the fact is that this used to work, some time before alpha12. So just trying to figure out what broke in the meantime.
As to why is there Debug Win32|x64, that's a good question, as there appears to be some redundant insertion of platform into full config names. It's been a while since I looked at this, so it could be I've actually forgotten the reasons for this :(
For instance,
configurations { "Debug", "Release" }
produces these configs:
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
(I'm guessing Win32 is the default platform, when not specified)
However,
configurations { "Debug", "Release" }
platforms { "Win64", "Win32" }
produces:
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug Win64|x64">
<Configuration>Debug Win64</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug Win64|Win32">
<Configuration>Debug Win64</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release Win64|x64">
<Configuration>Release Win64</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release Win64|Win32">
<Configuration>Release Win64</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
There are 8 configurations, while I think 4 should be enough! I hope someone will be able to shed some light on this.
Visual Studio requires an entry for every combination of configuration and architecture, even if they aren't used (or don't even make sense). Hence the extra ProjectConfigurations.
I suspect the problem is that we are automagically treating Win32 as an architecture under the hood, while Win64 is just a configuration label, and this is confusing configuration() somewhere. Though why that would have only started happening now I'm not certain.
There has been another issue about the exact same thing: #1171
Sam made an attempted fix in #1228 that to some extent missed the point.
- There is this function:
function vstudio.projectPlatform(cfg)
local platform = cfg.platform
if platform then
local pltarch = vstudio.archFromPlatform(cfg.platform) or platform
local cfgarch = vstudio.archFromConfig(cfg)
if pltarch == cfgarch then
platform = nil
end
end
if platform then
return cfg.buildcfg .. " " .. platform
else
return cfg.buildcfg
end
end
For "Win64" cfg.platform is "Win64", obviously.
-
pltarchis the result of this function:
function vstudio.archFromPlatform(platform)
local system = p.api.checkValue(p.fields.system, platform)
local arch = p.api.checkValue(p.fields.architecture, platform)
return architecture(system, arch or platform:lower())
end
system and arch are both nil because there is no "Win64" field in either of those tables. the architecture function has no "win64" field either, so it returns nil.
-
cfgarchis the result of this function:
function vstudio.archFromConfig(cfg, win32)
local isnative = project.isnative(cfg.project)
local arch = architecture(cfg.system, cfg.architecture)
if not arch then
arch = iif(isnative, "x86", "Any CPU")
end
if win32 and isnative and arch == "x86" then
arch = "Win32"
end
return arch
end
This again calls the architecture function, but with cfg.architecture, which should be "x86_64" at this point (thanks to sam's partial fix), getting translated to "x64", the [correct] return value.
Now "x64" obviously isn't nil, so the check in 1 fails and "Win64" is added as label, multiplying the configurations.
The fix should be adding "win64" to the architecture function in vstudio.lua.
Here:
https://github.com/premake/premake-core/blob/900e4b0d86fa87cefa31ce06ea7ebede540a4160/modules/vstudio/vstudio.lua#L25
The reason why i don't just add a fix is that i wanted to show how complex that stuff is. Maybe that could be easier? At the very least those functions in vstudio.lua should get grouped together, currently they are all over the place.
I think that fixing the redundant labels fixes the other issues around it at the same time as it's all about wrong platform matching. Any unknown platform will end up in that if there is a valid architecture in cfg.architecture. If there isn't, it works as both architecture calls return nil.
I suspect the problem is that we are automagically treating
Win32as an architecture under the hood, whileWin64is just a configuration label, and this is confusingconfiguration()somewhere.
That's my suspicion too, but I'm struggling to find where exactly is it coming from.
Though why that would have only started happening now I'm not certain.
Not exactly now. Somewhere in the past 2 years there's been a change that must have done it, since the last premake-core where this worked for me was in early 2017. I just skipped to the latest from there, as I needed the VS2019 support.
well it could actually be sam's fix i mentioned that broke it by fixing one side of the equation and breaking the equation with that. now it's time to fix the other side.
edit: correction: the bug is somewhere in the configuration call but that one is too well obfuscated for now, maybe i got time later
I'm experiencing a similar issue to this one, but I'm not sure it's the same pathology. I'm wondering if it might be a clue as to what is really happening.
I have two platforms, Win32 and x64 (mimicking Windows nomenclature as this happens to be a Windows-only project I found this with).
Both Debug and Release configurations in the x64 platform were inheriting the Win32 include and lib path values. They preceded the x64 platform values. I think that's the same symptom, but the configurations are reversed (64-bit inheriting 32-bit instead of vice versa).
This happens when either configuration or filter is used to qualify the includedirs and libdirs.
I ended up renaming Win32 to x86, as the bootstrap project uses, and that worked around the issue.
I reproduced this using the v5.0.0-alpha16 tag.
FYI, for others finding this issue: the configuration call is going to be deprecated shortly as it can't be supported in the next version. If you are able, switching out configuration for filter will fix this issue, and also help future-proof your scripts. I do intend to provide a compatibility module to help with the v5-to-v6 migration, but there isn't going to be much that I can do with configuration, since it is so open-ended (or "convenient", as I thought when I originally wrote it smh 🙄).
Realize that some of you have large existing projects that are difficult to change.
@starkos hm, as noted above I was seeing issues with filter, too. I've worked around for now, but I'm happy to test again once the next release is out.