ADD_CUSTOM_COMMAND and *multiple* DEPENDS Was: [CMake] Reexecute cmake to update build.make

Mathieu Malaterre mathieu.malaterre at gmail.com
Fri Jun 8 06:52:15 EDT 2007


Ok,

  I finally found out what was the issue. I cannot believe no one has
had the issue in the past, as it seems like a pretty easy mistake to
do:

SET(deps foo.h bla.h)
SEPARATE_ARGUMENTS(deps) # very very important !
ADD_CUSTOM_COMMAND(
      OUTPUT ...
      COMMAND ...
      DEPENDS ${deps}
    )

that fixes all my previous problems. I cannot believe I did not realize
my deps were separated by a ';' ... I really need new glasses

Thanks,
-Mathieu


On 6/7/07, gga <ggarra at advancedsl.com.ar> wrote:
> Mathieu Malaterre wrote:
> > It looks like you are on windows. Could you please try a nmake ("NMake
> > Makefiles") build and do:
> >
>
> I'm on Linux (thank god), but have also a windows box with vnc.
> I tried it on both, with cmake2.5 (CVS), but cmake2.4 should be the same
> ( I was using it before ).
>
> > 1)
> > edit foo.i
> > $ nmake TargetName
> >
> > vs
> > 2)
> > edit foo.i
> > $ nmake rebuild_cache
> > $ nmake TargetName
> >
> > Version #1 should fail, versus #2 should rebuild build.make, and redo
> > the correct dep.
>
> Both rebuild TargetName, as they should.
>
> I did find two bugs that were making the stuff less efficient in the
> modified UseSWIG.cmake file I posted.
>
> One due to python files always need regeneration due to their .py files
> (I was wrapping stuff for ruby, so it is now more efficient for
> languages other than python) and that the swig -MF invocation was also
> creating the wrapper needlessly.
>
> There's still one minor gotcha where you can still fool the system not
> to detect a dependency change, but it is somewhat obscure so I won't
> mention it.
>
>
> --
> Gonzalo Garramuño
> ggarra at advancedsl.com.ar
>
> AMD4400 - ASUS48N-E
> GeForce7300GT
> Kubuntu Edgy
>
> # - SWIG module for CMake
> # Defines the following macros:
> #   SWIG_ADD_MODULE(name language [ files ])
> #     - Define swig module with given name and specified language
> #   SWIG_LINK_LIBRARIES(name [ libraries ])
> #     - Link libraries to swig module
> #   SWIG_GET_WRAPPER_DEPENDENCIES(swigFile genWrapper language DEST_VARIABLE)
> #     - Put dependencies of the wrapper genWrapper generated by swig from
> #     swigFile in DEST_VARIABLE
> # All other macros are for internal use only.
> # To get the actual name of the swig module,
> # use: ${SWIG_MODULE_name_REAL_NAME}.
> # Set Source files properties such as CPLUSPLUS and SWIG_FLAGS to specify
> # special behavior of SWIG. Also global CMAKE_SWIG_FLAGS can be used to add
> # special flags to all swig calls.
> # Another special variable is CMAKE_SWIG_OUTDIR, it allows one to specify
> # where to write all the swig generated module (swig -outdir option)
> # The name-specific variable SWIG_MODULE_<name>_EXTRA_DEPS may be used
> # to specify extra dependencies for the generated modules.
>
> SET(SWIG_CXX_EXTENSION "cxx")
> SET(SWIG_EXTRA_LIBRARIES "")
>
> SET(SWIG_PYTHON_EXTRA_FILE_EXTENSION "py")
>
> #
> # Get dependencies of the generated wrapper.
> #
> MACRO(SWIG_GET_WRAPPER_DEPENDENCIES swigFile genWrapper language DEST_VARIABLE)
>   GET_FILENAME_COMPONENT(swig_getdeps_basename ${swigFile} NAME_WE)
>   GET_FILENAME_COMPONENT(swig_getdeps_outdir ${genWrapper} PATH)
>   GET_SOURCE_FILE_PROPERTY(swig_getdeps_extra_flags "${swigFile}" SWIG_FLAGS)
>   IF("${swig_getdeps_extra_flags}" STREQUAL "NOTFOUND")
>     SET(swig_getdeps_extra_flags "")
>   ENDIF("${swig_getdeps_extra_flags}" STREQUAL "NOTFOUND")
>
>   IF(NOT swig_getdeps_outdir)
>     SET(swig_getdeps_outdir ${CMAKE_CURRENT_BINARY_DIR})
>   ENDIF(NOT swig_getdeps_outdir)
>   SET(swig_getdeps_depsfile
>     "${swig_getdeps_outdir}/swig_${swig_getdeps_basename}_deps.txt")
>   GET_DIRECTORY_PROPERTY(swig_getdeps_include_directories INCLUDE_DIRECTORIES)
>   SET(swig_getdeps_include_dirs)
>   FOREACH(it ${swig_getdeps_include_directories})
>     SET(swig_getdeps_include_dirs ${swig_getdeps_include_dirs} -I${it})
>   ENDFOREACH(it)
>
>
>   EXECUTE_PROCESS(
>     COMMAND ${SWIG_EXECUTABLE} -MM -MF ${swig_getdeps_depsfile} ${swig_getdeps_extra_flags} ${CMAKE_SWIG_FLAGS} -${language} -o ${genWrapper} ${swig_getdeps_include_dirs} ${swigFile}
>     RESULT_VARIABLE swig_getdeps_result
>     ERROR_VARIABLE swig_getdeps_error
>     OUTPUT_STRIP_TRAILING_WHITESPACE)
>
>
>   IF(NOT ${swig_getdeps_result} EQUAL 0)
>     MESSAGE(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -MM -MF ${swig_getdeps_depsfile} ${swig_getdeps_extra_flags} ${CMAKE_SWIG_FLAGS} -${language} -o ${genWrapper} ${swig_getdeps_include_dirs} ${swigFile}\" failed with output:\n${swig_getdeps_error}")
>     SET(swig_getdeps_dependencies "")
>   ELSE(NOT ${swig_getdeps_result} EQUAL 0)
>     FILE(READ ${swig_getdeps_depsfile} ${DEST_VARIABLE})
>
>     # Remove the first line
>     STRING(REGEX REPLACE "^.+: +\\\\\n +" ""
>       ${DEST_VARIABLE} "${${DEST_VARIABLE}}")
>     # Clean the end of each line
>     STRING(REGEX REPLACE " +(\\\\)?\n" "\n" ${DEST_VARIABLE}
>       "${${DEST_VARIABLE}}")
>     # Clean beginning of each line
>     STRING(REGEX REPLACE "\n +" "\n"
>       ${DEST_VARIABLE} "${${DEST_VARIABLE}}")
>     # clean paths
>     STRING(REGEX REPLACE "\\\\\\\\" "/" ${DEST_VARIABLE}
>       "${${DEST_VARIABLE}}")
>     STRING(REGEX REPLACE "\n" ";"
>       ${DEST_VARIABLE} "${${DEST_VARIABLE}}")
>   ENDIF(NOT ${swig_getdeps_result} EQUAL 0)
> ENDMACRO(SWIG_GET_WRAPPER_DEPENDENCIES)
>
>
> #
> # For given swig module initialize variables associated with it
> #
> MACRO(SWIG_MODULE_INITIALIZE name language)
>   STRING(TOUPPER "${language}" swig_uppercase_language)
>   STRING(TOLOWER "${language}" swig_lowercase_language)
>   SET(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_language}")
>   SET(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}")
>
>   IF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xUNKNOWNx$")
>     MESSAGE(FATAL_ERROR "SWIG Error: Language \"${language}\" not found")
>   ENDIF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xUNKNOWNx$")
>
>   SET(SWIG_MODULE_${name}_REAL_NAME "${name}")
>   IF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPYTHONx$")
>     SET(SWIG_MODULE_${name}_REAL_NAME "_${name}")
>   ENDIF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPYTHONx$")
>   IF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPERLx$")
>     SET(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
>   ENDIF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPERLx$")
> ENDMACRO(SWIG_MODULE_INITIALIZE)
>
> #
> # For a given language, input file, and output file, determine extra files that
> # will be generated. This is internal swig macro.
> #
>
> MACRO(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
>   IF( language EQUAL "python" )
>     FOREACH(it ${SWIG_PYTHON_EXTRA_FILE_EXTENSION})
>       SET(${outfiles} ${${outfiles}}
>         "${generatedpath}/${infile}.${it}")
>     ENDFOREACH(it)
>   ENDIF( language EQUAL "python" )
> ENDMACRO(SWIG_GET_EXTRA_OUTPUT_FILES)
>
> #
> # Take swig (*.i) file and add proper custom commands for it
> #
> MACRO(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
>   SET(swig_full_infile ${infile})
>   GET_FILENAME_COMPONENT(swig_source_file_path "${infile}" PATH)
>   GET_FILENAME_COMPONENT(swig_source_file_name_we "${infile}" NAME_WE)
>   GET_SOURCE_FILE_PROPERTY(swig_source_file_generated ${infile} GENERATED)
>   GET_SOURCE_FILE_PROPERTY(swig_source_file_cplusplus ${infile} CPLUSPLUS)
>   GET_SOURCE_FILE_PROPERTY(swig_source_file_flags ${infile} SWIG_FLAGS)
>   IF("${swig_source_file_flags}" STREQUAL "NOTFOUND")
>     SET(swig_source_file_flags "")
>   ENDIF("${swig_source_file_flags}" STREQUAL "NOTFOUND")
>   SET(swig_source_file_fullname "${infile}")
>   IF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
>     STRING(REGEX REPLACE
>       "^${CMAKE_CURRENT_SOURCE_DIR}" ""
>       swig_source_file_relative_path
>       "${swig_source_file_path}")
>   ELSE(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
>     IF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
>       STRING(REGEX REPLACE
>         "^${CMAKE_CURRENT_BINARY_DIR}" ""
>         swig_source_file_relative_path
>         "${swig_source_file_path}")
>       SET(swig_source_file_generated 1)
>     ELSE(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
>       SET(swig_source_file_relative_path "${swig_source_file_path}")
>       IF(swig_source_file_generated)
>         SET(swig_source_file_fullname "${CMAKE_CURRENT_BINARY_DIR}/${infile}")
>       ELSE(swig_source_file_generated)
>         SET(swig_source_file_fullname "${CMAKE_CURRENT_SOURCE_DIR}/${infile}")
>       ENDIF(swig_source_file_generated)
>     ENDIF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
>   ENDIF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
>
>   SET(swig_generated_file_fullname
>     "${CMAKE_CURRENT_BINARY_DIR}")
>   IF(swig_source_file_relative_path)
>     SET(swig_generated_file_fullname
>       "${swig_generated_file_fullname}/${swig_source_file_relative_path}")
>   ENDIF(swig_source_file_relative_path)
>   # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
>   IF(CMAKE_SWIG_OUTDIR)
>     SET(swig_outdir ${CMAKE_SWIG_OUTDIR})
>   ELSE(CMAKE_SWIG_OUTDIR)
>     SET(swig_outdir ${CMAKE_CURRENT_BINARY_DIR})
>   ENDIF(CMAKE_SWIG_OUTDIR)
>   SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
>     swig_extra_generated_files
>     "${swig_outdir}"
>     "${swig_source_file_name_we}")
>   SET(swig_generated_file_fullname
>     "${swig_generated_file_fullname}/${swig_source_file_name_we}")
>   # add the language into the name of the file (i.e. TCL_wrap)
>   # this allows for the same .i file to be wrapped into different languages
>   SET(swig_generated_file_fullname
>     "${swig_generated_file_fullname}${SWIG_MODULE_${name}_LANGUAGE}_wrap")
>
>   IF(swig_source_file_cplusplus)
>     SET(swig_generated_file_fullname
>       "${swig_generated_file_fullname}.${SWIG_CXX_EXTENSION}")
>   ELSE(swig_source_file_cplusplus)
>     SET(swig_generated_file_fullname
>       "${swig_generated_file_fullname}.c")
>   ENDIF(swig_source_file_cplusplus)
>
>   #MESSAGE("Full path to source file: ${swig_source_file_fullname}")
>   #MESSAGE("Full path to the output file: ${swig_generated_file_fullname}")
>   GET_DIRECTORY_PROPERTY(cmake_include_directories INCLUDE_DIRECTORIES)
>   SET(swig_include_dirs)
>   FOREACH(it ${cmake_include_directories})
>     SET(swig_include_dirs ${swig_include_dirs} "-I${it}")
>   ENDFOREACH(it)
>
>   SET(swig_special_flags)
>   # default is c, so add c++ flag if it is c++
>   IF(swig_source_file_cplusplus)
>     SET(swig_special_flags ${swig_special_flags} "-c++")
>   ENDIF(swig_source_file_cplusplus)
>   SET(swig_extra_flags)
>   IF(SWIG_MODULE_${name}_EXTRA_FLAGS)
>     SET(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS})
>   ENDIF(SWIG_MODULE_${name}_EXTRA_FLAGS)
>   SWIG_GET_WRAPPER_DEPENDENCIES("${swig_source_file_fullname}"
>     "${swig_generated_file_fullname}" ${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}
>     swig_extra_dependencies)
>
>   LIST(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${swig_extra_dependencies})
>   # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
>   IF(CMAKE_SWIG_OUTDIR)
>     ADD_CUSTOM_COMMAND(
>       OUTPUT "${swig_generated_file_fullname}"
>       COMMAND "${SWIG_EXECUTABLE}"
>       ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}"
>       ${swig_source_file_flags}
>       ${CMAKE_SWIG_FLAGS}
>       -outdir ${CMAKE_SWIG_OUTDIR}
>       ${swig_special_flags}
>       ${swig_extra_flags}
>       ${swig_include_dirs}
>       -o "${swig_generated_file_fullname}"
>       "${swig_source_file_fullname}"
>       MAIN_DEPENDENCY "${swig_source_file_fullname}"
>       DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS}
>       COMMENT "Swig source")
>   ELSE(CMAKE_SWIG_OUTDIR)
>     ADD_CUSTOM_COMMAND(
>     OUTPUT "${swig_generated_file_fullname}" ${swig_extra_generated_files}
>       COMMAND "${SWIG_EXECUTABLE}"
>       ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}"
>       ${swig_source_file_flags}
>       ${CMAKE_SWIG_FLAGS}
>       -outdir ${swig_outdir}
>       ${swig_special_flags}
>       ${swig_extra_flags}
>       ${swig_include_dirs}
>       -o "${swig_generated_file_fullname}"
>       "${swig_source_file_fullname}"
>       MAIN_DEPENDENCY "${swig_source_file_fullname}"
>       DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS}
>       COMMENT "Swig source")
>   ENDIF(CMAKE_SWIG_OUTDIR)
>   SET_SOURCE_FILES_PROPERTIES("${swig_generated_file_fullname}"
>     PROPERTIES GENERATED 1)
>   SET(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files})
> ENDMACRO(SWIG_ADD_SOURCE_TO_MODULE)
>
> #
> # Create Swig module
> #
> MACRO(SWIG_ADD_MODULE name language)
>   SWIG_MODULE_INITIALIZE(${name} ${language})
>   SET(swig_dot_i_sources)
>   SET(swig_other_sources)
>   FOREACH(it ${ARGN})
>     IF(${it} MATCHES ".*\\.i$")
>       SET(swig_dot_i_sources ${swig_dot_i_sources} "${it}")
>     ELSE(${it} MATCHES ".*\\.i$")
>       SET(swig_other_sources ${swig_other_sources} "${it}")
>     ENDIF(${it} MATCHES ".*\\.i$")
>   ENDFOREACH(it)
>
>   SET(swig_generated_sources)
>   FOREACH(it ${swig_dot_i_sources})
>     SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it})
>     SET(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}")
>   ENDFOREACH(it)
>   GET_DIRECTORY_PROPERTY(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
>   SET_DIRECTORY_PROPERTIES(PROPERTIES
>     ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}")
>   ADD_LIBRARY(${SWIG_MODULE_${name}_REAL_NAME}
>     MODULE
>     ${swig_generated_sources}
>     ${swig_other_sources})
>   SET_TARGET_PROPERTIES(${SWIG_MODULE_${name}_REAL_NAME}
>     PROPERTIES PREFIX "")
> ENDMACRO(SWIG_ADD_MODULE)
>
> #
> # Like TARGET_LINK_LIBRARIES but for swig modules
> #
> MACRO(SWIG_LINK_LIBRARIES name)
>   IF(SWIG_MODULE_${name}_REAL_NAME)
>     TARGET_LINK_LIBRARIES(${SWIG_MODULE_${name}_REAL_NAME} ${ARGN})
>   ELSE(SWIG_MODULE_${name}_REAL_NAME)
>     MESSAGE(SEND_ERROR "Cannot find Swig library \"${name}\".")
>   ENDIF(SWIG_MODULE_${name}_REAL_NAME)
> ENDMACRO(SWIG_LINK_LIBRARIES name)
>
>
>


-- 
Mathieu


More information about the CMake mailing list