views:

89

answers:

4

Suppose you have some source code that comes from the unix world. This source consists of a few files which will create a library and a lot of small .c files (say 20 or so) that are compiled into command-line tools, each with their own main() function, that will use the library.

On unixy systems you can use a makefile to do this easily but the most naive transformation to the windows / Visual Studio world involves making a separate project for each tool which, although it works, is a lot of work to set up and synchronize and more difficult to navigate at both the filesystem and project/solution level. I've thought about using different configurations where all but one .c file are excluded from the build but that would make building all the tools at once impossible.

Is there a nice way of building all the tools from a single "thing" (project, msbuild file, etc.)?

I'm really not interested in using cygwin's gcc/mingw or NAnt. I'd like to stick with the standard Windows toolchain as much as possible.

+1  A: 

You don't HAVE to use visual studio to compile code. You can make your own batch file or Powershell script that simply calls the compiler on your source, just like a makefile.

snicker
A: 

If you're really using Visual Studio, I would suggest creating a project for each tool, and adding these projects to a single solution. From Visual Studio, it's easy to build a complete solution all at once, and MSBuild knows how to build .sln files as well.

msbuild myslnfile.sln

or even:

msbuild

... will build your solution.

Mark
I mentioned that I was trying to AVOID this. Clicking through the wizard and deleting the extraneous folders that VS makes is really annoying for 20ish tools.
Dana Robinson
If you don't like the extra folders, change the output location for the projects to something you do like. Also, you can easily edit the .proj file to remove folders such as obj\ if you'd like.
Mark
Also, I never said each .proj had to be in it's own folder, and certainly they can share files.
Mark
A default Win32 project adds Source, Include and Resource folders which are just noise when your project is one .c file. And yeah, I know you can munge all that stuff as much as you want (directories, etc.) The point is that I'm trying to avoid doing it 20 times.
Dana Robinson
So you're complaining about doing that once, or is this something you're going to be doing lots (setting up the projects)?
Mark
You could also easily hand-write the msbuild file (or even write one that built all 20 tools).
Mark
I deal with the Unix->Windows transition all the time and a lot of the software I see is built like this (1 makefile = lib + a bunch of command line and test tools). And yes, I know I can make MSBuild do pretty much anything but it appears to have a steep learning curve and I'd really like to focus on my project, not hacking crazy MSBuild scripts. Why can't MS just let me build a bunch of executables from one project?
Dana Robinson
MS isn't conspiring against you, here. MSBuild is perfectly capable of building multiple outputs from one "project" (msbuild file). Visual Studio doesn't do that, not using built-in wizards. If you were willing to learn make on Unix, why not learn MSBuild on Windows (or hey, this is a crazy idea, use make on Windows)?
Mark
A: 

If you have a makefile you can use a 'makefile' project in Visual Studio (which in misnamed - it simply allows you to specify custom build/debug commands), and use it to invoke GNU make.

You will need to change the makefile to use the VC++ command line tools instead of cc or gcc or whatever it uses, but often these are specified by macros at the top of the makefile.

If the makefile uses other Unix specific commands (such as rm), you may need to make modifications, or create bath files to map commands to Windows equivalents. Another option is to install any necessary tools from GNUWin32 to make it work.

If the build is very complex or involves configure scripts, then you have a harder task. You could generate the makefile from a configure script using MSYS/MinGW, and then modify it as above to make it work with VC++.

Makefile projects will not be as tightly integrated in Visual Studio however. All the build management is down to you and the makefile.

Clifford
A: 

So I've been looking into this for a while now and the solutions all leave much to be desired.

You can...

  • Create a lot of small projects by hand.

  • Use MSBuild and deal with its steep learning curve.

  • Use a build tool that does not integrate well with Visual Studio, like GNU make.

You can't even make a project template like you can with .NET projects! Well, you can make a wizard if you want to wade through the docs on doing that I suppose. Personally, I have decided to go with the "many small projects" solution and just deal with it. It turns out it can be less horrible than I had thought, though it still sucks. Here's what I did in Visual Studio 2008:

  1. Create your first Win32 command line tool project, get all your settings down for all platforms and make sure it works under all circumstances. This is going to be your "template" so you don't want to edit it after you've made 20 copies.

  2. (optional) I set up my paths in the visual studio project files so that everything is built in the project directory, then I have a post-build step copy just the dll/exe/pdb files I need to $(SolutionDir)$(OutDir). That way you can jump into a single directory to test all your tools and/or wrap them up for a binary distribution. VS2008 seems to be insane and drops output folders all over the place, with the default locations of Win32 and x64 output differing. Spending a few minutes to ensure that all platforms are consistent will pay off later.

  3. Clean up your template. Get rid of any user settings files and compiler output.

  4. Copy and paste your project as many times as you need. One project per tool.

  5. Rename each copied project folder and project file to a new tool name. Open up the project file in a text editor like Notepad++. If you have a simple, 1-file project you'll need to change the project name at two places at the beginning of the file and the source code file name(s) at the end of the file. You shouldn't need to touch the configuration stuff in the middle.

  6. You will also need to change the GUID for the project. Pop open guidgen.exe (in the SDK bin directory) and use the last radio button setting. Copy and paste a new GUID into each project file at the top. If you have dependencies, there will be one or more GUIDs at the bottom of the file near the source code. Do NOT change them as they are the GUIDs from the dependencies and have to match!

  7. Go into Visual Studio, open up your main solution and add your tool projects.

  8. Go into the configuration manager and make sure that everything is correct for all supported platforms, then test your build.

It's not beautiful, but it works and it's very much worth the setup time to be able to control your builds from the GUI. Hopefully VS2010 will be better about this, but I'm not too hopeful. It looks like MS is giving a lot more love to the .NET community than the C/C++ community these days.

Dana Robinson