7

I want to be able to call my C++ code as a python package. To do this I am using pybind11 with CMakelists (following this example https://github.com/pybind/cmake_example). My problem is that I have to include GSL libraries in the compilation of the code, and these need an explicit linker -lgsl .

If I were just to compile and run the C++ without wrapping it with python, the following Cmakelists.txt file does the job

cmake_minimum_required(VERSION 3.0)

set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")

project(myProject)


add_executable(
    myexecutable
    main.cpp
    function1.cpp
)

find_package(GSL REQUIRED)
target_link_libraries(myexecutable GSL::gsl GSL::gslcblas)

but when using pybind11 the template I found doesn't allow the add_executable therefore target_link_libraries doesn't work.

I have trie this

project(myProject)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES)   # See below (1)



# Set source directory
set(SOURCE_DIR "project")

# Tell CMake that headers are also in SOURCE_DIR
include_directories(${SOURCE_DIR})
set(SOURCES "${SOURCE_DIR}/functions.cpp")


# Generate Python module
add_subdirectory(lib/pybind11)
pybind11_add_module(namr ${SOURCES} "${SOURCE_DIR}/bindings.cpp")


FIND_PACKAGE(GSL REQUIRED)
target_link_libraries(GSL::gsl GSL::gslcblas)

but this produces errors in the building.

Any idea ?

Duccio Piovani
  • 1,410
  • 2
  • 15
  • 27

1 Answers1

8

Function pybind11_add_module creates a library target, which can be used for link added module with other libraries:

pybind11_add_module(namr ${SOURCES} "${SOURCE_DIR}/bindings.cpp")
target_link_libraries(namr PUBLIC GSL::gsl GSL::gslcblas)

This is explicitely stated in documentation:

This function behaves very much like CMake’s builtin add_library (in fact, it’s a wrapper function around that command). It will add a library target called <name> to be built from the listed source files. In addition, it will take care of all the Python-specific compiler and linker flags as well as the OS- and Python-version-specific file extension. The produced target <name> can be further manipulated with regular CMake commands.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • 3
    Thank you so much I am new to Cmake and cant navigate the docs as I should. This is however now generating a new error which is beyond my comprehension: `CMake Error at CMakeLists.txt:22 (target_link_libraries): The keyword signature for target_link_libraries has already been used with the target "namr". All uses of target_link_libraries with a target must be either all-keyword or all-plain` – Duccio Piovani Apr 23 '18 at 10:17
  • @Tsyvarev How to use this if `gsl` is installed at a non-standard directory. For example. if gsl was installed in a directory, which is inside the directory where the `CMakeList.txt` file exists. – ankit7540 Jan 16 '22 at 05:47
  • 2
    @ankit7540: You may hint `find_package` about location of the GSL by setting `CMAKE_PREFIX_PATH` variable. See that my answer: https://stackoverflow.com/a/34797156/3440745 – Tsyvarev Jan 16 '22 at 07:43