views:

784

answers:

8

When using Visual Stdio 2008, you can make a C++ project build with an internal tool rather than having the IDE invoke MSVC directly. This improves the consistency of builds across platforms if a cross-platform build system is used.

However, I cannot figure out how to do the same as a C# project. It would be possible to simply register it as a native project with C# sources, however, you lose some of the advantages gained through having a C# project. More importantly, it will mean that allowing a project to build both directly and with an external tool (which is sadly necessary) will require two separate projects, rather than merely creating an alternate build configuration to invoke the external tool.

Does anyone know if it's possible to prevent Visual Studio from invoking csc by itself and instead call an external tool?

EDIT: Apparently there has some misunderstanding. The goal here is not to compile anything outside of Visual Studio. Instead, it's to allow Visual Studio to serve as the IDE but not the build system. There is already a (Scons-based) build system capable of compiling the C# and C++ sources, and Visual Studio has been configured to invoke Scons for compilation of C++ projects. I'm trying to configure it so that when you hit the 'Build' button, it will invoke Scons for the C# projects as well as the C++ ones.

A: 

Under 'Tools' > 'External Tools' you should be able to define an outside tool to do activities for you. The Command should be the path to the executible for your external tool.

Hope this helps some.

Chris
This wouldn't integrate well with other systems, like the debugger.
coppro
+3  A: 

Edit: Your question is still answered using MSBuild(if you are simply looking to compile outside the IDE). The IDE(Visual Studios) is simply a "fancy" way of constructing the build files that are built by MSBuild. Visual Studios isn't building the files, it simply is invoking MSBuild which ships with the .NET Framework 2.0 and up which compiles your code based on the project file that you create. If Scons can read and process an MSBuild file then I'm sure you can invoke it to build your project. But considering the fact that C# is a Microsoft language, I think you will be hard-pressed to find a value-add in not using MSBuild since I'd assume both the language and build tool are very tuned to work together. - End Edit

You can use MSBuild to compile your C# project. If you open your .csproj file in a text editor you will see that it is a MSBuild file. If you want to write some C# outside of the IDE you can construct a build file using the .csproj file as a starting point and invoke MSBuild to compile your apps. The IDE is just a way of abstracting the editing of the MSBuild file away for you.

If you are really industrious you can create a set of custom tasks to do things in your custom build process like move files around and versioning. MSBuild Community Tasks are a great example of using custom code to do task for you during MSBuild.

Achilles
I am not looking for a way to compile outside the IDE at all. I'm trying to click the 'compile' button inside the IDE and have it invoke Scons. I can do this for C++ using a Makefile project. The build works fine with Scons now, I am just looking for IDE integration.
coppro
A: 

You don't have to maintain different project files to build using an external tool. MSBuild is designed to build using the same project files that Visual Studio uses.

Here's an article that describes it.

Customize Your Builds in Visual Studio Using the Standalone MSBuild Tool

It's for VS2005, but should apply to VS2008 as well.

Doug
+2  A: 

I found a question in the same direction here, where it is suggested to edit the registry. I am pretty sure there is no other way to change the compiler used by Visual Studio because there is no trace of csc.exe in any solution, config, csproj file or whatsoever, nor in the Visual Studio 9.0 folder / subfolders within the Program Files dir.

Registry locations can be found in:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\74ACAA9F1F0087E4882A06A5E18D7D32
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\9055DA7481CC1024CB23A6109FD8FC9B

but those keys may differ dependng on your installation. Conclusion: changing the compiler used by VS seems next to impossible.

Addition: The following MSDN article deals with the same question for an custom C++ compiler, and Ed Dore's answer seems to confirm my theory that there's no way to choose an custom compiler for use within VS.

Webleeuw
Ah, very neat info, and close to what I'm looking for, but not quite it - I'm not really trying to replace the compiler; rather to tell MSVC not to use it (if that makes sense)
coppro
Reading your comment on Achilles' post I understand that you'd like to invoke Scons when you click the build option in VS. I doubt if you can do that otherwise than replacing csc.exe with an external command within the registry. Thus your comment doesn't make mucht sense to me ;).
Webleeuw
A: 

