#.rst: # FindBISON # --------- # # Find ``bison`` executable and provide a macro to generate custom build rules. # # The module defines the following variables: # # ``BISON_EXECUTABLE`` # path to the ``bison`` program # # ``BISON_VERSION`` # version of ``bison`` # # ``BISON_FOUND`` # true if the program was found # # The minimum required version of ``bison`` can be specified using the # standard CMake syntax, e.g. ``find_package(BISON 2.1.3)``. # # If ``bison`` is found, the module defines the macro:: # # BISON_TARGET( # [COMPILE_FLAGS ] # [DEFINES_FILE ] # [VERBOSE ] # ) # # which will create a custom rule to generate a parser. ```` is # the path to a yacc file. ```` is the name of the source file # generated by bison. A header file is also be generated, and contains # the token list. # # The options are: # # ``COMPILE_FLAGS `` # Specify flags to be added to the ``bison`` command line. # # ``DEFINES_FILE `` # Specify a non-default header ```` to be generated by ``bison``. # # ``VERBOSE `` # Tell ``bison`` to write verbose descriptions of the grammar and # parser to the given ````. # # The macro defines the following variables: # # ``BISON__DEFINED`` # true is the macro ran successfully # # ``BISON__INPUT`` # The input source file, an alias for # # ``BISON__OUTPUT_SOURCE`` # The source file generated by bison # # ``BISON__OUTPUT_HEADER`` # The header file generated by bison # # ``BISON__OUTPUTS`` # The sources files generated by bison # # ``BISON__COMPILE_FLAGS`` # Options used in the ``bison`` command line # # Example usage: # # .. code-block:: cmake # # find_package(BISON) # BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp # DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.h) # add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS}) #============================================================================= # Copyright 2009 Kitware, Inc. # Copyright 2006 Tristan Carel # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) find_program(BISON_EXECUTABLE NAMES bison win_bison DOC "path to the bison executable") mark_as_advanced(BISON_EXECUTABLE) include(CMakeParseArguments) if(BISON_EXECUTABLE) # the bison commands should be executed with the C locale, otherwise # the message (which are parsed) may be translated set(_Bison_SAVED_LC_ALL "$ENV{LC_ALL}") set(ENV{LC_ALL} C) execute_process(COMMAND ${BISON_EXECUTABLE} --version OUTPUT_VARIABLE BISON_version_output ERROR_VARIABLE BISON_version_error RESULT_VARIABLE BISON_version_result OUTPUT_STRIP_TRAILING_WHITESPACE) set(ENV{LC_ALL} ${_Bison_SAVED_LC_ALL}) if(NOT ${BISON_version_result} EQUAL 0) message(SEND_ERROR "Command \"${BISON_EXECUTABLE} --version\" failed with output:\n${BISON_version_error}") else() # Bison++ if("${BISON_version_output}" MATCHES "^bison\\+\\+ Version ([^,]+)") set(BISON_VERSION "${CMAKE_MATCH_1}") # GNU Bison elseif("${BISON_version_output}" MATCHES "^bison \\(GNU Bison\\) ([^\n]+)\n") set(BISON_VERSION "${CMAKE_MATCH_1}") elseif("${BISON_version_output}" MATCHES "^GNU Bison (version )?([^\n]+)") set(BISON_VERSION "${CMAKE_MATCH_2}") endif() endif() # internal macro macro(BISON_TARGET_option_verbose Name BisonOutput filename) list(APPEND BISON_TARGET_cmdopt "--verbose") get_filename_component(BISON_TARGET_output_path "${BisonOutput}" PATH) get_filename_component(BISON_TARGET_output_name "${BisonOutput}" NAME_WE) add_custom_command(OUTPUT ${filename} COMMAND ${CMAKE_COMMAND} -E copy "${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output" "${filename}" VERBATIM DEPENDS "${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output" COMMENT "[BISON][${Name}] Copying bison verbose table to ${filename}" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) set(BISON_${Name}_VERBOSE_FILE ${filename}) list(APPEND BISON_TARGET_extraoutputs "${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output") endmacro() # internal macro macro(BISON_TARGET_option_extraopts Options) set(BISON_TARGET_extraopts "${Options}") separate_arguments(BISON_TARGET_extraopts) list(APPEND BISON_TARGET_cmdopt ${BISON_TARGET_extraopts}) endmacro() # internal macro macro(BISON_TARGET_option_defines Header) set(BISON_TARGET_output_header "${Header}") list(APPEND BISON_TARGET_cmdopt --defines=${BISON_TARGET_output_header}) endmacro() #============================================================ # BISON_TARGET (public macro) #============================================================ # macro(BISON_TARGET Name BisonInput BisonOutput) set(BISON_TARGET_output_header "") set(BISON_TARGET_cmdopt "") set(BISON_TARGET_outputs "${BisonOutput}") # Parsing parameters set(BISON_TARGET_PARAM_OPTIONS) set(BISON_TARGET_PARAM_ONE_VALUE_KEYWORDS VERBOSE COMPILE_FLAGS DEFINES_FILE ) set(BISON_TARGET_PARAM_MULTI_VALUE_KEYWORDS) cmake_parse_arguments( BISON_TARGET_ARG "${BISON_TARGET_PARAM_OPTIONS}" "${BISON_TARGET_PARAM_ONE_VALUE_KEYWORDS}" "${BISON_TARGET_PARAM_MULTI_VALUE_KEYWORDS}" ${ARGN} ) if(NOT "${BISON_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "") message(SEND_ERROR "Usage") else() if(NOT "${BISON_TARGET_ARG_VERBOSE}" STREQUAL "") BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${BISON_TARGET_ARG_VERBOSE}") endif() if(NOT "${BISON_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "") BISON_TARGET_option_extraopts("${BISON_TARGET_ARG_COMPILE_FLAGS}") endif() if(NOT "${BISON_TARGET_ARG_DEFINES_FILE}" STREQUAL "") BISON_TARGET_option_defines("${BISON_TARGET_ARG_DEFINES_FILE}") endif() if("${BISON_TARGET_output_header}" STREQUAL "") # Header's name generated by bison (see option -d) list(APPEND BISON_TARGET_cmdopt "-d") string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${BisonOutput}") string(REPLACE "c" "h" _fileext ${_fileext}) string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}" BISON_TARGET_output_header "${BisonOutput}") endif() list(APPEND BISON_TARGET_outputs "${BISON_TARGET_output_header}") add_custom_command(OUTPUT ${BISON_TARGET_outputs} ${BISON_TARGET_extraoutputs} COMMAND ${BISON_EXECUTABLE} ${BISON_TARGET_cmdopt} -o ${BisonOutput} ${BisonInput} VERBATIM DEPENDS ${BisonInput} COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) # define target variables set(BISON_${Name}_DEFINED TRUE) set(BISON_${Name}_INPUT ${BisonInput}) set(BISON_${Name}_OUTPUTS ${BISON_TARGET_outputs}) set(BISON_${Name}_COMPILE_FLAGS ${BISON_TARGET_cmdopt}) set(BISON_${Name}_OUTPUT_SOURCE "${BisonOutput}") set(BISON_${Name}_OUTPUT_HEADER "${BISON_TARGET_output_header}") endif() endmacro() # #============================================================ endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE VERSION_VAR BISON_VERSION) # FindBISON.cmake ends here