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

vsxmake generator: Add a BuildAll target #2969

Open
SirLynix opened this issue Oct 24, 2022 · 14 comments
Open

vsxmake generator: Add a BuildAll target #2969

SirLynix opened this issue Oct 24, 2022 · 14 comments

Comments

@SirLynix
Copy link
Member

Is your feature request related to a problem? Please describe.

Hello,

When using a visual studio project generated by the vsxmake generator, clicking "Solution => Build all" (or worse "Solution => Rebuild all") will trigger xmake build / xmake build -r on every target.

This is an issue when you have several projects (targets), as multiple xmake instance will be spawned and will try to rebuild the project from scratch sequentially, meaning a lot of files will be rebuilt multiple times.

This isn't great as one of the benefit we have from using vsxmake is that xmake compiles faster than msbuild.

Describe the solution you'd like

It's possible to tell Visual Studio to not build a project when building the whole solution, by removing the {#target_id#}.#mode#|#arch#.Build.0 = #mode#|#vsarch# association in the .sln file (this still allows to build a target but won't select it when building the solution).

It would be nice to have a solution similar to what cmake does: adding a phony target which builds everything (and will be the only one target with a Build.0 association), and use it to simply run xmake build or xmake build -r on the whole project.

Example:
image

I began working on this as I wanted to make a pull request for this: 36a8591
however I wasn't sure of the best way to generate the BuildAll.vcxproj using the vsxmake generator.

Also, it would be really cool to have a .xmake/UpdateVS.vcxproj which would trigger the xmake project -k vsxmake manually, a bit like plugin.vsxmake.autoupdate rule but in a way we could trigger manually.

Describe alternatives you've considered

There's no other solution than changing the way xmake generates project, we can use vs to tell it to not build projects when building the whole solution but xmake overrides this when it regenerates the .sln

Additional context

I'm using last xmake version

@waruqi
Copy link
Member

waruqi commented Oct 24, 2022

Great, but I also don't know how better to implement it, perhaps you could refer to the cmake generator.

@SirLynix
Copy link
Member Author

It's should be easy to implement, it's like a regular target which will trigger xmake, but instead of triggering xmake build TargetName it should just call xmake build.

My only difficulty is to generate this file with the current .vcxproj generation.

@waruqi
Copy link
Member

waruqi commented Oct 24, 2022

maybe you just need add a phony target and disable it by default.

rule("plugin.vsxmake.buildall")
    on_buildcmd(function(batchcmds)
        -- add build all command
    end)
target("BuildAll")
    set_kind("phony")
    set_default(false)
    add_rules("plugin.vsxmake.buildall")

and UpdateVS too. plugin.vsxmake.update

we can add plugin.vsxmake.buildall as builtin rule.

@SirLynix
Copy link
Member Author

I though of that, but that won't prevent visual studio from starting two xmake process per targets when "build solution" is triggered.

I think it would be best to have it as a part of the vsxmake generator, as it's a common need.

@waruqi
Copy link
Member

waruqi commented Oct 24, 2022

I though of that, but that won't prevent visual studio from starting two xmake process per targets when "build solution" is triggered.

I think it would be best to have it as a part of the vsxmake generator, as it's a common need.

no, use rule/batchcmds will generate only one xmake process when you click BuildAll.

It just add custom command in vcproj.

@SirLynix
Copy link
Member Author

Yes, but with that the "build solution" button won't have a correct behavior, which means the shortcut control+shift+B visual studio users are used to will rebuild a lot of files multiple times. This is the main issue which cannot be fixed by a user project.

@waruqi
Copy link
Member

waruqi commented Oct 24, 2022

Yes, but with that the "build solution" button won't have a correct behavior, which means the shortcut control+shift+B visual studio users are used to will rebuild a lot of files multiple times. This is the main issue which cannot be fixed by a user project.

? if we use BuildAll target + rule/batchcmds, and add xmake build --all custom command in vcproj, It will only build incrementally, not rebuild a lot files when we click BuildAll

@SirLynix
Copy link
Member Author

It will build correctly if you build that "BuildAll" target, yes.

But the issue I'm talking about is using the "Build solution" button:
.

With the current vsxmake generator this will try to build every single project, starting two xmake process for each which will conflict and wait for each other, and build files in a non-optimal order or rebuild every file multiple times when using "Rebuild solution".

@waruqi
Copy link
Member

waruqi commented Oct 24, 2022

oh, got it.

@SirLynix
Copy link
Member Author

I will try to implement this.

I was also thinking of reworking vsxmake projects to use "Makefile" type which allows to override Visual Studio behavior when compiling, for example:

<PropertyGroup>
  <NMakeBuildCommandLine>$(_XmakeExecutable) config $(_XmakeCommonFlags) $(_XmakeConfigFlags) && $(_XmakeExecutable) build $(_XmakeCommonFlags) $(_XmakeBuildFlags) $(_XmakeTarget)</NMakeBuildCommandLine>
  <NMakeReBuildCommandLine>$(_XmakeExecutable) config $(_XmakeCommonFlags) $(_XmakeConfigFlags) && $(_XmakeExecutable) build -r $(_XmakeCommonFlags) $(_XmakeBuildFlags) $(_XmakeTarget)</NMakeReBuildCommandLine>
  <NMakeCleanCommandLine>$(_XmakeExecutable) config $(_XmakeCommonFlags) $(_XmakeConfigFlags) && $(_XmakeExecutable) clean $(_XmakeCommonFlags) $(_XmakeCleanFlags) $(_XmakeTarget)</NMakeCleanCommandLine>
  <NMakeOutput>$(OutDir)$(TargetName)$(TargetExt)</NMakeOutput>
</PropertyGroup>

This is similar to what Unreal Engine does (since it uses a custom build tool), what do you think?

@waruqi
Copy link
Member

waruqi commented Jun 25, 2024

NMakeBuildCommandLine will override whole vs build command?

@SirLynix
Copy link
Member Author

Yes, when the project has type "Makefile" it expects you to give build commands and bypasses normal VS behavior.

It means all projects use the "Makefile" configuration type instead of binary/shared/static but those are not used anyway since xmake handles compilation.

https://learn.microsoft.com/en-us/cpp/build/reference/nmake-property-page?view=msvc-170

@waruqi
Copy link
Member

waruqi commented Jun 25, 2024

This seems to be a nice feature. you can try it.

@Domain
Copy link
Contributor

Domain commented Sep 13, 2024

One simple solution is: set all other projects to non-default target, only BuildAll project is the default target. Then build solution will build the BuildAll project only. But I cannot call xmake again inside on_buildcmd, no matter what I used: os.run, task.run, process.open, all failed.

maybe you just need add a phony target and disable it by default.

rule("plugin.vsxmake.buildall")
    on_buildcmd(function(batchcmds)
        -- add build all command
    end)
target("BuildAll")
    set_kind("phony")
    set_default(false)
    add_rules("plugin.vsxmake.buildall")

and UpdateVS too. plugin.vsxmake.update

we can add plugin.vsxmake.buildall as builtin rule.

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

No branches or pull requests

3 participants