[Cmake] Mulitple related workspaces -- success!

Karr, David David . Karr at titan . com
Mon, 11 Aug 2003 10:34:14 -0400


Here's the situation.  I wanted to convert to CMake a couple
of workspaces that looked like this:

  /foo/foo.dsw
  /foo/bar/bar.dsw

The .lib files from both projects were all being put in
  /foo/lib
and the .dll and .exe files were all put in
  /foo/bin

These things could change, of course, but at least for the
initial conversion I wanted as little disruption as possible
in a project that has been underway for quite some time.
Also, there were a very large number of .dsp files in the two
workspaces producing a great many .dll, .lib, and .exe files.
(Actually a major selling point of CMake is its ability to
manage all the input directories, libraries, and options that
the compiler and/or linker need, and to make changes to those
uniformly across these many .dsp files--a near-hopeless task
using the Visual Studio GUI.)

And this is an in-source build too, because that's the way=20
the existing projects were set up, though I'd like to change
that if I can.

Here's what I did.  There were a bunch of commands (such as
setting the compiler options) that I wanted to execute exactly
the same way in both workspaces, so I put those in a file
called /foo/fooDefs.txt.  I included this in=20
/foo/CMakeLists.txt *and* in /foo/bar/CMakeLists.txt.
Some of the commands in this file used the variables
foo_SOURCE_DIR and foo_BINARY_DIR, which of course wouldn't
be defined in /foo/bar/CMakeLists.txt, but of course there the
PROJECT(bar) command defines bar_SOURCE_DIR as /foo/bar, so in
that file I defined foo_SOURCE_DIR with the command:

  SET(REGEX REPLACE "/[^/]*$" "" foo_SOURCE_DIR ${bar_SOURCE_DIR})

This strips the last component off the path defined by
bar_SOURCE_DIR.  I used a similar trick for foo_BINARY_DIR.
A side effect of this is it provides a nice way to say where=20
to look for the file fooDefs.txt from within=20
/foo/bar/CMakeLists.txt.

In fooDefs.txt I defined the output directories:

  SET(EXECUTABLE_OUTPUT_PATH ${foo_BINARY_DIR}/bin)
  SET(LIBRARY_OUTPUT_PATH ${foo_BINARY_DIR}/lib)

This alone would almost do what I needed--it puts the outputs
of the two workspaces in the same two places--but it puts the
.dll files with the .lib files instead of with the .exe files,
and appends "/Debug" to the directory, so I copied the=20
templates from the CMake Templates directory into my source
and modified them to "fix" those things.  (I know, they weren't
broken; but they didn't match the file structure I inherited.) =20
Then I used my new templates:

  SET(MSPROJECT_TEMPLATE_DIRECTORY ${foo_SOURCE_DIR}/CMake/Templates)

Finally, I just did something like this:

  cd /foo
  cmake
  cd /foo/bar
  cmake

And out-of-source builds would work nicely too:

  cd /build/foo
  cmake /foo
  cd /build/foo/bar
  cmake /foo/bar

-- David