5

I am trying to run gperf from a cmake file.

I created a very minimal CMakeLists.txt below.

When I run it by

$ cmake .
$ make 

It does not create the example.hpp file

What could be problem with the below CMakeLists.txt?

cmake_minimum_required( VERSION 2.6 )

function(gperf_generate_new source target)

        add_custom_target(${target} echo "Creating ${target}")

        add_custom_command(
                SOURCE ${source}
                TARGET ${target}
                COMMAND gperf -L c++ ${source} > ${target}
                OUTPUTS ${target}
                DEPENDS ${source}
                )

endfunction()

gperf_generate_new(command_options.new.gperf example.hpp)
Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213
Sri Kant
  • 169
  • 1
  • 12
  • Check [this](http://stackoverflow.com/questions/2354473/cmake-add-custom-command?rq=1) and [this](http://stackoverflow.com/questions/17696872/cmake-add-custom-command-that-is-executed-on-every-build?rq=1) Q/As. Likely your question is a duplicate. – user3159253 Oct 13 '15 at 00:15
  • Problem with your CMakeLists.txt file is that you use incorrect options for `add_custom_command`: `SOURCE` option is completely unrelated to this command, `OUTPUTS` should be `OUTPUT` and shouldn't be mixed with `TARGET` option (`OUTPUT` and `TARGET` are used for *different flows* of this command). **CMake [documentation](https://cmake.org/cmake/help/cmake2.6docs.html#section_Commands) precisely describes command's signatures**, no needs to guess which additional option can take this or that command. – Tsyvarev Oct 13 '15 at 07:24

1 Answers1

3

Files, produced by source-files generators(like gpref) are rarely needed as standalone. Instead, these source files are usually used for creating executables or libraries inside a project.

So, standard pattern of using source-file generators in the CMake looks like:

# Call add_custom_command() with appropriate arguments for generate output file
# Note, that *gperf* will work in the build tree,
# so for file in the source tree full path should be used.
function(gperf_generate_new input output)
    add_custom_command(
        OUTPUT ${output}
        COMMAND gperf -L c++ ${input} > ${output}
        DEPENDS ${input}
        COMMENT "Generate ${output}" # Just for nice message during build
    )
endfunction()

# Generate *example.hpp* file ...
gperf_generate_new(${CMAKE_CURRENT_SOURCE_DIR}/command_options.new.gperf example.hpp)

# ... for use it in executable
add_executable(my_program ${CMAKE_CURRENT_BINARY_DIR}/example.hpp <other sources>)

If you want only to test whether example.hpp is generating, instead of add_executable() use

add_custom_target(my_target
    ALL # Force target to be built with default build target.
    DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/example.hpp
)

Note, that linkage between add_custom_command and add_custom_target is expressed using same filename in their OUTPUT and DEPENDS options correspondingly. With such link order of these commands is insignificant (but both commands should be called from the same CMakeLists.txt script).

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • on my build system it worked only when I changed it to add_custom_target(my_target ALL # Force target to be built with default build target. DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/example.hpp ) – Sri Kant Oct 14 '15 at 23:17
  • 1
    For me it works unmodified, but CMake doesn't explicitely document usage of relative paths in `DEPENDS` option for `add_custom_target`. I have fixed my post. – Tsyvarev Oct 15 '15 at 07:29