views:

78

answers:

4

Hello,

My solution has a library project which needs a special environment to be built (lots of external libraries and tools)... but it is not vital to our application. We'd like to avoid installing these tools when not necessary (most of our developers work on other parts of code).

We have created another project which has the same API, but has an empty implementation and is compilable without those external tools. I'd like to be able to easily switch between those projects and still get all the references in other projects correct.

I don't know VS/MSBuild very well, but willing to learn whatever is necessary. Is it possible? I am looking for ideas... We're using Subversion, and solutions involving some hacks inside VCS are also welcome.

+1  A: 

It sounds as if your library project is one that can be separated from your primary solution, taking the tool baggage with it. Doing that, you could build the speciality solution separately, an link the compiled assembly from the main solution.

Grant Palin
We'd really like to keep it as part of our main solution (this simplifies f.e. continuous integration setup), but if there will be no other ideas, I'll consider yours. Thank you.
liori
@liori If the external dependencies are in the form of libraries and standalone tools, you can add those to your source control, and refer to them as necessary. This would avoid the need for any "special setup".
Grant Palin
A: 

For discussion, I'll assume you have a project directory containing your solution file, a "RealLibrary\RealLibrary.csproj" project file (your "real" library, with the dependencies), and a "MockLibrary\MockLibrary.csproj" file (your "mock" library, with the empty implementations).

If I understand correctly, you want to easily "swap" the MockLibrary for the RealLibrary in your solution, and vice-versa.

The easiest/hackiest way to do this, assuming your solution (and dependent projects) are configured to look for the "RealLibrary.csproj" project, is to rename the "RealLibrary" directory (it doesn't matter to what), and rename the "MockLibrary" directory to "RealLibrary" and rename "MockLibrary.csproj" to "RealLibrary.csproj". This will effectively "trick" your solution and dependent projects into loading the "mock library" even though they are referencing the "real library".

A slightly more complex (and perhaps cleaner) solution is to actually modify your "sln" and "csproj" files to reference "MockLibrary.csproj" instead of "RealLibrary.csproj". In the "sln" file, you'll need to change the path to the project in the section near the top:

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RealLibrary", "RealLibrary\RealLibrary.csproj", "{E1714F9A-E1D9-4132-A561-AE2B4919391C}"
EndProject

You need to change that path "RealLibrary\RealLibrary.csproj" to "MockLibrary\MockLibrary.csproj". If you're going for completeness, you can change the name as well (or perhaps just use a generic name like "Library" for the name).

Likewise, in the dependent csproj files, you'll need to find all instances of the "ProjectReference" node where you reference "RealLibrary.csproj" and modify the path. These sections look like this:

<ProjectReference Include="..\RealLibrary\RealLibrary.csproj">
  <Project>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Project>
  <Name>RealLibrary</Name>
</ProjectReference>

You could relatively easily write some scripts to perform this swap. However, I think there's a deeper problem here that can be addressed more directly. I'll post that as a separate answer, but I wanted you to have the actual answer you were looking for first.

Stuart Lange
I guess I'd have to undo renaming anytime I'd like to `svn update`?
liori
Yeah, going with my first method could lead to some svn disasters. The second isn't quite as bad, but you still run into the possibility of conflicts on those sln/csproj files. If your intent is for developers to typically work with the "mock" library, I would check the solution into svn using that, and use a pre-build script in CI to swap in the "real" library. Developers could run that script ad-hoc if they needed to work with the "real" library.
Stuart Lange
A: 

The deeper problem I see here is that your library "needs a special environment to be built", specifically because it depends on "lots of external libraries and tools". I would suggest that you NOT go down the path of creating the mock library, but instead focus on getting the library to build correctly without a special environment. You can achieve this by including all of those dependencies in source control along with your project, and reference those dependencies via relative paths inside your working copy. In my build environments, I try to avoid static environmental dependencies as much as possible (ideally limiting it just to the .NET framework itself).

To get the dependencies into source control, you can either check them directly into the project itself, or you can check them into a different location and then "reference" them in your project via svn:external definitions. In my environment, I have a separate "bin" repository used just for these kind of third party library dependencies, and then many dependent projects can pull them in via externals.

If you can eliminate your library's build-time environmental dependencies, your build will be much more robust and it will be much easier for developers to work with the project.

Stuart Lange
These libraries/tools have costly per-seat licenses, take ~10GB of space after installation and need proper installation to function (some crazy scientific software). I have no influence on that. We already use svn:external for some smaller libraries though.
liori
Fair enough -- that's totally legit then. It's too bad that you have those constraints, but sometimes you just can't get around them. Given that, I see three options: 1) Compile your library separately and reference the compiled binary in downstream projects (@Grant Palin), 2) Swap the projects, as I describe in my other answer, and 3) Maintain two separate solutions (not very attractive).
Stuart Lange
A: 

Create another build-configuration for your project. So you will have at least 2 build-configurations e.g. Debug_SpecialNeeds and Debug.

Yatin
In Visual Studio, references in managed projects cannot be given per build configuration. I modified the MSBuild files to add conditions on references, (in my case depending on existence of some files in the system), but VS seem to ignore them and raise warnings/errors for both real and mock projects.
liori