Execute an MSBuild target only once per a solution build - msbuild

Given a Visual Studio solution composed of arbitrary number of projects all sharing a Directory.Build.targets file with a target called PrintEnvVars.
How could I ensure that the target PrintEnvVars gets called only once per entire solution build? Preferably during the build of the first project of the solution (in the project build order).

Related

Merging projects under one solution with single exe file

I have various small apps which I would like to to gather under a new application where they can all be accessed from one "exe" file. I have merged the projects into a solution called "ETABS SUIT" and referenced the projects.
I was expecting and hoping to have just one executable file in the debug folder when I build the solution, but it seems like all projects are built separately with standalone exe files.
Is there a different way to combine all my projects under a new solution and get a single exe file when built? (It may be also okay if I can check a boolean value provided in the main solution before starting the other projects but what I define in the main solution is not recognized in added projects)

Build Multiple Projects in a Single Solution for VSTS

I'm in this case, I have a single solution built on Visual Studio 2013. It contains more than 10 projects that reference each others, I need only to build and release 3 projects of them on Azure via Visual Studio Team Services so the question is what is the best approach to do this
Thank you
If they all reference each other than you may need to build all of them. Dependencies will be resolved at build time.
You can reference individual Project files in place of a Solution. You will then need to maintain order yourself.
Just use the same build step for building a Solution, but fill out a Project (.proj) file instead. Control the order by having multiple build steps.
Please read my Suggestions below-
- Copy all the references dll's in one shared folder through Post build event.
- Create new solution according to your deployment needs and take all references from the shared folder in all projects.
- Deploy the solution you want
If the references are project references, you just need to specify the solution file (.sln) to build, otherwise, you need to specify project dependence (Right click your solution=> Project Dependence=>Select a project=>Check the projects’ options that dependence to)

MSBuild - Project Dependencies Build Order Anomaly

We have an MSBuild .proj file that is used to build and run lots of projects. That have file references to one another. Due to the fact that it is file references, we maintain the list of Project Dependencies on the solution, so that MSBuild is able to identify the order to execute projects in.
We had an issue recently, where our US development team added a new reference to one project, but didn't update the dependencies list. This builds fine for them locally, and on the server. However for the UK team, the build consistently failed for all developers.
I'm trying to understand why this was the case. The only thing I can think of is that our Culture causes the build order to be slightly different when two projects are essentially ranked at the same level. i.e. If Project A and B are perceived to have the same dependencies, then the order the two build in is arbitrarily determined, and this might be different in the UK culture vs the US culture.
That said, my machine (it broke for me) has the Region Format set the English US. And Location UK.
Does this sound feasible? or is there a better explanation for this?
Changing the culture will not fix the issue where you're making a file reference on a components output rather than a project reference to the project that will build the assembly.
Solution files do map dependencies and would help MsBuild determine build order. When MsBuild processes a solution it will first convert it in memory to MsBuild xml format, then it will determine project order by listing the dependencies, then determine if a project needs to be rebuilt by comparing the last update time of the input files to the output files.
When you have a project reference within a project (in a project, open the References folder, remove references to output assemblies and instead reference the project itself). This will modify the project file replacing Reference item groups with ProjectReference item groups. This allows MsBuild to make this determination on a project level and resolves the issue of having to manually configure the project build order.

Jenkins and MSBuild and Copy Artifacts Plugin and proper usage for multiple projects

My problem boils down to this base case: our solution has two projects, A and B, which project C then includes into its build process.
When someone pushes to project A or B, Jenkins builds the project using MSBuild, archives the artifact, and then kicks off a build of C.
When C begins, it has four "Copy Artifacts" tasks that need to run: first, it copies the artifacts from A into .\A\obj\Release\, then it copies the same artifacts into .\A\bin\Release. Then it repeats for project B. Then it builds itself.
That's right: for each project C relies on, Copy Artifacts has to be run twice, or else MSBuild detects that something is out of date and the whole thing is built from scratch.
Is there an easier way to do this? Can I pass a parameter to MSBuild (or configure the .csproj) that says "only build this project, assume the other project binaries are up-to-date, regardless of the timestamp"? Is there a better plugin that will take care of this for me?
This is really annoying (and confusing) in our real-world case where we've got almost 20 different projects, with layered dependencies between them.
You can pass BuildProjectReferences=false into MSBuild to tell it to skip auto-building references and just build the project indicated.

Versioning CommonAssemblyInfo.cs and MSBuild

So I have a CommonAssemblyInfo.cs linked into all the projects in my solution and is dynamically generated by my rake/albacore scripts which is not checked into source control.
I also have a CommonAssemblyInfo.cs.local for use when there is no ruby available, mainly to be used by devs.
Is it possible to have a msbuild task or something that runs before any of the other project compilation that will copy CommonAssemblyInfo.cs.local to CommonAssemblyInfo.cs before trying to compile my solution? I hate having to have a command you have to just know about and type in order to open and buidl the solution in Visual Studio.
UPDATE
So I ended up using a batch file as a solution wide pre-build event as described here: Solution-wide pre-build event?, it checks to see if CommonAssemblyInfo.cs exists and if not copies CommonAssemblyInfo.cs.local to CommonAssemblyInfo.cs just using a simple batch file.
This is the solution I ended up with.
I have each project in the solution link to a CommonAssemblyInfo.cs which is automagically generated for me by my build scripts (rake + albacore).
Since I cannot check CommonAssemblyInfo.cs into source control, I create a CommonAssemblyInfo.cs.local.
Simple solution: create go.bat which copies CommonAssemblyInfo.cs.local to CommonAssemblyInfo.cs that devs must run the first time they check out the project before opening the solution in VS.
For purely political reasons, if I did this people would have had hissy fits about me doing "nonstandard" things. Complex solution follows:
I created a project in the solution called PreBuild which every project in the solution depends on. This forces the build order to be such that this project is built first. This project contains a pre-build event which calls the following batch file:
echo verifying CommonVersionInfo.cs exists
cd
IF NOT EXIST ..\..\..\CommonAssemblyInfo.cs COPY ..\..\..\CommonAssemblyInfo.cs.local ..\..\..\CommonAssemblyInfo.cs
So now any developers who choose to keep their heads in the sand may checkout the project and blissfully open it up in VS unaware that any build scripts exist at all.
Are you talking about compilation in the VS IDE, or compilation through team build? If you are talking about team build, then you can use the "AfterGet" event as a place to use the standard "copy" msbuild task. If you are talking about the VS IDE, then you can still use the "copy" msbuild task.