PythonExtensions

This module defines CMake functions to build Python extension modules and stand-alone executables.

The following variables are defined:

PYTHON_PREFIX                     - absolute path to the current Python
                                    distribution's prefix
PYTHON_SITE_PACKAGES_DIR          - absolute path to the current Python
                                    distribution's site-packages directory
PYTHON_RELATIVE_SITE_PACKAGES_DIR - path to the current Python
                                    distribution's site-packages directory
                                    relative to its prefix
PYTHON_SEPARATOR                  - separator string for file path
                                    components.  Equivalent to ``os.sep`` in
                                    Python.
PYTHON_PATH_SEPARATOR             - separator string for PATH-style
                                    environment variables.  Equivalent to
                                    ``os.pathsep`` in Python.
PYTHON_EXTENSION_MODULE_SUFFIX    - suffix of the compiled module. For example, on
                                    Linux, based on environment, it could be ``.cpython-35m-x86_64-linux-gnu.so``.

The following functions are defined:

python_extension_module

For libraries meant to be used as Python extension modules, either dynamically loaded or directly linked. Amend the configuration of the library target (created using add_library) with additional options needed to build and use the referenced library as a Python extension module.

python_extension_module(<Target>

[LINKED_MODULES_VAR <LinkedModVar>] [FORWARD_DECL_MODULES_VAR <ForwardDeclModVar>] [MODULE_SUFFIX <ModuleSuffix>])

Only extension modules that are configured to be built as MODULE libraries can be runtime-loaded through the standard Python import mechanism. All other modules can only be included in standalone applications that are written to expect their presence. In addition to being linked against the libraries for these modules, such applications must forward declare their entry points and initialize them prior to use. To generate these forward declarations and initializations, see python_modules_header.

If <Target> does not refer to a target, then it is assumed to refer to an extension module that is not linked at all, but compiled along with other source files directly into an executable. Adding these modules does not cause any library configuration modifications, and they are not added to the list of linked modules. They still must be forward declared and initialized, however, and so are added to the forward declared modules list.

If the associated target is of type MODULE_LIBRARY, the LINK_FLAGS target property is used to set symbol visibility and export only the module init function. This applies to GNU and MSVC compilers.

Options:

LINKED_MODULES_VAR <LinkedModVar>

Name of the variable referencing a list of extension modules whose libraries must be linked into the executables of any stand-alone applications that use them. By default, the global property PY_LINKED_MODULES_LIST is used.

FORWARD_DECL_MODULES_VAR <ForwardDeclModVar>

Name of the variable referencing a list of extension modules whose entry points must be forward declared and called by any stand-alone applications that use them. By default, the global property PY_FORWARD_DECL_MODULES_LIST is used.

MODULE_SUFFIX <ModuleSuffix>

Suffix appended to the python extension module file. The default suffix is retrieved using sysconfig.get_config_var("SO")", if not available, the default is then .so on unix and .pyd on windows. Setting the variable PYTHON_EXTENSION_MODULE_SUFFIX in the caller scope defines the value used for all extensions not having a suffix explicitly specified using MODULE_SUFFIX parameter.

python_standalone_executable

python_standalone_executable(<Target>)

For standalone executables that initialize their own Python runtime (such as when building source files that include one generated by Cython with the –embed option). Amend the configuration of the executable target (created using add_executable) with additional options needed to properly build the referenced executable.

python_modules_header

Generate a header file that contains the forward declarations and initialization routines for the given list of Python extension modules. <Name> is the logical name for the header file (no file extensions). <HeaderFilename> is the actual destination filename for the header file (e.g.: decl_modules.h).

python_modules_header(<Name> [HeaderFilename]

[FORWARD_DECL_MODULES_LIST <ForwardDeclModList>] [HEADER_OUTPUT_VAR <HeaderOutputVar>] [INCLUDE_DIR_OUTPUT_VAR <IncludeDirOutputVar>])

without the extension is used as the logical name. If only <Name> is

If only <Name> is provided, and it ends in the “.h” extension, then it is assumed to be the <HeaderFilename>. The filename of the header file provided, and it does not end in the “.h” extension, then the <HeaderFilename> is assumed to <Name>.h.

The exact contents of the generated header file depend on the logical <Name>. It should be set to a value that corresponds to the target application, or for the case of multiple applications, some identifier that conveyes its purpose. It is featured in the generated multiple inclusion guard as well as the names of the generated initialization routines.

The generated header file includes forward declarations for all listed modules, as well as implementations for the following class of routines:

int <Name>_<Module>(void)

Initializes the python extension module, <Module>. Returns an integer handle to the module.

void <Name>_LoadAllPythonModules(void)

Initializes all listed python extension modules.

void CMakeLoadAllPythonModules(void);

Alias for <Name>_LoadAllPythonModules whose name does not depend on <Name>. This function is excluded during preprocessing if the preprocessing macro EXCLUDE_LOAD_ALL_FUNCTION is defined.

