# How to create tests for my Python bindings project

**URL:** <https://discourse.cmake.org/t/how-to-create-tests-for-my-python-bindings-project/13125>\
**Category:** Code\
**Tags:** os:linux\
**Created:** [December 4, 2024, 10:21pm UTC](https://discourse.cmake.org/t/how-to-create-tests-for-my-python-bindings-project/13125 "2024-12-04T22:21:20Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![greenleaf](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/g/db5fbb/32.png) [@greenleaf](https://discourse.cmake.org/u/greenleaf)\
**Post date:** [December 4, 2024, 10:21pm UTC](https://discourse.cmake.org/t/how-to-create-tests-for-my-python-bindings-project/13125/1 "2024-12-04T22:21:20Z")

</div>

I have the following CMake:

```auto
cmake_minimum_required(VERSION 3.20)

include(cmake/prelude.cmake)

project(
    myLibPythonBindings
    VERSION 0.1.0
    LANGUAGES CXX
)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED True)

docs_early_return()

include(cmake/variables.cmake)

# ---- Find dependencies ----
find_package(Ceres CONFIG)
...

# ---- Declare library ----

pybind11_add_module(
    myLibPythonBindings_myLibPythonBindings
    MODULE
    source/files1.cpp
    ...
    source/files2.cpp
)
add_library(myLibPythonBindings::myLibPythonBindings ALIAS myLibPythonBindings_myLibPythonBindings)
#add_library(myLibPythonBindings::core ALIAS myLibPythonBindings)

# when myLibProject is statically linked, dependency information will not be available
# via any external means (e.g., ldd), therefore cmake treats all PRIVATE deps as PUBLIC
# all of the below will be added to INTERFACE_LINK_LIBRARIES, therefore we try to find them
find_package(PkgConfig REQUIRED)
pkg_check_modules(openlibm IMPORTED_TARGET openlibm)

find_package(cpp-sort)
...
find_package(openlibm)

include(GenerateExportHeader)
generate_export_header(
    myLibPythonBindings_myLibPythonBindings
    BASE_NAME myLibPythonBindings
    EXPORT_FILE_NAME export/myLibPythonBindings/myLibPythonBindings_export.hpp
    CUSTOM_CONTENT_FROM_VARIABLE pragma_suppress_c4251
)

set_target_properties(
    myLibPythonBindings_myLibPythonBindings PROPERTIES
    CXX_VISIBILITY_PRESET hidden
    VISIBILITY_INLINES_HIDDEN YES
    VERSION "${PROJECT_VERSION}"
    SOVERSION "${PROJECT_VERSION_MAJOR}"
    EXPORT_NAME myLibPythonBindings
    OUTPUT_NAME myLibPythonBindings
)

target_include_directories(
    myLibPythonBindings_myLibPythonBindings ${myLibPythonBindings_warning_guard}
    PUBLIC
    "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
)

target_include_directories(
    myLibPythonBindings_myLibPythonBindings SYSTEM
    PUBLIC
    "$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/export>"
)

target_compile_features(myLibPythonBindings_myLibPythonBindings PUBLIC cxx_std_20)

target_link_libraries(myLibPythonBindings_myLibPythonBindings PRIVATE myLibProject::myLibProject)

if (APPLE)
    set_target_properties(myLibPythonBindings_myLibPythonBindings PROPERTIES VERSION "")
endif()

# ---- Install rules ----

if(NOT CMAKE_SKIP_INSTALL_RULES)
  include(cmake/install-rules.cmake)
endif()

# ---- Developer mode ----

if(NOT myLibPythonBindings_DEVELOPER_MODE)
  return()
elseif(NOT PROJECT_IS_TOP_LEVEL)
  message(
      AUTHOR_WARNING
      "Developer mode is intended for developers of myLibPythonBindings"
  )
endif()

include(cmake/dev-mode.cmake)

```

It will generate Python bindings for a library that I wrote. How can I now also create an executable that will run some tests?

I tried:

```auto
cmake_minimum_required(VERSION 3.14)

project(myLibPythonBindingsTests LANGUAGES CXX)

if(PROJECT_IS_TOP_LEVEL)
  find_package(myLibPythonBindings REQUIRED)
  enable_testing()
endif()

add_executable(myLibPythonBindings_test source/myLibPythonBindings_test.cpp)
target_link_libraries(myLibPythonBindings_test PRIVATE myLibPythonBindings::myLibPythonBindings)
target_compile_features(myLibPythonBindings_test PRIVATE cxx_std_20)

add_test(NAME myLibPythonBindings_test COMMAND myLibPythonBindings_test)

```

But I get:

```auto
CMake Error at test/CMakeLists.txt:11 (target_link_libraries):
  Target "myLibPythonBindings::myLibPythonBindings" of type MODULE_LIBRARY may not be linked into
  another target. One may link only to INTERFACE, OBJECT, STATIC or SHARED
  libraries, or to executables with the ENABLE_EXPORTS property set.

```

What would be the best way to set up my cmake files here?

---

<div class="post-metadata">

**Author:** ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)\
**Post date:** [December 6, 2024, 9:51am UTC](https://discourse.cmake.org/t/how-to-create-tests-for-my-python-bindings-project/13125/2 "2024-12-06T09:51:11Z")

</div>

I have no experience with PyBind, but looking into its [docs](https://pybind11.readthedocs.io/en/stable/compiling.html#pybind11-add-module), I found the following:

> `MODULE` or `SHARED` may be given to specify the type of library. If no type is given, `MODULE` is used by default which ensures the creation of a Python-exclusive module. Specifying `SHARED` will create a more traditional dynamic library which can also be linked from elsewhere.

Since you apparently want to link to the generated library, you should probably be specifying `SHARED` instead of `MODULE`.

---

<div class="post-metadata">

**Author:** ![greenleaf](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/g/db5fbb/32.png) [@greenleaf](https://discourse.cmake.org/u/greenleaf)\
**Post date:** [December 6, 2024, 6:30pm UTC](https://discourse.cmake.org/t/how-to-create-tests-for-my-python-bindings-project/13125/3 "2024-12-06T18:30:28Z")

</div>

Tried it but not much success. I’ll figure this out and update the question once I do.
