Skip to content

Instantly share code, notes, and snippets.

@jrialland
Created August 30, 2022 12:39
Show Gist options
  • Save jrialland/dd51999ab8ca96203bbece1d5bc130de to your computer and use it in GitHub Desktop.
Save jrialland/dd51999ab8ca96203bbece1d5bc130de to your computer and use it in GitHub Desktop.
CMake script for lemon parser generator
# - Find lemon executable and provides macros to generate custom build rules
# The module defines the following variables:
#
# LEMON_EXECUTABLE - path to the LEMON program
# LEMON_VERSION - version of LEMON
# LEMON_FOUND - true if the program was found
#
# If LEMON is found, the module defines the macro:
#
# LEMON_TARGET(<Name> <LEMONInp>)
#
# which will create a custom rule to generate parser. <LEMONInp> is
# the path to a LEMON file.
# exemple LEMON_TARGET(myexecutable mygrammar.lemon)
#
#
# The macro defines a set of variables:
# LEMON_${Name}_DEFINED - true is the macro ran successfully
# LEMON_${Name}_INPUT - The input source file, an alias for <LEMONInp>
# LEMON_${Name}_OUTPUT_SOURCE - The source file generated by LEMON
# LEMON_${Name}_OUTPUT_HEADER - The header file generated by LEMON
# LEMON_${Name}_OUTPUT_REPORT - The report fils generated by LEMON
cmake_minimum_required(VERSION 2.8)
find_program(LEMON_EXECUTABLE NAMES lemon DOC "path to the LEMON executable")
mark_as_advanced(LEMON_EXECUTABLE)
if(LEMON_EXECUTABLE)
execute_process(COMMAND ${LEMON_EXECUTABLE} -x
OUTPUT_VARIABLE LEMON_version_output
ERROR_VARIABLE LEMON_version_error
RESULT_VARIABLE LEMON_version_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(${LEMON_version_result} EQUAL 0)
string(REGEX REPLACE "^Lemon version ([^ ]+)$" "\\1" LEMON_VERSION "${LEMON_version_output}")
else()
message(SEND_ERROR
"Command \"${LEMON_EXECUTABLE} -x\" failed with output:
${LEMON_version_error}")
endif()
#============================================================
# LEMON_TARGET (public macro)
#============================================================
#
macro(LEMON_TARGET Name Input)
set(LEMON_TARGET_usage
"LEMON_TARGET(<Name> <Input>")
string(REGEX REPLACE ".lemon$" ".c" C_FILE ${Input})
add_custom_command(OUTPUT ${C_FILE}
COMMAND ${LEMON_EXECUTABLE}
ARGS ${Input}
DEPENDS ${Input}
COMMENT
"[LEMON][${Name}] Generating parser with LEMON ${LEMON_VERSION}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
set(LEMON_${Name}_DEFINED TRUE)
set(LEMON_${Name}_INPUT ${Input})
set(LEMON_${Name}_OUTPUT_SOURCE ${C_FILE})
set(LEMON_${Name}_OUTPUT_HEADER ${Output})
set(LEMON_${Name}_OUTPUT_REPORT ${Output})
endmacro()
endif()
# use this include when module file is located under /usr/share/cmake/Modules
#include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
# use this include when module file is located in build tree
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LEMON REQUIRED_VARS LEMON_EXECUTABLE
VERSION_VAR LEMON_VERSION)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment