Steve
Steve

Reputation: 41

How can I add C/C++ and swig generated code to the same library using cmake

The SWIG plugin to CMake is currently puzzling me. I want to build a single shared object that contains executable code compiled directly from C/C++ code as well as indirectly from input files to swig.

In my CMakeLists.txt file I therefore have

file (GLOB SOURCES ./src/ice/ice/*.c ./src/ice/ice/*.cpp)
add_library (ice SHARED ${SOURCES})
target_include_directories (ice PUBLIC ./bld/build/gen)
...
set_property(SOURCE ./src/ice/ice/ice_swig.i PROPERTY CPLUSPLUS ON) 
swig_add_library (ice LANGUAGE tcl SOURCES ./src/ice/ice/ice_swig.i ) 
...

During configuration, I get this error:

CMake Error at /public/public64/packages/development/cmake-3.8.1/share/cmake-3.8/Modules/UseSWIG.cmake:275 (add_library):
add_library cannot create target "ice" because another target with the same name already exists. The existing target is a shared library created in source directory "/home/steve/cmake_games/src/ice/ice".
See documentation for policy CMP0002 for more details. Call Stack (most recent call first): src/ice/ice/CMakeLists.txt:20 (swig_add_library)
-- Configuring incomplete, errors occurred!

It seems that both add_libary and swig_add_library are defining a target with the same name. This does not allow me to add both C/C++ "handcrafted" code and swig generated code to the same library. What is the correct way of using CMake to add SWIG generated C/C++ to the same library?

Upvotes: 1

Views: 3014

Answers (2)

ChrisSH
ChrisSH

Reputation: 136

We solved this by creating a child library and linking it with the SWIG library:

file (GLOB SOURCES ./src/ice/ice/*.c ./src/ice/ice/*.cpp)
add_library (ice_baby SHARED ${SOURCES})
target_include_directories (ice_baby PUBLIC ./bld/build/gen)
...
set_property(SOURCE ./src/ice/ice/ice_swig.i PROPERTY CPLUSPLUS ON) 
swig_add_library (ice LANGUAGE tcl SOURCES ./src/ice/ice/ice_swig.i ) 
swig_link_libraries (ice ice_baby)
...

Upvotes: 2

Mizux
Mizux

Reputation: 9281

You should use the new syntax of UseSWIG

first:

swig_add_library (ice_tcl
TYPE STATIC
LANGUAGE tcl
SOURCES ./src/ice/ice/ice_swig.i) 

then try to add:

target_link_library(ice PRIVATE ${SWIG_MODULE_ice_tcl_REAL_NAME})

ps: not sure if the swig generated tcl file won't try to open the ice_tcl library directly... In this case you'll need two libraries like here: https://github.com/Mizux/cmake-swig

Upvotes: 0

Related Questions