cmakecmake-custom-command

cmake add_custom_command


I'm struggling with add_custom_command. Let me explain the problem in detail.

I've these set of cxx files and hxx files. I run a perl script on each of them to generate a certain kind of translation file. The command looks like

perl trans.pl source.cxx -o source_cxx_tro

and similarly for header.hxx files as well.

So I'll end up with some multiple commands (each for a file)

Then I run another perl scripn on the output generated from these commands (source_cxx_tro, header_hxx_tro)

perl combine.pl source_cxx_tro header_hxx_tro -o dir.trx

dir.trx is the output file.

I've something like this.

Loop_Over_All_Files()
Add_Custom_Command (OUTPUT ${trofile} COMMAND perl trans.pl ${file} -o ${file_tro})
List (APPEND trofiles ${file_tro})
End_Loop()

Add_Custom_Command (TARGET LibraryTarget POST_BUILD COMMAND perl combine.pl ${trofiles} -o LibraryTarget.trx)

What I expect is when building the post build target, the trofiles will be built first. but it is not the case. The ${trofiles} are not getting built and hence the post build command ends in a failure. Is there any way I can tell the POST_BUILD command depend on the previous custom command ?

Any suggestions ?

Thanks in advance, Surya


Solution

  • Use add_custom_command's to create a file transformation chain

    and make the last transformation an first class entity in cmake by using add_custom_target. By default this target won't be build, unless you mark it with ALL or let another target that is built depend on it.

    set(SOURCES foo.cxx foo.hxx)
    add_library(Foo ${SOURCES})
    
    set(trofiles)
    foreach(_file ${SOURCES})
      string(REPLACE "." "_" file_tro ${_file})
      set(file_tro "${file_tro}_tro")
      add_custom_command(
        OUTPUT ${file_tro} 
        COMMAND perl ${CMAKE_CURRENT_SOURCE_DIR}/trans.pl ${CMAKE_CURRENT_SOURCE_DIR}/${_file} -o ${file_tro}
        DEPENDS ${_file}
      ) 
      list(APPEND trofiles ${file_tro})
    endforeach()
    add_custom_command(
      OUTPUT Foo.trx  
      COMMAND perl ${CMAKE_CURRENT_SOURCE_DIR}/combine.pl ${trofiles} -o Foo.trx
      DEPENDS ${trofiles}
    )
    add_custom_target(do_trofiles DEPENDS Foo.trx)
    add_dependencies(Foo do_trofiles)