Using T4MVC with build script - model-view-controller

Has anyone gotten T4MVC to run as part of a build script ? Preferably a NAnt build script.
I'd like to not have to check in the generated files and just have the build server create them as part of the build, but T4MVC will only run inside of Visual Studio.
I've tried:
http://devtalk.dk/2010/03/11/How+To+Run+T4MVC+On+Build.aspx
http://otac0n.com/blog/2010/12/23/Pain-Free-T4MVC.aspx
Has anyone successfully gotten a solution to work ?

I don't think you'll be able to make this work. T4MVC relies heavily on the DTE object model, and that simply is not available outside of VS.

Related

Does devenv.com work with extensions?

I am using this extension (https://github.com/ceztko/SolutionConfigurationName) to put solution output all in one folder. It is working splendidly on our development machines. (I modified the source to support VS2012 installation)
We are now trying to run a build using devenv.com, but it seems that the macros are not being evaluated properly --or rather, they are an empty string ""
Does anyone know if devenv.com plays nice with extensions? Or maybe the workflow for a headless build is different such that the extension is not getting triggered? It uses UpdateSolution_Begin to update the variables.
tia
A headless build won't load that extension, and definitely won't go triggering solution events like that.
To be honest, this feels strongly like an XY problem. A solution build results in the MSBuild Configuration property being specified to each individual project, and I can't think of any scenario where you wouldn't simply be able to base a build customization on that property. For the Roslyn codebase itself we direct all OutDirs for all projects by simply having a single msbuild .targets file that defines the output path, and then we include that in all projects. Very clean, and doesn't require VS extensions to be installed, or even VS installed at all in order to do a build.

Pre-build event to run before any project in a solution is built

I have a little program I wrote to download all NuGet packages for a solution. I would like to setup a pre-build event that would run this program every time I build.
But I need it to run before the first project starts to build. I could look at what is currently building first, and put it on that project's pre-build event, but that is fairly brittle. Any time I add a new project or update references between projects, I would have to double check that the "first" building project is still the first one.
So, what I really need is a way to do this before any building really starts. I have heard of Visual Studio macros. But those are not something that gets checked in so I would prefer to not use those (but if that is my only option, I would use them).
You could try this: http://sedodream.com/2010/10/22/MSBuildExtendingTheSolutionBuild.aspx
Unfortunately it only works called from the command line via MSBuild. Seems to be a design flaw that the behaviour is different and these events are not available via the IDE.
You could also modify your base MSBuild tasks to include the action based on a specific flag/file existence/solution name, but this is all sorts of evil.
Otherwise, you are pretty stuck with a prebuild on each project.
I call nuget install from the prebuild event for any project that uses nuget packages. It is smart enough to only download packages that have not already been downloaded.

How to integrate Google Closure Compiler as a build step in Visual Studio 2010

Is there any reference or tutorial for this? And if it's possible, have the javascript file being built only if the file is modified.
You might be able to try this:
http://closurecompiler.codeplex.com/documentation,
But I couldn't get it to work and ended up writing a batch file and hooked it up as a post-build process in the project properties. I've been pretty happy with that solution as it allows me to easily (and in a more standardized fashion) tweak the closure parameters. And any errors from it get reported to you whenever you build.

Good techniques to use Makefiles in VisualStudio?

I know the ideal way to build projects is without requiring IDE based project files, since it theoretically causes all sort of trouble with automation and what not. But I've yet to work on a project that compiles on Windows that doesn't depend on the VisualStudio project (Ok, obviously some Open Source stuff gets done with Cygwin, but I'm being general here).
On the other hand if we just use VS to run a makefile, we loose all the benefits of the compile options window, and it becomes a pain to maintain the external makefile.
So how do people that use VS actually handle external makefiles? I have yet to find a painless system to do this...
Or in reality most people don't do this, although its preached as good practice?
Take a look at MSBuild!
MSBuild can work with the sln/csproj files from VS, so for simple projects you can just call them directly.
if you need more control, wrap the projects in your own build process, add your own tasks etc. - it is very extensible!
(I wanted to add a sample but this edior totally messed up the XML... sorry)
Ideally perhaps, in practice no.
Makefiles would be my preference as the build master, however, the developers spend all their time inside the visual studio IDE and when they make a change, it's to the vcproj file, not the makefile. So if I'm doing the global builds with makefiles, it's too easily put out of synch with the project/solution files in play by 8 or 10 others.
The only way I can stay in step with the whole team is to run devenv.exe on the solution files directly in my build process scripts.
There are very few makefiles in my builds, where there are they are in the pre-build or custom build sections or a separate utility project.
One possibility is to use CMake - you describe with a script how you project is to be built, and CMake generates the Visual Studio solution/project files for you.
And if you need to build your project from the command line, or in a continuous integration tool, you use CMake to generate a Makefile for NMake.
And if you project is a cross-platform one - you can run CMake to generate the makefiles for the toolchain of your choice.
A simple CMake script looks like this:
project(hello)
add_executable(hello hello.cpp)
Compare these two lines with a makefile or the way you setup a simple project in your favorite IDE.
In a nutshell CMake does not only cross-platform-enables your project it also makes it cross-IDE. If you like to just test your project with eclipse or KDevelop, or codeblocks, just run CMake to generate the corresponding project files.
Well, in practice it is no always so easy, but the CMake idea just rocks.
For example, if you consider using CMake with Visual Studio there is some tweaking required to obtain the familiar VS project feeling, main obstacle is to organize your header and source files, but it is possible - check the CMake wiki (and by writting a short script you might even simplify this task).
We use a NAnt script, which at the compile step calls MSBuild. Using NAnt allows us to perform both pre- and post-build tasks, such as setting version numbers to match source control revision numbers, collating code coverage information, assembling and zipping deployment sources. But still, at the heart of it, it's MSBuild that's actually doing the compiling.
You can integrate a NAnt build as a custom tool into the IDE, so that it can be used both on a build or continuous integration server and by the developers in the same way.
Personally, I use Rake to call msbuild on my solution or project. For regular development I use the IDE and all the benefits that provides.
Rake is set up so that I can just compile, compile and run tests or compile run tests and create deployable artifacts.
Once you have a build script it is really easy to start doing things like setting up continuous integration and using it to automate deployment.
You can also use most build tools from within the IDE if you follow these steps to set it up.
We use the devenv.exe (same exe that launches the IDE) to build our projects from the build scripts (or the command line). When specifying the /Build option the IDE is not displayed and everything is written back to the console (or the log file if you specify the /Out option)
See http://msdn.microsoft.com/en-us/library/xee0c8y7(VS.80).aspx for more information
Example:
devenv.exe [solution-file-name] /Build [project-name] /Rebuild "Release|Win32" /Out solution.log
where "Release|Win32" is the configuration as defined in the solution and solution.log is the file that gets the compiler output (which is quite handy when you need to figure out what went wrong in the compile)
We have a program that parses the vcproj files and generates makefile fragments from that. (These include the list of files and the #defines, and there is some limited support for custom build steps.) These fragments are then included by a master makefile which does the usual GNU make stuff.
(This is all for one of the systems we target; its tools have no native support for Visual Studio.)
This didn't require a huge amount of work. A day to set it up, then maybe a day or two in total to beat out some problems that weren't obvious immediately. And it works fairly well: the compiler settings are controlled by the master makefile (no more fiddling with those tiny text boxes), and yet anybody can add new files and defines to the build in the usual way.
That said, the combinatorical problems inherent to Visual Studio's treatment of build configurations remain.
Why would you want to have project that "compiles on Windows that doesn't depend on the VisualStudio project"? You already have a solution file - you can just use it with console build.
I'd advise you to use msbuild with conjunction with makefile, nant or even simple batch file if your build system is not as convoluted as ours...
Is there something I'm missing?
How about this code?
public TRunner CleanOutput()
{
ScriptExecutionEnvironment.LogTaskStarted("Cleaning solution outputs");
solution.ForEachProject(
delegate (VSProjectInfo projectInfo)
{
string projectOutputPath = GetProjectOutputPath(projectInfo.ProjectName);
if (projectOutputPath == null)
return;
projectOutputPath = Path.Combine(projectInfo.ProjectDirectoryPath, projectOutputPath);
DeleteDirectory(projectOutputPath, false);
string projectObjPath = String.Format(
CultureInfo.InvariantCulture,
#"{0}\obj\{1}",
projectInfo.ProjectName,
buildConfiguration);
projectObjPath = Path.Combine(productRootDir, projectObjPath);
DeleteDirectory(projectObjPath, false);
});
ScriptExecutionEnvironment.LogTaskFinished();
return ReturnThisTRunner();
}
public TRunner CompileSolution()
{
ScriptExecutionEnvironment.LogTaskStarted ("Compiling the solution");
ProgramRunner
.AddArgument(MakePathFromRootDir(productId) + ".sln")
.AddArgument("/p:Configuration={0}", buildConfiguration)
.AddArgument("/p:Platform=Any CPU")
.AddArgument("/consoleloggerparameters:NoSummary")
.Run(#"C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe");
ScriptExecutionEnvironment.LogTaskFinished ();
return ReturnThisTRunner ();
}
You can find the rest of it here: http://code.google.com/p/projectpilot/source/browse/trunk/Flubu/Builds/BuildRunner.cs
I haven't tried it myself yet, but Microsoft has a Make implementation called NMake which seems to have a Visual Studio integration:
NMake
Creating NMake Projects
Visual Studio since VS2005, uses "msbuild" to define and run builds. When you fiddle with project settings in the Visual Studio designer - let's say you turn XML doc generation on or off, or you add a new dependency, or you add a new project or Assembly reference - Visual Studio will update the .csproj (or .vbproj, etc) file, which is an msbuild file.
Like Java's ant or Nant before it, msbuild uses an XML schema to describe the project and build. It is run from VS when you do a "F6" build, and you can also run it from the command line, without ever opening VS or running devenv.exe.
So, use the VS tool for development and command-line msbuild for automated builds - same build, and same project structure.

Is there a way to conditionally run Visual Studio Post Build Steps

What we are looking for is: while compiling the same configuration, say Release|Win32, is there a way to only do the postbuild steps sometimes. Like, if I am on a dev machine do all the post-build steps or if I am on a build server then don't do them. Or is the only way to accomplish this is by implementing a new configuration?
Commenters: Thanks for the ideas, we do not want to use scripts as they would be one more thing to maintain, and going to MSBuild proj files would be a lot of headache at this point as well. Thanks for trying though.
You could use environment variables in the post build script. Something like this:
if NOT %ComputerName% == DEVMACHINENAME GOTO end
c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ngen "$(TargetPath)"
:end
If you want to crack into MSBuild itself (.*proj files are essentially just MSBuild scripts), you can run machine-specific steps post-build: http://flimflan.com/blog/MachineSpecificTasksWithMSBuild.aspx
"This takes advantage of the fact that all environment variables are immediately available as properties in an MSBuild script; and that all Windows machines (that I've worked on recently) have the COMPUTERNAME environment variable set."
Would it be possible to implement your post build steps as an external script which is always executed, but has logic to conditionally perform the steps you require?
If you don't like to have a separate build configuration (which I think would make most sense) you could e.g. define an environment variable on your build server which you then can test for in you post-build script.

Resources