How to package SWIG with a library

87 views Asked by At

I am using SWIG to generate wrappers for my code which makes SWIG as a direct dependency. I want to package it as part of the library code and build it prior to compilation of my source code. How shall i do so using cmake file if at all i can do so that way.

I have tried including it as an external dependency as well as subdirectory in the CMAKE file but it gives me error like SWIG not found or cannot include SWIG. I would love some recommendation on if this is the right way to package and install SWIG because I don't want to make it into a client side dependency. I would really appreciate some help.

This is the code snippet:

ExternalProject_Add(
    SWIG_Project
    SOURCE_DIR ${CMAKE_SOURCE_DIR}/headers/swig-4.1.1
    BUILD_COMMAND make
    INSTALL_COMMAND "" 
    BUILD_IN_SOURCE 1
)

After doing this how am i supposed to use SWIG like the way find_package(SWIG) works since i want to use this command SWIG_ADD_LIBRARY(abc LANGUAGE python SOURCES abc.i)

1

There are 1 answers

0
Mizux On

You must use the module UseSwig so after your find_package(SWIG) you must use:

include(UseSWIG)

if(${SWIG_VERSION} VERSION_GREATER_EQUAL 4)
  list(APPEND CMAKE_SWIG_FLAGS "-doxygen")
endif()

if(UNIX AND NOT APPLE)
  if (CMAKE_SIZEOF_VOID_P EQUAL 8)
    list(APPEND CMAKE_SWIG_FLAGS "-DSWIGWORDSIZE64")
  else()
    list(APPEND CMAKE_SWIG_FLAGS "-DSWIGWORDSIZE32")
  endif()
endif()

# Find Python 3
find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)
list(APPEND CMAKE_SWIG_FLAGS "-py3" "-DPY3")

then you can use to wrap foo.i as module pyFoo:

set_property(SOURCE foo.i PROPERTY CPLUSPLUS ON)
set_property(SOURCE foo.i PROPERTY SWIG_MODULE_NAME pyFoo)
swig_add_library(pyFoo
  TYPE MODULE
  LANGUAGE python
  OUTPUT_DIR ${CMAKE_BINARY_DIR}/.../foo
  SOURCES foo.i)
add_library(${PROJECT_NAMESPACE}::pyFoo ALIAS pyFoo)

target_include_directories(pyFoo
  PRIVATE
    ...
    ${Python3_INCLUDE_DIRS}
)
set_property(TARGET pyFoo PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON)

# note: macOS is APPLE and also UNIX !
if(APPLE)
  set_target_properties(pyFoo PROPERTIES
    SUFFIX ".so"
    INSTALL_RPATH "@loader_path;@loader_path/.../.libs"
    )
  set_property(TARGET pyFoo APPEND PROPERTY
    LINK_FLAGS "-flat_namespace -undefined suppress"
    )
elseif(UNIX)
  set_target_properties(pyFoo PROPERTIES
    INSTALL_RPATH "$ORIGIN:$ORIGIN/../../${PYTHON_PROJECT}/.libs"
    )
endif()
target_link_libraries(pyFoo PRIVATE ${PROJECT_NAMESPACE}::Foo)

# Variable PYTHON_LIBRARIES can contains keyword `optimized`
# which won't be interpreted inside a generator expression.
# i.e. we can't use: $<$<PLATFORM_ID:Windows>:${PYTHON_LIBRARIES}>
# see: https://cmake.org/cmake/help/git-stage/command/target_link_libraries.html#command:target_link_libraries
if(MSVC)
  target_link_libraries(pyFoo PRIVATE ${Python3_LIBRARIES})
endif()

ref: https://cmake.org/cmake/help/latest/module/UseSWIG.html

note: you can also look at this template repo: https://github.com/Mizux/python-native