views:

1320

answers:

5

I have a number of native C++ libraries (Win32, without MFC) compiling under Visual Studio 2005, and used in a number of solutions.

I'd like to be able to choose to compile and link them as either static libraries or DLLs, depending on the needs of the particular solution in which I'm using them.

What's the best way to do this? I've considered these approaches:

1. Multiple project files

  • Example: "foo_static.vcproj" vs "foo_dll.vcproj"
  • Pro: easy to generate for new libraries, not too much manual vcproj munging.
  • Con: settings, file lists, etc. in two places get out of sync too easily.

2. Single project file, multiple configurations

  • Example: "Debug | Win32" vs "Debug DLL | Win32", etc.
  • Pro: file lists are easier to keep in sync; compilation options are somewhat easier to keep in sync
  • Con: I build for both Win32 and Smart Device targets, so I already have multiple configurations; I don't want to make my combinatorial explosion worse ("Static library for FooPhone | WinMobile 6", "Dynamic library for FooPhone | WinMobile 6", "Static library for BarPda | WinMobile 6", etc.
  • Worse Con: VS 2005 has a bad habit of assuming that if you have a configuration defined for platform "Foo", then you really need it for all other platforms in your solution, and haphazardly inserts all permutations of configuration/platform configurations all over the affected vcproj files, whether valid or not. (Bug filed with MS; closed as WONTFIX.)

3. Single project file, selecting static or dynamic via vsprops files

  • Example: store the appropriate vcproj fragments in property sheet files, then apply the "FooApp Static Library" property sheet to config/platform combinations when you want static libs, and apply the "FooApp DLL" property sheet when you want DLLs.
  • Pros: This is what I really want to do!
  • Cons: It doesn't seem possible. It seems that the .vcproj attribute that switches between static and dynamic libraries (the ConfigurationType attribute of the Configuration element) isn't overrideable by the .vsprops file. Microsoft's published schema for these files lists only <Tool> and <UserMacro> elements.

EDIT: In case someone suggests it, I've also tried a more "clever" version of #3, in which I define a .vsprops containing a UserMacro called "ModuleConfigurationType" with a value of either "2" (DLL) or "4" (static library), and changed the configuration in the .vcproj to have ConfigurationType="$(ModuleConfigurationType)". Visual Studio silently and without warning removes the attribute and replaces it with ConfigurationType="1". So helpful!

Am I missing a better solution?

+2  A: 

I think the typical way this is done is choice 2 above. It is what I use and what I have seen done by a number of libraries and companies.

If you find it does not work for you then by all means use something else.

Good luck.

Tim
We're doing 1) and 2), each somewhat successfully, and with different drawbacks. I was hoping for a 4)...
Tim Lesher
A: 

Multiple projects are the best way to go - this is the configuration i have most widely seen in umpteen no of projects that i have come across.

That said, it might be also possible to implement the third option by modifying your vcproj files on the fly from external tools(like a custom vbscript), that you could invoke from a make file. You can use shell variables to control the behavior of the tool.

Note that you should still use use visual studio to make the build, the makefile should only launch your external tool if required to make the mods and then follow that by the actual build command

A: 

Why not go for version 1 and generate the second set of project files from the first using a script or something. That way you know that the differences are JUST the pieces required to build a dll or static lib.

Len Holgate
A: 

I prefer 2 configurations way.

Setup all common settings via 'All configurations' item in a project properties windows. After it separated settings. And it's done. Let's go coding.

Also there is very good feature named 'Batch build', which builds specified configurations by turn.

abatishchev
A: 

I use Visual Studio 6.0 (Still) due to issues that are preventing us from Migrating to VS2005 or newer. Rebuilding causes severe issues (everything breaks)... so many of us are considering lobbying a migration to GnuC++ moving forward in a structured way to eventually get us off of licensed Visual Studio products and onto Eclipse and Linux.

In Unix/Linux it is easy to build for all configurations.. so I can't believe what a time and productivity sink it is to try and accomplish the same task in Visual Studio. For VS6.0 I have so far found that only having two separate projects seems to be workable. I haven't yet tried the multiple configuration technique, but will see if it works in the older VS6.0.

In VS 6.0, the multiple configuations technique is the only way to segregate platform differences, as VS6 didn't have the concept of target platforms in the way VS2005 does.
Tim Lesher