[CMake] Building a DLL and test driver EXE using CMake -- error by design?
Michael Hertling
mhertling at online.de
Tue Mar 22 19:29:54 EDT 2011
On 03/22/2011 03:16 PM, Chris Volpe ARA/SED wrote:
> I posted this question in the VTK Users mailing list originally, but have since determined that it is more of a CMake issue than a VTK issue, and the involvement of VTK is only tangential.
>
> I am trying to set up a source tree which will allow CMake to create a MSVC++ .sln file that contains the following two projects:
>
> 1. A DLL (called "FeatureViewer") containing a vanilla C++ class that links against several VTK kits (Graphics, Rendering, and Hybrid).
>
> 2. An EXE (called "TestDriver") that links against the aforementioned library containing the vanilla C++ class.
>
> I want to deliver the DLL, LIB, and class header file from (1) above (as well as the dependent VTK DLLs) to a co-worker who has his own application and wants to use the functionality I'm encapsulating, but he doesn't want to "vtk-ify" his build process. The EXE in (2) above is simply my test driver for (1).
>
> My problem is that the EXE won't build because the generated project is spuriously looking for vtk libraries (e.g. vtkGraphics.lib et. al.) at link time that it doesn't directly reference, and it doesn't know where to find them. The EXE shouldn't need to know about them because their use is strictly within the FeatureViewer library. If I go into the EXE project properties and manually delete the references to vtkGraphics.lib et. al. from the linker->input->additional-dependencies list, it works.
>
> At first, I thought I was just doing something wrong in my CMakeLists.txt files, but page 25 of the CMake User's Guide suggests that this behavior is by design.
> The example given is:
>
> add_library(foo foo.cxx)
> target_link_libraries(foo bar)
>
> add_executable(foobar foobar.cxx)
> target_link_libraries(foobar foo)
>
> The text below the example states, "This will link the libraries foo and bar into the executable foobar even [sic], although only foo was explicitly linked into foobar. With shared or DLL builds this linking is not always needed, but the extra linkage is harmless."
>
> It seems to me that this extra linkage is not harmless: I don't want clients of FeatureViewer to have to know about vtkGraphics.lib et. al., but CMake is creating a spurious reference.
>
> Can someone provide a work-around?
>
> My CMakeLists.txt files look like this:
>
> Top Level:
> CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
> IF(COMMAND CMAKE_POLICY)
> CMAKE_POLICY(SET CMP0003 NEW)
> ENDIF(COMMAND CMAKE_POLICY)
>
> PROJECT(FeatureViewer)
>
> add_subdirectory(TestDriver)
> add_subdirectory(FeatureViewer)
>
> FeatureViewer:
> SET (FeatureViewer_SRCS
> FeatureViewer.cxx
> )
>
> IF(NOT VTK_BINARY_DIR)
> FIND_PACKAGE(VTK REQUIRED)
> IF(NOT VTK_USE_RENDERING)
> MESSAGE(FATAL_ERROR "Example ${PROJECT_NAME} requires VTK_USE_RENDERING.")
> ENDIF(NOT VTK_USE_RENDERING)
> INCLUDE(${VTK_USE_FILE})
> ENDIF(NOT VTK_BINARY_DIR)
>
> ADD_LIBRARY(FeatureViewer SHARED ${FeatureViewer_SRCS})
> TARGET_LINK_LIBRARIES(FeatureViewer vtkGraphics vtkRendering vtkHybrid)
>
> TestDriver:
> ADD_EXECUTABLE(TestDriver TestDriver.cxx)
>
> TARGET_LINK_LIBRARIES(TestDriver FeatureViewer)
>
> INCLUDE_DIRECTORIES(${FeatureViewer_SOURCE_DIR}/FeatureViewer)
>
> Thanks in advance!!
> Chris
The TARGET_LINK_LIBRARIES() command works transitively, i.e. TestDriver
will be linked against each shared library that FeatureViewer is linked
against, too. You might break this transitivity by explicitly setting
the LINK_INTERFACE_LIBRARIES target properties of FeatureViewer to ""
or, in general, to the set of libraries which are still to be linked
transitively. As an alternative, you might use a second invocation
TARGET_LINK_LIBRARIES(FeatureViewer TARGET_LINK_LIBRARIES ...)
in FeatureViewer/CMakeLists.txt to explicitly specify the transitive
libraries. Of course, the VTK ones should not appear in these lists.
'hope that helps.
Regards,
Michael
More information about the CMake
mailing list