[CMake] The Visual Studio project file inclusion problems.

Klaim - Joël Lamotte mjklaim at gmail.com
Sat Oct 20 12:45:30 EDT 2012


I'm use CMake 2.8.9.

Here is a summary of my understanding of what problem occurs when you try
to add a library that only have a visual studio project file,
in your project that is based on CMake.
I would like to have confirmations and also maybe some help about the
global issues I didn't find a solution for.

-----------------
1. The basic way to add a visual studio library project in CMake is to
write:

    include_external_msproject( my_vs_lib path/to/my_vs_lib.vcxproj ) #
assuming it's VS2010 or VS2012 project file, otherwise it's .vcproj

This works only if you just want to compile it.
To link with this project, you have two ways:

1.1. Do as in other cases of linking:

    target_link_libraries( my_exe my_vs_lib )

This generate an error because my_vs_lib isn't configured as STATIC or
SHARED target, but as UTILITY.
(I'll get back on this soon)

1.2. Consider the library as a "dependency" (which have an abstract meaning
which makes understanding fuzzy):

    add_dependencies( my_exe my_vs_lib )

This works in most cases...

--------------------

2. Now, let's assume you have the following configuration;

include_external_msproject( my_vs_lib path/to/my_vs_lib.vcxproj ) # this is
configured to be STATIC linking

# somewhere else
add_library( my_library STATIC ${MY_LIBRARY_SOURCES} )
add_dependencies( my_library my_vs_lib )

#somewhere else
add_executable( my_exe ${MY_EXE_SOURCES} )
target_link_libraries( my_exe my_library )

So basically we have ( with <- meaning "link with"):

    my_vs_lib <- my_library <- my_exe

The two libraries are in static linking mode.

In this configuration, my_exe will not link: all the my_vs_lib symbols used
will be missing.
The reason is that add_dependencies() will not make CMake guess that
dependencies might be targets required for linking
therefore if you don't directly compile the library (but you do compile an
exe using the library) then it don't need to be added to the linking.
This suggests that target_link_libraries() should be used instead, but as
said before, it don't work. (more on that coming)

2.1. The simpler solution to this, which is not very good because it forces
the programmer to do manipulations by hand,
is to use a project property in the generated exe project file.
In Visual Studio, right click on the exe project, select "Framework &
References" then select the library project, then on the right, change the
"Link Library Dependencies" to "True".
This will make the dependencies of the library to be linked too in the user
project of the library.

As said, this solution cannot be done without getting manually in Visual
Studio, for each project that needs it.

2.2. One virtual solution could be to make target_link_libraries() works
with the my_vs_lib project.
To do that, we need to make include_external_msproject() generate a target
that is not a  UTILITY (which I don't know the ...UTILITY)
but a STATIC or SHARED target.
It seems like it could be possible, as include_external_msproject() have
additional options:

include_external_msproject: Include an external Microsoft project file in a
> workspace.
>


>   include_external_msproject(projectname location
>                              [TYPE projectTypeGUID]
>                              [GUID projectGUID]
>                              [PLATFORM platformName]
>                              dep1 dep2 ...)
> Includes an external Microsoft project in the generated workspace file.
> Currently does nothing on UNIX. This will create a target named
> [projectname]. This can be used in the add_dependencies command to make
> things depend on the external project.
> TYPE, GUID and PLATFORM are optional parameters that allow one to specify
> the type of project, id (GUID) of the project and the name of the target
> platform. This is useful for projects requiring values other than the
> default (e.g. WIX projects). These options are not supported by the Visual
> Studio 6 generator.


I tried to set TYPE to STATIC value, but it apparently didn't work.
The main problem here is that the documentation is not clear on what is the
kind of value acceptable in TYPE and PLATFORM for example.
Shouldn't TYPE be STATIC,  MODULE, SHARED or UTILITY?
If yes, is there a known issue about this option not working?

2.3. I might be wrong, but it appears to me that maybe using
add_custom_target instead() of include_external_msproject() could work.
However, I didn't find the way to make it work so far.
Does someone here tried to do this?

2.4. A brute force solution would be to make all projects using the
my_library also add my_vs_lib as dependency.
I didn't test this solution because it's an obvious maintenance hell, even
using a CMake macro to define the targets (which I already do).

--------------------

So, is my understanding of the situation correct and complete?
Did I miss some other solutions? Or maybe known issues?

Thanks for your time.

Joel Lamotte
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20121020/a8a7a308/attachment.htm>


More information about the CMake mailing list