cmakeperl-xs

How to use the program's exit status at compile time?


This question is subsequent to my previous one: How to integrate such kind of source generator into CMake build chain?

Currently, the C source file is generated from XS in this way:

set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${file_src_by_xs} PROPERTIES GENERATED 1)
add_custom_target(${file_src_by_xs}
    COMMAND ${XSUBPP_EXECUTABLE} ${XSUBPP_EXTRA_OPTIONS} ${lang_args} ${typemap_args} ${file_xs} >${CMAKE_CURRENT_BINARY_DIR}/${file_src_by_xs}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    DEPENDS ${file_xs} ${files_xsh} ${_XSUBPP_TYPEMAP_FILES}
    COMMENT "generating source from XS file ${file_xs}"
)

The GENERATED property let cmake don't check the existence of this source file at configure time, and add_custom_target let the xsubpp always re-run at each compile. The reason for always rerun is because xsubpp will generate an incomplete source file even if it fails, so there are possibility that the whole compiling continues with an incomplete source file.

I found it is time consuming to always re-run source generator and recompile it. So I want to have it re-run only when dependent XS files are modified. However, if I do so, the incomplete generated source file must be deleted.

So my question is: is there any way to remove the generated file, only when the program exit abnormally at compile time?

Or more generic: is there any way to run a command depending on another command's exit status at compile time?


Solution

  • Inspired by @Lindydancer's answer, I achieved the purpose by multiple COMMANDs in one target, and it don't need to write an external wrapper script.

    set(source_file_ok ${source_file}.ok)
    add_custom_command(
        OUTPUT ${source_file} ${source_file_ok}
        DEPENDS ${xs_file} ${xsh_files}
        COMMAND rm -f ${source_file_ok}
        COMMAND xsubpp ...... >${source_file}
        COMMAND touch ${source_file_ok}
    )
    
    add_library(${xs_lib} ${source_file})
    add_dependencies(${xs_lib} ${source_file} ${source_file_ok})
    

    The custom target has 3 commands. The OK file only exists when xsubpp is success, and this file is added as a dependency of the library. When xsubpp is not success, the dependency on the OK file will force the custom command to be run again.

    The only flaw is cross-platform: not all OS have touch and rm, so the name of these two commands should be decided according to OS type.