Using CMake with setup.py

cmake, distutils, setup.py

Solution

Only files, not directories, can be reliably used as OUTPUT and DEPENDS. You could modify your custom command to also produce a timestamp file, something like this:

add_custom_command(
  OUTPUT ${OUTPUT}/timestamp
  COMMAND ${PYTHON} setup.py build
  COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}/timestamp
  DEPENDS ${DEPS}
)

add_custom_target(target ALL DEPENDS ${OUTPUT}/timestamp)

Problem

For a project I build a C library and implict Python bindings (via GObject introspection) with CMake. I also want to distribute some Python helper modules using distutils. I am able to build and install the module with this `CMakeLists.txt` ``` find_program(PYTHON "python") if (PYTHON) set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in") set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py") set(DEPS "${CMAKE_CURRENT_SOURCE_DIR}/module/__init__.py") set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build") configure_file(${SETUP_PY_IN} ${SETUP_PY}) add_custom_command(OUTPUT ${OUTPUT} COMMAND ${PYTHON} ARGS setup.py build DEPENDS ${DEPS}) add_custom_target(target ALL DEPENDS ${OUTPUT}) install(CODE "execute_process(COMMAND ${PYTHON} ${SETUP_PY} install)") endif() ``` and the following `setup.py.in`: ``` from distutils.core import setup, Extension if __name__ == '__main__': setup(name='foo', version='${PACKAGE_VERSION}', package_dir={ '': '${CMAKE_CURRENT_SOURCE_DIR}' }, packages=['module']) ``` Unfortunately, the build step is executed each time I run `make`. I guess, the problem is related to the output of the custom command which is a directory rather than a file. Now, is there any way to tell CMake to run `python setup.py build` only when `setup.py.in` or one of the sources changed?

Original source