You can build your solution from the command line like this: -

C:\WINDOWS\Microsoft.NET\Framework\v3.5>msbuild.exe "C:\path\Your Solution.sln"

Cheers,

Phil.

Plip
Did you read coppro's comment and the other answers before posting? He said he's not looking for a way to compile outside VS, but a way to replace the call to csc.exe from within VS.
Webleeuw
+3  A: 

Given all the other answers, what MSBuild does when either VS or MSBuild perform a build can be found in the Targets files that ship with .Net. These can be be found in the FrameWork directory on your system. In my case:

C:\Windows\Microsoft.NET\Framework64\v3.5

Contains Microsoft.Common.targets among others. This file contains the following snippit:

<!--
============================================================
                                    Build

The main build entry point.
============================================================
-->
<PropertyGroup>
    <BuildDependsOn>
        BeforeBuild;
        CoreBuild;
        AfterBuild
    </BuildDependsOn>
</PropertyGroup>
<Target
    Name="Build"
    Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
    DependsOnTargets="$(BuildDependsOn)"
    Outputs="$(TargetPath)"/>

This means that redifining this Target you can make MSBuild an VS do anything you want. The top of the mentioned file contains an important messagge:

Microsoft.Common.targets

WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
    created a backup copy.  Incorrect changes to this file will make it
    impossible to load or build your projects from the command-line or the IDE.

This file defines the steps in the standard build process for .NET projects.  It
contains all the steps that are common among the different .NET languages, such as
Visual Basic, C#, and Visual J#.

My suggestion would be to read all you can about MSBuild and it's build file syntax and try redifining the Build target in your project(s). My impression is that after reading up on MSBuild you'll probably find an easier way to meet your requierements. You can find an example of redifining a Target like this in one of the answers of this so question .

Edit:

How to redefine a target? Redefining is essentially defining the same target 'after' it has been defined. So for instance in your .*proj file(s) define a Build Task after the <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> line that imports all targets needed to in this case build a C# project. An example could be

<Target
 Name="Build"
 Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
 DependsOnTargets="BeforeBuild"
 Outputs="$(TargetPath)">
 <Exec Command="nmake" />
</Target>
Bas Bossink
I'm confused. How do I redefine it to make it do something different?
coppro
A: 

Edit your project file and update the CscToolPath keys to point to the directory containing your tool and add CscToolExe keys that holds the name of the directory:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|.NET 3.5' ">
   .
   .
   .
   <CscToolPath>path\to\custom\tool\directory</CscToolPath>
   <CscToolExe>exe name</CscToolExe>
   .
   .
   .
</PropertyGroup>

I have not tested this, and the CscToolExe key may cause problems, in which case I would simply rename the external tool executable to "csc.exe".

Oded
While I like that suggestion, that's not an option; SCons would have a heart attack if you passed it all the csc flags
coppro
In that case, prhaps a custom .targets file that will call SCons with the parameters you want will work? You can base it off the CSharp one, and in the project file change the import to your custom .targets file: <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Oded
A: 

Looking through the answers, it seems clear to me that integrating scons into Visual Studio in a way that is compatible with the debugger and so on is not going to happen...

An option you might to consider, and I understand you don't want to change build systems, but bear with me, is to use a meta-build system, ie 'cmake'. http://www.cmake.org/

Cmake doeesn't actually build the project. What it does is to create build files for you, that you can use to build the project, and on Windows, the build files it creates for you are: Visual Studio project files. You can simply load those directly into your IDE, and compile, and use normally!

CMake is I feel very easy to use, and provides a high level of transparence and maintainability.

The exact same CMakeLists.txt files on linux will causes linux makefiles to be generated.

On mingw, they can generate mingw makefiles.

There are numerous generators available within cmake. The list is here:

http://www.cmake.org/cmake/help/cmake-2-8-docs.html#section_Generators

http://springrts.com is a huge opensource rts game that used to use scons as its cross-platform build system and now uses cmake.

I understand that you don't really want to have to change build systems, so it is a medium to long term solution.

Cmake is in any case one more option, to add to those of using a custom build tool, or using msbuild, or running the scons build from the commandline by hand.

Hugh Perkins