Specifying Include Directories for NumPy Extension Modules: Alternatives to `add_include_dirs()`


Purpose

  • By providing the correct paths, the compiler can locate the necessary headers for building your extension module.
  • add_include_dirs() helps specify the directories containing these header files during compilation.
  • Involves building custom extension modules for NumPy, which might rely on header files from external libraries.

Context

  • Warning
    numpy.distutils is deprecated as of NumPy versions for Python 3.12 and above. It's recommended to use the standard setuptools module for packaging.
  • add_include_dirs() is part of the numpy.distutils module, a legacy mechanism for building NumPy packages.

Usage

  1. import numpy as np
    from numpy.distutils.core import Extension
    
  2. Create an Extension object

    This object represents the extension module you're building.

    ext = Extension("my_extension", [], include_dirs=[path_to_include_dir])
    
    • Replace "my_extension" with your desired module name.
    • [] is an empty list for source files (you can add source files here if needed).
    • include_dirs is a list containing the paths to directories with header files. You can provide multiple paths as a list.

Example

import numpy as np

from numpy.distutils.core import Extension


def test_func():
    inc_dir = np.get_include()  # Get NumPy's include directory
    ext = Extension("my_extension", [], include_dirs=[inc_dir])
    return ext

if __name__ == "__main__":
    ext = test_func()
    print(ext.include_dirs)

This code retrieves NumPy's include directory using np.get_include() and adds it to the include_dirs list of an extension module named my_extension.

Key Points

  • Consider migrating to setuptools for packaging NumPy extensions in newer Python versions.
  • Ensure you provide the correct paths to the header files your extension module needs.
  • add_include_dirs() is specifically for numpy.distutils, not the recommended setuptools.


from setuptools import Extension, setup

# Replace with the actual header file directory path
header_dir = "/path/to/your/header/files"

ext_mod = Extension("my_extension",
                    sources=["my_extension.c"],  # Replace with your source file
                    include_dirs=[header_dir])

setup(
    ext_modules=[ext_mod],
    # ... other setup arguments
)

This example:

  1. Imports Extension and setup from setuptools.
  2. Defines the header_dir variable with the path to your header files.
  3. Creates an Extension object named ext_mod:
    • "my_extension": Desired module name.
    • ["my_extension.c"]: List of source files (replace with your C source file).
    • include_dirs=[header_dir]: Path to the header directory.
  4. Uses setup to configure the build process, including the ext_modules argument with the ext_mod object.

Remember to replace placeholders like "my_extension" and "path/to/your/header/files" with your specific values.



    • Recommended approach for newer Python versions.
    • setuptools provides the Extension class similar to numpy.distutils.core.Extension.
    • Within the Extension object, use the include_dirs keyword argument:
    from setuptools import Extension, setup
    
    header_dir = "/path/to/your/header/files"
    
    ext_mod = Extension("my_extension",
                        sources=["my_extension.c"],
                        include_dirs=[header_dir])
    
    setup(
        ext_modules=[ext_mod],
        # ... other setup arguments
    )
    
  1. Using build_ext from distutils.core (for compatibility)

    • Less preferred, use only if setuptools doesn't work for specific reasons.
    • Import build_ext from distutils.core.
    • Create a build_ext subclass and override its get_gnu_incpath method (or similar method depending on the compiler) to add your include directories.
AlternativeApproachPreferred?
setuptoolsStandard module, recommended for newer Python versionsYes
distutils.coreLess preferred, for compatibility with legacy code or specific requirementsNo

Important Note

  • While distutils.core might be used for compatibility in some cases, it's generally recommended to migrate to setuptools for packaging NumPy extensions due to its broader adoption and future-proof nature.