Skip to content

Creating python packages

Mayeul d'Avezac edited this page Mar 6, 2016 · 2 revisions

Python packages can be created in many, many ways. The following handles:

  • python extensions (*.c or *.cc files)
  • pure python packages (*.py files)
  • cython extensions (*.pyx *.pxd)

In all cases, it is possible to use a single function to create a new package:

include(PythonModule)

add_python_module(moduleName # Fully qualified name of the module, e.g "my.module"
[source files] # Source files or patterns (e.g "this.py" "*.pyx")
[INSTALL|NOINSTALL] # Do/don't install package when doing make install
[CPP]       # cython extensions are c++
[NOCONFIG]  # If absent, *.in.* are passed through configure_file(... ... @ONLY)
[FAKE_INIT] # Adds an empty __init__.py file in my/module directory. Useful 
            # for submodules with tests only
[HEADER_DESTINATION <destination>] # Directory where headers should go
[LOCATION <location>] # Location where to install the package, if different
                      # from my/module. Generally, default should do.
[SOURCES <source files and patterns>]    # Another way to specify sources
[EXCLUDE <excluded files and patterns>]  # Files/pattern to exclude from source files
[LIBRARIES <targets or libraries>]       # Libraries to link with the extension
[OBJECTS $<TARGET_OBJECTS:A> ...]        # Adds OBJECT libraries to the C/Cython extension
)

Pure C extensions should be named added one at a time. Although they may include any number of c/c++ files, one and only one should define an actual module. The name of the module correspond to the first argument above.

Pure python and cython extensions can be added all at once. They will go as subcomponents of the module specified by the first argument above (Or by LOCATION, if given).

In the build directory, the package is placed at the appropriate location in PYTHON_BINARY_DIR. This makes it easy to run and debug the package by using the create_environment function provided by the cook-off.

If compiling cython extensions, the user should take care that one of the following is true:

  • cython_EXECUTABLE is defined
  • cython is installed on the system and the python is sufficiently modern that "${PYTHON_EXECUTABLE} -m cython" works
  • cython has been installed locally, LOCAL_PYTHON_EXECUTABLE is defined and is sufficiently modern that the "-m" option works

The easies option is check for cython with

include(PythonPackageLookUp)
include(EnvironmentScript)

# Python packages located below will be found by env
add_to_python_path("${EXTERNAL_ROOT}/python")
# local env python
set(LOCAL_PYTHON_EXECUTABLE "${PROJECT_BINARY_DIR}/localpython.sh")
create_environment_script(
    EXECUTABLE "${PYTHON_EXECUTABLE}"
    PATH "${LOCAL_PYTHON_EXECUTABLE}"
    PYTHON
)

# finds existing cython or installs it in ${EXTERNAL_ROOT}/python
lookup_python_package(cython REQUIRED PATH "${EXTERNAL_ROOT}/python")