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.
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.
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>
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.
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.
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.
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.
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".
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"
Related
I am having an awful time understanding how MSBuild works with NET Core project files (csproj) on Windows 11. I have 71 NET Core C# project files (executables, libraries, test projects). They all compile and run properly under Visual Studio or with msbuild batch jobs that build and PUBLISH to a publish folder on the command line.
BUILDING LOCALLY PRODUCES DIFFERENT BIN/* FOLDERS
But when I run MSBuild (with the same command-line arguments) on the 71 projects to build locally (not publish locally), some of the projects produce different output folders.
Some of them create bin/Debug/* folders, some create bin/x64/Debug/ folders, and some projects produce both types of folders. The “*” part is framework/runtime, which is net5.0-windows/win-x64 on my system.
Here is what my typical NET 5.0 project file looks like:
<PropertyGroup>
<Platforms>AnyCPU</Platforms>
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetFramework>net5.0-windows7.0</TargetFramework>
<SelfContained>false</SelfContained>
<IsPackable>false</IsPackable>
<IsPublishable>false</IsPublishable>
// The IsPublishable setting makes no difference.
// The build operation is not a publishable operation.
</PropertyGroup>
Here is what my MSBuild command looks like for all 71 projects
MSBuild /t:Restore;Build /p:Configuration=Debug /p:Platform=x64 /p:RuntimeIdentifier=win-x64 csproj-file-pathname
I have done many experiments, including completely deleting the obj and bin trees before running the MSBuild command lines, but nothing works. I cannot see any discernible relationships among project files, types of projects (lib or exe or app), and MSBuild command line arguments that would explain the different local build output folders.
Does anyone know what would make some projects create different output folder structures (and contents) if the project files are the same and the MSBuild arguments are the same?
Does anyone know for sure exactly what bin/* output folders should be produced by the msbuild arguments shown above? I have spent hours fighting the issue without success. Thank you.
MSBuild Structured Log Viewer is going to be your friend here. Whenever I need to know exactly what MSBuild is doing, I break this tool out.
I made a couple of library projects to show you what's going on
Here's the solution configuration for x64
I build the solution with the same properties you are using.
I'm pretty familiar with MSBuild and I know what property to look for, for the final copy. So I search for $property OutDir. This means I'm looking for an MSBuild property with the name that contains OutDir.
As you can see, we're pretty much getting the same situation you described. Some have bin\x64\Debug while some are just bin\Debug. They all have their target framework appended but they also have their runtime identifier appended.
If we want to see the project exactly as MSBuild sees it. We can expand the evaluation folder and click the "Preprocess" from the context menu. This will be a monster xml. This is actually your csproj in its full expanded glory after all the .props and .targets imported from the .NET SDK and from your repo.
You can get this file from the cli as well with MSBuild -preprocess[:file] option.
There's a lot of stuff going on but really we're only looking for stuff that directs the output. I know OutputPath is used in OutDir so I search for OutputPath and jump around. I find that the special .targets file that controls default outputs is called Microsoft.NET.DefaultOutputPaths.targets. Here's the relevant portion:
<Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
<Platform Condition="'$(Platform)'==''">AnyCPU</Platform>
<PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
<BaseOutputPath Condition="'$(BaseOutputPath)' == ''">bin\</BaseOutputPath>
<BaseOutputPath Condition="!HasTrailingSlash('$(BaseOutputPath)')">$(BaseOutputPath)\</BaseOutputPath>
<OutputPath Condition="'$(OutputPath)' == '' and '$(PlatformName)' == 'AnyCPU'">$(BaseOutputPath)$(Configuration)\</OutputPath>
<OutputPath Condition="'$(OutputPath)' == '' and '$(PlatformName)' != 'AnyCPU'">$(BaseOutputPath)$(PlatformName)\$(Configuration)\</OutputPath>
<OutputPath Condition="!HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath>
The first part of your question can finally be answered. For projects that build under the AnyCPU solution (even when you specify x64), you don't get the $(Platform) in the output. You can see that in my example: only net6lib has x64 in the OutDir.
So what about the runtime identifier, I don't see it in this .targets file. It's actually expanded on a little later in a different file: Microsoft.NET.RuntimeIdentifierInference.targets.
Relevant portion with comment
<!--
Append $(RuntimeIdentifier) directory to output and intermediate paths to prevent bin clashes between
targets.
But do not append the implicit default runtime identifier for .NET Framework apps as that would
append a RID the user never mentioned in the path and do so even in the AnyCPU case.
-->
<PropertyGroup Condition="'$(AppendRuntimeIdentifierToOutputPath)' == 'true' and '$(RuntimeIdentifier)' != '' and '$(_UsingDefaultRuntimeIdentifier)' != 'true'">
<IntermediateOutputPath>$(IntermediateOutputPath)$(RuntimeIdentifier)\</IntermediateOutputPath>
<OutputPath>$(OutputPath)$(RuntimeIdentifier)\</OutputPath>
</PropertyGroup>
And there's the last part of your output portion. $(TargetFramework) gets inserted in there as well between the previous target I mentioned and this target but you already knew that.
There is no madness here at all. MSBuild is following exactly what it's been told to do.
Hopefully this helps some!
Is there a way in Visual Studio to define some files or resources to be used only in specific build configurations? We use many #if DEBUG clauses to add debug-only code, but the same can't be done in a .config xml file, for example. Is there a way to define two versions of that file to be used, depending on whether the build configuration is set to Debug or Release?
I found this that describes what I'm looking to do but for Android using Ant. Is there a similar mechanism for Visual Studio and .NET?
Is there a way in Visual Studio to define some files or resources to be used only in specific build configurations?
According to this doc: MSBuild concepts which mentioned “MSBuild provides a basic XML schema that you can use to control how the build platform builds software.”, I think MSBuild could help you solve this issue.
Is there a way to define two versions of that file to be used, depending on whether the build configuration is set to Debug or Release?
MSBuild has four parts: properties, items, tasks, and targets. For this issue you may need to focus on “items” part.
Solution:
You could add this command line “Condition=”’$(Configuration)’==’Debug’” and “Condition=”’$(Configuration)’==’Release’” to control when(Debug/Release) to use different versions of resources.
Refer to following screenshot, and this link(List of common properties and parameters-- Condition).
I have a CMake-based C++ project, and recently I've included existing C# program into it.
Here is CMake code:
include_external_msproject(MarkTrainingSet MarkTrainingSet.csproj
GUID 77A5B8C9-998E-4D0E-A444-6AD14FB0DC37
PLATFORM AnyCPU)
The .csproj file was generated by the same Visual Studio 2013, as builds my C++ project. GUID value and AnyCPU platform are the values from that file.
My problem is that this C# project is not built when I issue Build solution command to the Visual Studio.
I have to go to the solution properties (right-click on the solution in Solution Explorer), then Configuration Properties -> Configuration, and manually check Build checkbox in the line, corresponding to my MarkTrainingSet project.
If CMake regenerates the solution, I have to recall about that checkbox and redo the procedure.
The documentation about include_external_msproject is very incomplete.
What should I do to make this C# project always build automatically?
The last time I looked, CMake's implememtation of include_external_msproject() is restricted to C/C++ projects.
You may find this defect report worth a look, though it looks stale. http://www.cmake.org/Bug/view.php?id=9742 ... ( also see http://marc.info/?l=cmake&m=133319401303885 )
I couldn't get a sense of whether the patches were included in CMake or not though, but the defect is still open.
Generally syntax looks like this:
include_external_msproject(projectname folder/projectname.csproj PLATFORM AnyCPU)
Seems to work with vs2019 included cmake.
I am writing a utility for my company that will batch build a number of solutions in a one-click fashion. There are about 8 solutions in all, and each one has an average of 20 projects. The utility needs to be able to capture the build log and the total number of errors for each solution, just as is done when you build at the command line. I know I this is the command to accomplish that
msbuild mysolution.sln /t:build /verbosity:minimal /maxcpucount:xx
However, I would like to make use of the Microsoft.Build.Evaluation API's if possible. I know the Project object can load a single project, but is there anyway to build an entire solution? I intend to build this utility to make use of the all cpus/cores on the system and build multiple solutions simultaneously. I've looked at the MSDN page for Microsoft.Build.Evaluation, though the documentation is (still) abysmal.
Thanks for any help you can offer!
Jason
You do not need a Visual Studio solution file (sln) to build multiple projects. As you may know, Visual Studio project files are just MSBuild XML files and they can fall other project files. Therefore, build a project file that builds the other projects as required. This can be done in one of two ways.
First, solution files are just MSBuild XML so anything that can generate XML can generate a solution. See the MSBuild XML Schema for more information.
Second, construct a Microsoft.Build.Evaluation.Project programmatically using the constructor that takes an Microsoft.Build.Construction.ProjectRootElement instance then call Project.Build(). The ProjectRootElement has methods for adding common element types such as CreateTaskElement(), CreatePropertyElement() and CreateTargetElement().
See also:
Replace .sln with MSBuild and wrap contained projects into targets
Generating an MSBUILD project file from a visual studio solution file and project files.
Has anyone done any development of Compass for CSS/SASS in a standard C# ASP.NET environment?
Is there a single distribution I can just download that's ready to go for Windows or do I need install every piece of the equation and build compass myself?
Are there any plugins that make developing with Compass friendlier with VS2008 such as automagical handling of Compass/SASS in builds, syntax highlighting, and/or intellisense support?
If there aren't any VS IDE plugins what are the best options for a standalone text editor for handling coding in Compass?
To complete the last answers, you can install Web Workbench, a plugin for Visual Studio 2010 wich add syntax highlighting, intellisence and some other stuff for the SASS language (SCSS syntax only).
If you prefer using Compass and/or some other tools to compile your CSS, you should disable the built-in compiler. I listed some other SASS compilers here: Using SASS with ASP.NET.
To disable the built-in compiler: select the .scss file in Solution Explorer, go to the Properties window and delete the text from the Custom Tool box.
Since Web Workbench 3 you can now manage more easily what you want to compile with this plugin. See the Mindscape > Web Workbench Settings menu item.
Getting started with Compass,
First yes I have to install Ruby and the compass source and compile up my version of compass I followed the instructions on Compass's Wiki Getting Started.
After getting Compass and all it's dependencies installed and built I created my first project.
compass -f blueprint project-name
Which creates a default project with compass for the blueprint css framework, currently there's a bug in compass with the creation of the grid.png file in the images directory for compass so you need to copy the original grid.png from the source folder
C:\Ruby\lib\ruby\gems\1.8\gems\chriseppstein-compass-0.8.10
\frameworks\blueprint\templates\project
Or similarly located file depending on where you installed everything. One of the most important changes IMO for working with compass on asp.net is to change the SASS CACHE directive of compass. The SASS CACHE creates a bunch of temporary folders in your project directory which probably would have poor outcomes if they ended under source control. So open up config.rb and add this line
sass_options = {:cache_location =>
"#{Compass.configuration.project_path}\\tmp\\sass-cache"}
Make sure to note the escaped backslashs.
After this I modified the names of the folders that compass uses for how I wanted them named inside the config.rb and started getting to it with SASS and Compass. I recommend watching the hour long introduction to compass video it's very helpful and I learned alot from it: Watch the screen cast.
One of the things which this showed me was how to set compass to watch for file system changes and automagic compile the sass to css. By using
compass -w
This is working real well for me, just make sure you keep your css files checked out or turn them off read only if they're under source control if your project doesn't support concurrent checkouts.
For editing I'm using SciTE that's included with Ruby by default for the config.rb files or just the editor window in VS2008. For Sass I came across a big list on the HAML website. jEdit with highlighting syntax file for SASS was what I ended up using after trying a few. I'd still like to find a VS plugin for syntax highlighting so I don't need to use another editor but jEdit is definitely getting the job done.
My answer is a bit antiquated. Before following my original answer, I would recommend exploring the Nuget package SassAndCoffee. The full details can be found here.
How does it work?
SassAndCoffee embeds the original
compilers in the DLL as (Sass 3.2.0
and CoffeeScript 1.1.0 as of this
writing) and uses IronRuby and
Jurassic respectively to execute the
compilers against your source.
Why is
this better than [SOMEOTHERPROJECT]?
No external processes are executed
You don’t have to install Ruby or node.js
It’s in NuGet so you don’t have to fiddle with web.config
Files are cached and are rebuilt as-needed.
I wanted to add another alternative here. If you just want to ensure that compass builds the sass files and includes the css files when you build your ASP.net project you can add the following to your project(csproj) file under the project section:
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release' ">
<Exec Command="compass compile --output-style compressed --force" />
<ItemGroup>
<Content Include="Styles\*.css" />
</ItemGroup>
</Target>
<Target Name="AfterCompile" Condition=" '$(Configuration)' == 'Debug' ">
<Exec Command="compass compile" />
<ItemGroup>
<Content Include="Styles\*.css" />
</ItemGroup>
</Target>
The first Target is for Release and will also compress the css, the other one is for Debug.
If you want to customize paths add a config.rb to the project root folder:
css_dir = "Content"
sass_dir = "Content/Sass"
This all of course requires compass and ruby to be installed and to be in the path of your machine.