CMake – Automatically regenerate a file using an external tool and custom target upon “make”

Software development
Hi. I'm working on a project and I use cmake for generating "projects", that is, under Linux, a Makefile. I also use an external tool (re2c) to generate the scanner, and an included tool to generate the parser (lemon, part of sqlite). The problem is I need to "cmake" every time I change something in the grammar (lemon_parser.y) or in the scanner ( The cmake files are: ./CMakeLists.txt: 1 cmake_minimum_required(VERSION 2.6) 2 project(Calc C) 3 #set(CMAKE_USE_RELATIVE_PATHS ON FORCE) 4 set(CMAKE_BUILD_TYPE Debug) 5 #set(CMAKE_VERBOSE_MAKEFILE true) 6 include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/parser) 7 8 IF ( ${CMAKE_SOURCE_DIR} EQUAL ${CMAKE_BINARY_DIR} AND NOT ${ACCEPT_SOURCE_DIR} ) 9 MESSAGE( FATAL "Please choose a different directory for building" ) 10 ENDIF( ${CMAKE_SOURCE_DIR} EQUAL ${CMAKE_BINARY_DIR} AND NOT ${ACCEPT_SOURCE_DIR} ) 11 12 add_subdirectory(lemon) 13 add_subdirectory(hash) 14 add_subdirectory(parser) 15 #memory safety 16 #add_subdirectory(memory_safety) 17 18 add_executable(calc main.c) 19 target_link_libraries(calc hash parser) ./parser/CMakeLists.txt and a file irrelevant to the problem: ./hash/CMakeLists.txt: 1 add_library(hash STATIC hash_table.c hash_functions.c)

Answer Wiki

Thanks. We'll let you know when a new response is added.

Fixed it in the meanwhile:

<pre> 1 set(parser_odir “${CMAKE_CURRENT_BINARY_DIR}/”)
2 include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${parser_odir})
4 #The right way to me would be to use the commands (2) and (4)
5 #but it seems one needs (1) and (3) instead, if regeneration
6 #of the and parser.y is desired with only a “make”
7 #command.
8 #
9 #Why I think that would be the right way? Because commands
10 #have output (in cmake terms) and targets don’t.
12 add_custom_target(lemon_parser
13 COMMAND ${CMAKE_COMMAND} -E copy “lemon_parser.y” “${parser_odir}lemon_parser.y”
14 #(1):
15 COMMAND ${PROJECT_BINARY_DIR}/lemon/lemon d=”${CMAKE_CURRENT_SOURCE_DIR}/lempar.c” “${parser_odir}lemon_parser.y”
17 COMMENT “add_custom_target(lemon_parser)”
18 )
19 add_custom_command(OUTPUT “${parser_odir}lemon_parser.c”
20 #(2):
21 # COMMAND ${PROJECT_BINARY_DIR}/lemon/lemon d=”${CMAKE_CURRENT_SOURCE_DIR}/lempar.c” “${parser_odir}lemon_parser.y”
22 COMMENT “add_custom_command(parser)”
23 )
25 add_custom_target(re2c_scanner
26 #(3):
27 COMMAND re2c -i “${CMAKE_CURRENT_SOURCE_DIR}/” > “${parser_odir}scanner.c”
28 COMMENT “add_custom_target(re2c_scanner)”
29 )
30 add_custom_command(OUTPUT “${parser_odir}scanner.c”
31 #(4):
32 # COMMAND re2c -i “${CMAKE_CURRENT_SOURCE_DIR}/” > “${parser_odir}scanner.c”
33 COMMENT “add_custom_command(scanner)”
34 )
35 add_library(parser STATIC parser.c ast.c “${parser_odir}scanner.c” “${parser_odir}lemon_parser.c”)
36 add_dependencies(parser lemon_parser re2c_scanner)
37 add_dependencies(lemon_parser lemon)</pre>

Hopefully this will help someone else.

Discuss This Question: 1  Reply

There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.
  • OriginalCopy
    OOps, I've forgot to paste the parser/CMakeLists.txt:
         1	set(parser_odir "${CMAKE_CURRENT_BINARY_DIR}/")
         2	include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${parser_odir})
         4	add_custom_command(
         5			OUTPUT "${parser_odir}lemon_parser.c" "${parser_odir}lemon_parser.h" "${parser_odir}lemon_parser.out"
         6			#COMMAND ${PROJECT_BINARY_DIR}/lemon/lemon d="${CMAKE_CURRENT_SOURCE_DIR}/lempar.c" "${CMAKE_CURRENT_BINARY_DIR}/lemon_parser.y"
         7			COMMAND ${PROJECT_BINARY_DIR}/lemon/lemon d="${CMAKE_CURRENT_SOURCE_DIR}/lempar.c" "${parser_odir}lemon_parser.y"
         8			DEPENDS lemon "${CMAKE_CURRENT_SOURCE_DIR}/lemon_parser.y"
         9		)
        10	#add_custom_target(lemon_parser)
        11	file(READ lemon_parser.y parser_content)
        12	file(WRITE "${parser_odir}lemon_parser.y" "${parser_content}")
        14	add_custom_command(
        15			OUTPUT "${parser_odir}scanner.c" 
        16			COMMAND re2c -i "${CMAKE_CURRENT_SOURCE_DIR}/" > "${parser_odir}scanner.c"
        17			DEPENDS "${parser_odir}lemon_parser.h" "${CMAKE_CURRENT_SOURCE_DIR}/"
        18		)
        19	#add_custom_target(re2c_scanner)
        21	#add_custom_target(lemon_parser ALL DEPENDS "${parser_odir}lemon_parser.c" "${parser_odir}lemon_parser.h")
        22	add_library(parser STATIC "${parser_odir}lemon_parser.c" "${parser_odir}scanner.c" parser.c ast.c)
    Is there any feedback area? The small "ask a question" textarea on the right is hard to use.
    30 pointsBadges:

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

Thanks! We'll email you when relevant content is added and updated.


Share this item with your network: