[CMake] add_custom_command dependencies

Johann MacDonagh johann.macdonagh at gmail.com
Tue Apr 9 14:32:16 EDT 2013


I'm having a problem with something pretty basic, so I'm wondering what I'm
doing wrong.

In my build process, I want to use PyInstaller to generate an EXE. Due to
the way the source code is laid out, the scripts for this PyInstaller setup
are split among several directories. In addition, I need some special
binary files to be packaged as well (some of which are generated as other
targets). So, my solution was to copy all the scripts from the source
directories and all of the built binary files into
${CMAKE_CURRENT_BINARY_DIR}. I would then run PyInstaller from that
directory, and then I wouldn't have to worry about PYTHON_PATH issues or
trying to find binaries.

This works the first time you try to build the PyInstaller output. If a
source Python script changes and I rebuild ALL, then the only task that
occurs is that source script it copied to the ${CMAKE_CURRENT_BINARY_DIR}.
The PyInstaller package is not rebuilt. If I build ALL again immediately
afterwards (without changing any files), then the PyInstaller package is
rebuilt (no files are copied).

I've reduced this down to a sample script:

cmake_minimum_required (VERSION 2.8.10)

project (MyProj)

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/somedir/dsource.txt
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/source.txt
${CMAKE_CURRENT_BINARY_DIR}/somedir/dsource.txt
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/source.txt)
list(APPEND _MY_DEPS ${CMAKE_CURRENT_BINARY_DIR}/somedir/dsource.txt)

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/somedir/dsource2.txt
    COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/source2.txt
${CMAKE_CURRENT_BINARY_DIR}/somedir/dsource2.txt
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/source2.txt)
list(APPEND _MY_DEPS ${CMAKE_CURRENT_BINARY_DIR}/somedir/dsource2.txt)

add_custom_command(
    OUTPUT built.txt
    COMMAND ${CMAKE_COMMAND} -E touch built.txt
    DEPENDS ${_MY_DEPS})

add_custom_target(SomeTarget ALL DEPENDS built.txt)

In this example, "source.txt" and "source2.txt" in the source directory
represent two Python scripts that PyInstaller needs. Those are copied to
${CMAKE_CURRENT_BINARY_DIR}/somedir/dsource.txt and dsource2.txt. Once
those two files are copied, the PyInstaller proces can run (represented
here by touching "built.txt").

The first time i build ALL on this project, then the two files are copied
and built.txt is touched. If I change source.txt and build ALL, then only
"somedir/dsource.txt" is recopied (built.txt is not touched). If I
immediately build again without changing a file,t then "built.txt" is
touched.

I understand what's going on. "built.txt" depends on "somedir/dsource.txt"
and "somedir/dsource2.txt". When i change "source.txt" all the dependencies
are scanned. "built.txt" notices that "somedir/dsource.txt" hasn't changed,
so it doesnt rebuild. Simultaneously, "somedir/dsource.txt" notices that
"source.txt" has changed so it builds (copies). Then if i tell it to build
again, now "built.txt" notices that "somedir/dsource.txt" has changed and
it builds (touches).

Clearly this is not what I want. What am I doing wrong, or how can I fix up
this script to achieve the results I'm looking for?

Thanks!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20130409/ad90f260/attachment.html>


More information about the CMake mailing list