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