I have a C++ library (called myfibo
) and I want to make a python binding modue (called myfibopy
) using CMake and Swig.
The first build works perfectly. But if I rename an exposed C++ function, the python module doesn't build anymore because the Swig wrapper (PYTHON_wrap.cxx) is not regenerated.
I have already tried using SWIG_USE_LIBRARY_INCLUDE_DIRECTORIES as explained here but with no success.
What I am doing wrong?
Here is the toy example to reproduce the error:
Directory tree
.
├── CMakeLists.txt
├── myfibo
│ ├── CMakeLists.txt
│ ├── fibo.cpp
│ └── include
│ └── fibo.hpp
└── myfibopy
├── CMakeLists.txt
└── fibo.i
fibo.hpp
#pragma once
void fib(int n);
fibo.cpp
#include "fibo.hpp"
#include <iostream>
void fib(int n)
{
int a = 0;
int b = 1;
while (a < n)
{
std::cout << a << " ";
a = b;
b = a+b;
}
std::cout << std::endl;
}
fibo.i
%module myfibopy
%include fibo.hpp
%{
#include "fibo.hpp"
%}
./CMakeLists.txt
project(myfibopy)
cmake_minimum_required(VERSION 3.15)
add_subdirectory(myfibo)
add_subdirectory(myfibopy)
myfibo/CMakeLists.txt
add_library(myfibo SHARED fibo.cpp)
target_include_directories(myfibo
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include> # unused
)
myfibopy/CMakeLists.txt
find_package(PythonLibs 3 REQUIRED)
include_directories(${PYTHON_INCLUDE_PATH})
find_package(SWIG 4.0 REQUIRED)
include(${SWIG_USE_FILE})
set(SRC fibo.i)
set_source_files_properties(${SRC} PROPERTIES CPLUSPLUS ON)
swig_add_library(myfibopy LANGUAGE python SOURCES ${SRC})
target_link_libraries(myfibopy PUBLIC myfibo)
# See https://gitlab.kitware.com/cmake/cmake/-/issues/18003
set_target_properties(myfibopy PROPERTIES SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE)
First compilation
> cmake -Bbuild -H.
[...]
> cmake --build build
[...]
Perfect. Now, build
directory exists and I can play with myfibopy
module.
After renaming fib
into fib2
in fibo.hpp and fibo.cpp
> cmake --build build
Consolidate compiler generated dependencies of target myfibo
[ 20%] Building CXX object myfibo/CMakeFiles/myfibo.dir/fibo.cpp.o
[ 40%] Linking CXX shared library libmyfibo.so
[ 40%] Built target myfibo
[ 60%] Built target myfibopy_swig_compilation
Consolidate compiler generated dependencies of target myfibopy
[ 80%] Building CXX object myfibopy/CMakeFiles/myfibopy.dir/CMakeFiles/myfibopy.dir/fiboPYTHON_wrap.cxx.o
./build/myfibopy/CMakeFiles/myfibopy.dir/fiboPYTHON_wrap.cxx: In function ‘PyObject* _wrap_fib(PyObject*, PyObject*)’:
./build/myfibopy/CMakeFiles/myfibopy.dir/fiboPYTHON_wrap.cxx:2968:3: error: ‘fib’ was not declared in this scope
fib(arg1);
^~~
./build/myfibopy/CMakeFiles/myfibopy.dir/fiboPYTHON_wrap.cxx:2968:3: note: suggested alternative: ‘fib2’
fib(arg1);
^~~
fib2
myfibopy/CMakeFiles/myfibopy.dir/build.make:75: recipe for target 'myfibopy/CMakeFiles/myfibopy.dir/CMakeFiles/myfibopy.dir/fiboPYTHON_wrap.cxx.o' failed
make[2]: *** [myfibopy/CMakeFiles/myfibopy.dir/CMakeFiles/myfibopy.dir/fiboPYTHON_wrap.cxx.o] Error 1
CMakeFiles/Makefile2:170: recipe for target 'myfibopy/CMakeFiles/myfibopy.dir/all' failed
make[1]: *** [myfibopy/CMakeFiles/myfibopy.dir/all] Error 2
Makefile:90: recipe for target 'all' failed
make: *** [all] Error 2
Did you try:
USE_SWIG_DEPENDENCIES
New in version3.20
.
If set toTRUE
, implicit dependencies are generated by the swig tool itself. This property is only meaningful for Makefile, Ninja, Xcode, and Visual Studio (Visual Studio 11 2012 and above) generators. Default value isFALSE
.
New in version 3.21: Added the support of Xcode generator.
New in version 3.22: Added the support of Visual Studio Generators.
or
USE_TARGET_INCLUDE_DIRECTORIES
New in version 3.13.
If set toTRUE
, contents of target property INCLUDE_DIRECTORIES will be forwarded to SWIG compiler. If set toFALSE
target property INCLUDE_DIRECTORIES will be ignored. If not set, target propertySWIG_USE_TARGET_INCLUDE_DIRECTORIES
will be considered.
src: https://cmake.org/cmake/help/git-stage/module/UseSWIG.html