void Py_Initialize_Wrapper();

Wrapper arpund Py_Initialize() that initializes all listed python extension modules. This function is excluded during preprocessing if the preprocessing macro EXCLUDE_PY_INIT_WRAPPER is defined. If this function is generated, then Py_Initialize() is redefined to a macro that calls this function.

Options:

FORWARD_DECL_MODULES_LIST <ForwardDeclModList>

List of extension modules for which to generate forward declarations of their entry points and their initializations. By default, the global property PY_FORWARD_DECL_MODULES_LIST is used.

HEADER_OUTPUT_VAR <HeaderOutputVar>

Name of the variable to set to the path to the generated header file. By default, <Name> is used.

INCLUDE_DIR_OUTPUT_VAR <IncludeDirOutputVar>

Name of the variable to set to the path to the directory containing the generated header file. By default, <Name>_INCLUDE_DIRS is used.

Defined variables:

<HeaderOutputVar>

The path to the generated header file

<IncludeDirOutputVar>

Directory containing the generated header file

Example usage

find_package(PythonExtensions)
find_package(Cython)
find_package(Boost COMPONENTS python)

# Simple Cython Module -- no executables
add_cython_target(_module.pyx)
add_library(_module MODULE ${_module})
python_extension_module(_module)

# Mix of Cython-generated code and C++ code using Boost Python
# Stand-alone executable -- no modules
include_directories(${Boost_INCLUDE_DIRS})
add_cython_target(main.pyx CXX EMBED_MAIN)
add_executable(main boost_python_module.cxx ${main})
target_link_libraries(main ${Boost_LIBRARIES})
python_standalone_executable(main)

# stand-alone executable with three extension modules:
# one statically linked, one dynamically linked, and one loaded at runtime
#
# Freely mixes Cython-generated code, code using Boost-Python, and
# hand-written code using the CPython API.

# module1 -- statically linked
add_cython_target(module1.pyx)
add_library(module1 STATIC ${module1})
python_extension_module(module1
                        LINKED_MODULES_VAR linked_module_list
                        FORWARD_DECL_MODULES_VAR fdecl_module_list)

# module2 -- dynamically linked
include_directories(${Boost_INCLUDE_DIRS})
add_library(module2 SHARED boost_module2.cxx)
target_link_libraries(module2 ${Boost_LIBRARIES})
python_extension_module(module2
                        LINKED_MODULES_VAR linked_module_list
                        FORWARD_DECL_MODULES_VAR fdecl_module_list)

# module3 -- loaded at runtime
add_cython_target(module3a.pyx)
add_library(module3 MODULE ${module3a} module3b.cxx)
target_link_libraries(module3 ${Boost_LIBRARIES})
python_extension_module(module3
                        LINKED_MODULES_VAR linked_module_list
                        FORWARD_DECL_MODULES_VAR fdecl_module_list)

# application executable -- generated header file + other source files
python_modules_header(modules
                      FORWARD_DECL_MODULES_LIST ${fdecl_module_list})
include_directories(${modules_INCLUDE_DIRS})

add_cython_target(mainA)
add_cython_target(mainC)
add_executable(main ${mainA} mainB.cxx ${mainC} mainD.c)

target_link_libraries(main ${linked_module_list} ${Boost_LIBRARIES})
python_standalone_executable(main)

The following functions are defined:

add_python_library

Add a library that contains a mix of C, C++, Fortran, Cython, F2PY, Template, and Tempita sources. The required targets are automatically generated to “lower” source files from their high-level representation to a file that the compiler can accept.

add_python_library(<Name>

SOURCES [source1 [source2 …]] [INCLUDE_DIRECTORIES [dir1 [dir2 …]] [LINK_LIBRARIES [lib1 [lib2 …]] [DEPENDS [source1 [source2 …]]])

Example usage

find_package(PythonExtensions)

file(GLOB arpack_sources ARPACK/SRC/*.f ARPACK/UTIL/*.f)

 add_python_library(arpack_scipy
   SOURCES ${arpack_sources}
           ${g77_wrapper_sources}
   INCLUDE_DIRECTORIES ARPACK/SRC
 )
add_python_extension

Add a extension that contains a mix of C, C++, Fortran, Cython, F2PY, Template, and Tempita sources. The required targets are automatically generated to “lower” source files from their high-level representation to a file that the compiler can accept.

add_python_extension(<Name>

SOURCES [source1 [source2 …]] [INCLUDE_DIRECTORIES [dir1 [dir2 …]] [LINK_LIBRARIES [lib1 [lib2 …]] [DEPENDS [source1 [source2 …]]])

Example usage

find_package(PythonExtensions)

file(GLOB arpack_sources ARPACK/SRC/*.f ARPACK/UTIL/*.f)

 add_python_extension(arpack_scipy
   SOURCES ${arpack_sources}
           ${g77_wrapper_sources}
   INCLUDE_DIRECTORIES ARPACK/SRC
 )