kravemir
kravemir

Reputation: 11026

How to integrate ANTLR with CMake?

I'm trying to make CMake generate source files with ANTLR without any success.

Here command I'm using to generate these files:

$ antlr grammar/MyGrammar.g -fo src/parser

My executable target is defined in PROJECT/src/CMakeLists.txt, instead of PROJECT/CMakeLists.txt.

Upvotes: 2

Views: 2155

Answers (2)

ibre5041
ibre5041

Reputation: 5298

A little bit off topic but maybe it will be usefull for you. Here you'll find CMake build file for the ANTLR C runtimme library.

Generated sources are same as any other sources generated from metadata. You can use QT's UIC complier macro as an example:


    MACRO (QT4_WRAP_UI outfiles )
    QT4_EXTRACT_OPTIONS(ui_files ui_options ${ARGN})
    FOREACH (it ${ui_files})
      GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
      GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
      SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h)
         ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
         COMMAND ${QT_UIC_EXECUTABLE}
         ARGS ${ui_options} -o ${outfile} ${infile}
         MAIN_DEPENDENCY ${infile} VERBATIM)
      SET(${outfiles} ${${outfiles}} ${outfile})
    ENDFOREACH (it)
    ENDMACRO (QT4_WRAP_UI)

Upvotes: 0

Fraser
Fraser

Reputation: 78398

If you're saying you want to execute this command from within PROJECT/src/CMakeLists.txt, then the following should work:

execute_process(COMMAND antlr grammar/MyGrammar.g -fo src/parser
                WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)

Edit

Going by your comment, it looks like you want to invoke this every time you build your executable.

To tie the antlr invocation with your executable, you can use add_custom_command

add_custom_command(TARGET MyExe PRE_BUILD
                   COMMAND antlr grammar/MyGrammar.g -fo src/parser
                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)

This will only execute the antlr call if the MyExe target is out of date. If MyGrammar.g is changed, but MyExe doesn't need rebuilt, antlr doesn't run.

If you have multiple targets which depend on antlr being run, or you want to be able to invoke the antlr command any time, you could instead use add_custom_target. This adds the antlr command as a new psuedo-target. If you just build this target, all it does is invoke antlr. For each target which depends on it, use add_dependencies:

add_custom_target(Antlr 
                  COMMAND antlr grammar/MyGrammar.g -fo src/parser
                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..
                  SOURCES ../grammar/MyGrammar.g)
add_dependencies(MyExe Antlr)
add_dependencies(MyOtherExe Antlr)

As before, antlr will only be invoked if one of the dependent targets needs rebuilt, or if you explicitly build the new custom target "Antlr". (You don't need the SOURCES argument in the add_custom_target call, but this convenience feature adds MyGrammar.g to the target's files visible in IDEs like MSVC)

Upvotes: 2

Related Questions