premake / premake-core

Premake
https://premake.github.io/
BSD 3-Clause "New" or "Revised" License
3.17k stars 616 forks source link

Visual Studio 2022 solution doesn't generate Mixed Platforms correctly when specifying an architecture explicitly #1758

Closed peter1745 closed 2 years ago

peter1745 commented 2 years ago

What seems to be the problem? When you generate a Visual Studio 2022 solution (using vs2022 build action) that has an architecture specified, and a .NET 5/6 project as well as a C++ project, the solution won't contain the "Mixed Platforms" platform. Meaning you can't build the C# project because the "Any CPU" platform doesn't exist. Instead it just generates whatever architecture is set to. From what I can tell this means that you can't really have a x64 platform when a C# project is present in the solution, since premake generates a Win32 platform if architecture isn't set on Windows.

What did you expect to happen? I expected the solution to have either "Mixed Platforms" in the SolutionConfigurationPlatforms section, or an x64 AND Any CPU platform, and for the CSProject project to have "Any CPU" set as the target platform. I expected the .sln file to looks something like this:


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CPPProject", "CPPProject\CPPProject.vcxproj", "{7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSProject", "CSProject\CSProject.csproj", "{D2B13928-3E1C-EE9E-875A-9F44F303CCF3}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Mixed Platforms = Debug|Mixed Platforms
        Release|Mixed Platforms = Release|Mixed Platforms
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}.Debug|Mixed Platforms.ActiveCfg = Debug|x64
        {7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}.Debug|Mixed Platforms.Build.0 = Debug|x64
        {7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}.Release|Mixed Platforms.ActiveCfg = Release|x64
        {7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}.Release|Mixed Platforms.Build.0 = Release|x64
        {D2B13928-3E1C-EE9E-875A-9F44F303CCF3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
        {D2B13928-3E1C-EE9E-875A-9F44F303CCF3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
        {D2B13928-3E1C-EE9E-875A-9F44F303CCF3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
        {D2B13928-3E1C-EE9E-875A-9F44F303CCF3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
EndGlobal

What have you tried so far? I was able to workaround it by simply creating the "Any CPU" platform in the Configuration Manager. You can also remove the architecture field from the workspace, which would cause premake to generate a Win32 platform, and a Any CPU platform.

How can we reproduce this? Here's the premake script I used to generate the solution:

workspace "PremakeRepro"
    architecture "x64"
    targetdir "build"

    configurations 
    { 
        "Debug", 
        "Release"
    }

project "CPPProject"
    location "CPPProject"
    kind "ConsoleApp"
    language "C++"
    cppdialect "C++17"

    targetdir ("bin/%{prj.name}")
    objdir ("bin-int/%{prj.name}")

    files 
    { 
        "%{prj.name}/src/**.h", 
        "%{prj.name}/src/**.cpp"
    }

    includedirs
    {
        "%{prj.name}/src"
    }

    filter "system:windows"
        systemversion "latest"

    filter "configurations:Debug"
        symbols "On"

    filter "configurations:Release"
        optimize "On"

project "CSProject"
    location "CSProject"
    kind "SharedLib"
    language "C#"
    dotnetframework "net6.0"

    targetdir ("bin/%{prj.name}")
    objdir ("bin-int/%{prj.name}")

    files 
    {
        "%{prj.name}/Source/**.cs", 
    }

Running this premake script with vs2022 as the action should give you a .sln file that looks something like this:


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CPPProject", "CPPProject\CPPProject.vcxproj", "{7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSProject", "CSProject\CSProject.csproj", "{D2B13928-3E1C-EE9E-875A-9F44F303CCF3}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|x64 = Debug|x64
        Release|x64 = Release|x64
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}.Debug|x64.ActiveCfg = Debug|x64
        {7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}.Debug|x64.Build.0 = Debug|x64
        {7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}.Release|x64.ActiveCfg = Release|x64
        {7F401BA0-6BF8-5CED-D4FF-3549C0D6F7DD}.Release|x64.Build.0 = Release|x64
        {D2B13928-3E1C-EE9E-875A-9F44F303CCF3}.Debug|x64.ActiveCfg = Debug|x64
        {D2B13928-3E1C-EE9E-875A-9F44F303CCF3}.Debug|x64.Build.0 = Debug|x64
        {D2B13928-3E1C-EE9E-875A-9F44F303CCF3}.Release|x64.ActiveCfg = Release|x64
        {D2B13928-3E1C-EE9E-875A-9F44F303CCF3}.Release|x64.Build.0 = Release|x64
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
EndGlobal

What version of Premake are you using? I'm using 5.0.0-dev, and as of this issue it's up to date with the master branch.

Anything else we should know? I also tried running the script with vs2019 as the action, and it gave me the same .sln file, but when I open it in Visual Studio 2019 it works just fine. I also tried manually creating a solution with a C++ and C# project through Visual Studio 2022, and it gave both the x64 AND Any CPU platforms.

samsinsane commented 2 years ago

I haven't had a chance to test this out, but what happens if you only specify architecture "x64" for the C++ project? Move the line down ~10 lines in the Premake script.

peter1745 commented 2 years ago

@samsinsane I tested it, and moving the architecture down to the project scope worked. It now generates the Any CPU platform, and properly detects that we're using a mix of platforms. I still think this is a bug though, since architecture is supposed to work on both the project, and workspace level. And having architecture on the workspace level was definitely working prior to the beta1. I'm not sure but has that changed? The example for architecture in the docs shows that it can be used on the workspace level.

Especially since it would be really annoying to have to copy the architecture to every single C++ project in the workspace (I'm working on a project where we have a lot of C++ projects in the workspace)

samsinsane commented 2 years ago

I still think this is a bug though, since architecture is supposed to work on both the project, and workspace level.

Specifying architecture at the workspace level is still working. Your issue indicates that you wanted Any CPU while specifying x64, that doesn't make any sense, Premake generated what you requested.

And having architecture on the workspace level was definitely working prior to the beta1.

I don't really understand what this means. Beta1 added support for VS2022, and your comment above suggests that everything still works for VS2019. It doesn't sound like anything broke in Premake, but that either VS2022 no longer supports x64 C# projects or your VS2022 install is broken. If it's the former then Premake will need to be updated to reflect that change, but otherwise I don't believe anything has broken or changed in Premake that would cause the problem you're seeing.

Especially since it would be really annoying to have to copy the architecture to every single C++ project in the workspace (I'm working on a project where we have a lot of C++ projects in the workspace)

Instead of moving it, change it to this maybe? (Untested, but it should work)

filter { "language:C++" }
  architecture "x64"
filter {}
peter1745 commented 2 years ago

Ah, yeah I think VS2022 (or maybe .NET 6) dropped support for x64 target platforms. In that case premake will need to reflect that, but yes you're right it's probably because they dropped support for it