[Cmake] Problem with more than one group of source files in a Visual Studio project, and a workaround

Karr, David David . Karr at titan . com
Fri, 25 Jul 2003 18:44:56 -0400


OK, I'm still trying to convert an existing Visual Studio
workspace over to CMake.  I've modified my architecture
to buy into the existing ideas of CMake as much as I can=20
(and as far as I know), and I'm using an umodified copy=20
of CMake 1.6.7 to try to generate my projects.

In some of the projects in the existing Visual Studio
workspace, the developers had decided to divide the=20
source files into multiple disjoint source groups.
For example, a project might look like this when its
groups are expanded in the Visual Studio window:

  MyProject files
   |-- Alpha Source Files
   | |-- file_a1.cpp
   | |-- file_a2.cpp
   |-- Beta Source Files
   | |-- file_b1.cpp
   | |-- file_b1.cpp

There were good reasons for doing this in at least=20
some of the cases, and it would be difficult to "sell"
one-source-group-per-project to all the developers.

Unfortunately, in my first attempt to replicate this
project structure with CMake, in addition to using the=20
SOURCE_GROUP(var FILES ...) command to make the source
groups, I also passed the source file names to the
ADD_EXECUTABLE(MyProject ...) command.
I then got an extra copy of each of the .cpp
files under this project, either in a "Source Files"
source group or, if I overrode the regular expression of
"Source Files" so that it doesn't match .cpp, I got all
these files at the same level as CMakeLists.txt.  Either
way, when I tried to build the project in Visual Studio, it
produced an error message claiming that two files (it gave
their full paths, which happen to be identical) were both
configured to produce the same output.

I think the reason for this is that the local generator for=20
Visual Studio 6 runs through the source files to add them to
the correct source groups if they aren't already there, and=20
when it does so it looks specifically to match a regular=20
expression; the cmSourceGroup::Match(...) function doesn't=20
tell you when the file happens to have been added to the=20
group by SOURCE_GROUP(var FILES ...).  Ergo the file is
added to a source group again (I've even seen it show up
twice in the same group while looking for a workaround)
and Visual Studio is apparently fooled into thinking there=20
are two copies of it.

I made sure that I used the full paths in the filenames I
added to source groups, but it didn't seem to help.


I attempted to work around this by not declaring any sources
for the build, that is, I'd do something like this:

  ADD_LIBRARY(my_library SHARED "")

But CMake doesn't allow this.  So my workaround was to=20
declare a dummy source file in the ADD_EXECUTABLE or=20
ADD_LIBRARY command, for example,

  ADD_LIBRARY(my_library SHARED "README.txt")

It doesn't seem to matter what the dummy file is as long as
it actually exists and isn't considered a source file by
Visual Studio (but honestly, I tried a .txt file, it worked,
so I didn't look any further).


I'm sure this is possible to fix in the CMake source but it=20
was easier to just work around it for now.  The obvious fix
seems to be a more careful search of existing source groups=20
while generating the .dsp files, so that CMake never=20
automatically duplicates any filename that's already in=20
some source group.  But I came up with this via a novice
understanding of how the internals of CMake work, so there
may be a better way.


-- David A. Karr