mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-02 03:39:43 -06:00
This fixes Sphinx warning `Unexpected section title or transition`. RST transition element (horizontal line) cannot appear inside some container-like elements.
468 lines
15 KiB
CMake
468 lines
15 KiB
CMake
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
# file LICENSE.rst or https://cmake.org/licensing for details.
|
|
|
|
#[=======================================================================[.rst:
|
|
FindBISON
|
|
---------
|
|
|
|
Finds the Bison command-line parser generator and provides a CMake command to
|
|
generate custom build rules for using Bison:
|
|
|
|
.. code-block:: cmake
|
|
|
|
find_package(BISON [<version>] ...)
|
|
|
|
Bison is a parser generator that replaced earlier Yacc (Yet Another
|
|
Compiler-Compiler). On Unix-like systems, most common implementation is
|
|
GNU Bison. On Windows, this module looks for Windows-compatible Bison, if
|
|
installed.
|
|
|
|
Result Variables
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
This module defines the following variables:
|
|
|
|
``BISON_FOUND``
|
|
Boolean indicating whether (the requested version of) Bison is found.
|
|
|
|
``BISON_VERSION``
|
|
The version of Bison found.
|
|
|
|
Cache Variables
|
|
^^^^^^^^^^^^^^^
|
|
|
|
The following cache variables may also be set:
|
|
|
|
``BISON_EXECUTABLE``
|
|
The path to the ``bison`` command-line program.
|
|
|
|
Commands
|
|
^^^^^^^^
|
|
|
|
This module provides the following command if ``bison`` is found:
|
|
|
|
.. command:: bison_target
|
|
|
|
Creates a custom build rule to generate a parser file from a Yacc file using
|
|
Bison:
|
|
|
|
.. code-block:: cmake
|
|
|
|
bison_target(
|
|
<name>
|
|
<input-yacc-file>
|
|
<output-parser-file>
|
|
[DEFINES_FILE <header>]
|
|
[VERBOSE [<file>]] # The [<file>] argument is deprecated
|
|
[REPORT_FILE <file>]
|
|
[OPTIONS <options>...]
|
|
[COMPILE_FLAGS <string>] # Deprecated
|
|
)
|
|
|
|
.. versionchanged:: 3.14
|
|
When policy :policy:`CMP0088` is set to ``NEW``, ``bison`` runs in the
|
|
:variable:`CMAKE_CURRENT_BINARY_DIR` directory.
|
|
|
|
``<name>``
|
|
String used as an identifier for this command invocation.
|
|
|
|
``<input-yacc-file>``
|
|
The path to an input Yacc source file (``.y``). If given as a relative
|
|
path, it will be interpreted relative to the current source directory
|
|
(:variable:`CMAKE_CURRENT_SOURCE_DIR`).
|
|
|
|
``<output-parser-file>``
|
|
The path of the output parser file to be generated by Bison. If given as a
|
|
relative path, it will be interpreted relative to the current Bison working
|
|
directory.
|
|
|
|
``DEFINES_FILE <header>``
|
|
.. versionadded:: 3.4
|
|
|
|
By default, Bison can generate a header file containing the list of tokens.
|
|
This option allows specifying a custom ``<header>`` file to be generated by
|
|
Bison. If given as a relative path, it will be interpreted relative to the
|
|
current Bison working directory.
|
|
|
|
``VERBOSE [<file>]``
|
|
Enables generation of a verbose grammar and parser report. By default, the
|
|
report file is created in the current Bison working directory and named
|
|
``<output-parser-filename>.output``.
|
|
|
|
``<file>``
|
|
.. deprecated:: 3.7
|
|
Use ``VERBOSE REPORT_FILE <file>``.
|
|
|
|
Specifies the path to which the report file should be copied. This
|
|
argument is retained for backward compatibility and only works when the
|
|
``<output-parser-file>`` is specified as an absolute path.
|
|
|
|
``REPORT_FILE <file>``
|
|
.. versionadded:: 3.7
|
|
|
|
Used in combination with ``VERBOSE`` to specify a custom path for the report
|
|
output ``<file>``, overriding the default location. If given as a relative
|
|
path, it will be interpreted relative to the current Bison working
|
|
directory.
|
|
|
|
``OPTIONS <options>...``
|
|
.. versionadded:: 4.0
|
|
|
|
A :ref:`semicolon-separated list <CMake Language Lists>` of extra options
|
|
added to the ``bison`` command line.
|
|
|
|
``COMPILE_FLAGS <string>``
|
|
.. deprecated:: 4.0
|
|
Superseded by ``OPTIONS <options>...``.
|
|
|
|
A string of space-separated extra options added to the ``bison`` command
|
|
line. A :ref:`semicolon-separated list <CMake Language Lists>` will not
|
|
work.
|
|
|
|
.. rubric:: Command variables
|
|
|
|
This command also defines the following variables:
|
|
|
|
``BISON_<name>_DEFINED``
|
|
Boolean indicating whether this command was successfully invoked.
|
|
|
|
``BISON_<name>_INPUT``
|
|
The input source file, an alias for ``<input-yacc-file>``.
|
|
|
|
``BISON_<name>_OUTPUT_SOURCE``
|
|
The output parser file generated by ``bison``.
|
|
|
|
``BISON_<name>_OUTPUT_HEADER``
|
|
The header file generated by ``bison``, if any.
|
|
|
|
``BISON_<name>_OUTPUTS``
|
|
A list of files generated by ``bison``, including the output parser file,
|
|
header file, and report file.
|
|
|
|
``BISON_<name>_OPTIONS``
|
|
.. versionadded:: 4.0
|
|
|
|
A list of command-line options used for the ``bison`` command.
|
|
|
|
``BISON_<name>_COMPILE_FLAGS``
|
|
.. deprecated:: 4.0
|
|
Superseded by ``BISON_<name>_OPTIONS`` variable with the same value.
|
|
|
|
A list of command-line options used for the ``bison`` command.
|
|
|
|
Examples
|
|
^^^^^^^^
|
|
|
|
Examples: Finding Bison
|
|
"""""""""""""""""""""""
|
|
|
|
Finding Bison:
|
|
|
|
.. code-block:: cmake
|
|
|
|
find_package(BISON)
|
|
|
|
Finding Bison with a minimum required version:
|
|
|
|
.. code-block:: cmake
|
|
|
|
find_package(BISON 2.1.3)
|
|
|
|
Finding Bison and making it required (if Bison is not found, processing stops
|
|
with an error message):
|
|
|
|
.. code-block:: cmake
|
|
|
|
find_package(BISON 2.1.3 REQUIRED)
|
|
|
|
Example: Generating Parser
|
|
""""""""""""""""""""""""""
|
|
|
|
Finding Bison and adding input Yacc source file ``parser.y`` to be processed by
|
|
Bison into ``parser.cpp`` source file with header ``parser.h`` at build phase:
|
|
|
|
.. code-block:: cmake
|
|
|
|
find_package(BISON)
|
|
|
|
if(BISON_FOUND)
|
|
bison_target(MyParser parser.y parser.cpp DEFINES_FILE parser.h)
|
|
endif()
|
|
|
|
add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
|
|
|
|
Examples: Command-line Options
|
|
""""""""""""""""""""""""""""""
|
|
|
|
Adding additional command-line options to the ``bison`` executable can be passed
|
|
as a list. For example, adding the ``-Wall`` option to report all warnings, and
|
|
``--no-lines`` (``-l``) to not generate ``#line`` directives:
|
|
|
|
.. code-block:: cmake
|
|
|
|
find_package(BISON)
|
|
|
|
if(BISON_FOUND)
|
|
bison_target(MyParser parser.y parser.cpp OPTIONS -Wall --no-lines)
|
|
endif()
|
|
|
|
:manual:`Generator expressions <cmake-generator-expressions(7)>` can be used in
|
|
the ``OPTIONS <options>...`` argument. For example, to add the ``--debug``
|
|
(``-t``) option only for the ``Debug`` build type:
|
|
|
|
.. code-block:: cmake
|
|
|
|
find_package(BISON)
|
|
|
|
if(BISON_FOUND)
|
|
bison_target(MyParser parser.y parser.cpp OPTIONS $<$<CONFIG:Debug>:-t>)
|
|
endif()
|
|
|
|
See Also
|
|
^^^^^^^^
|
|
|
|
* The :module:`FindFLEX` module to find Flex scanner generator.
|
|
#]=======================================================================]
|
|
|
|
find_program(BISON_EXECUTABLE NAMES bison win-bison win_bison DOC "path to the bison executable")
|
|
mark_as_advanced(BISON_EXECUTABLE)
|
|
|
|
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
|
|
# sets BISON_TARGET_cmdopt
|
|
macro(BISON_TARGET_option_extraopts Options)
|
|
set(BISON_TARGET_cmdopt "")
|
|
set(BISON_TARGET_extraopts "${Options}")
|
|
separate_arguments(BISON_TARGET_extraopts)
|
|
list(APPEND BISON_TARGET_cmdopt ${BISON_TARGET_extraopts})
|
|
endmacro()
|
|
|
|
# internal macro
|
|
# sets BISON_TARGET_output_header and BISON_TARGET_cmdopt
|
|
macro(BISON_TARGET_option_defines BisonOutput Header)
|
|
if("${Header}" STREQUAL "")
|
|
# default header path generated by bison (see option -d)
|
|
string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${BisonOutput}")
|
|
string(REPLACE "c" "h" _fileext ${_fileext})
|
|
string(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}"
|
|
BISON_TARGET_output_header "${BisonOutput}")
|
|
list(APPEND BISON_TARGET_cmdopt "-d")
|
|
else()
|
|
set(BISON_TARGET_output_header "${Header}")
|
|
list(APPEND BISON_TARGET_cmdopt "--defines=${BISON_TARGET_output_header}")
|
|
endif()
|
|
endmacro()
|
|
|
|
# internal macro
|
|
# sets BISON_TARGET_verbose_file and BISON_TARGET_cmdopt
|
|
macro(BISON_TARGET_option_report_file BisonOutput ReportFile)
|
|
if("${ReportFile}" STREQUAL "")
|
|
get_filename_component(BISON_TARGET_output_path "${BisonOutput}" PATH)
|
|
get_filename_component(BISON_TARGET_output_name "${BisonOutput}" NAME_WE)
|
|
set(BISON_TARGET_verbose_file
|
|
"${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output")
|
|
else()
|
|
set(BISON_TARGET_verbose_file "${ReportFile}")
|
|
list(APPEND BISON_TARGET_cmdopt "--report-file=${BISON_TARGET_verbose_file}")
|
|
endif()
|
|
if(NOT IS_ABSOLUTE "${BISON_TARGET_verbose_file}")
|
|
cmake_policy(GET CMP0088 _BISON_CMP0088
|
|
PARENT_SCOPE # undocumented, do not use outside of CMake
|
|
)
|
|
if("x${_BISON_CMP0088}x" STREQUAL "xNEWx")
|
|
set(BISON_TARGET_verbose_file "${CMAKE_CURRENT_BINARY_DIR}/${BISON_TARGET_verbose_file}")
|
|
else()
|
|
set(BISON_TARGET_verbose_file "${CMAKE_CURRENT_SOURCE_DIR}/${BISON_TARGET_verbose_file}")
|
|
endif()
|
|
unset(_BISON_CMP0088)
|
|
endif()
|
|
endmacro()
|
|
|
|
# internal macro
|
|
# adds a custom command and sets
|
|
# BISON_TARGET_cmdopt, BISON_TARGET_extraoutputs
|
|
macro(BISON_TARGET_option_verbose Name BisonOutput filename)
|
|
cmake_policy(GET CMP0088 _BISON_CMP0088
|
|
PARENT_SCOPE # undocumented, do not use outside of CMake
|
|
)
|
|
set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
|
if("x${_BISON_CMP0088}x" STREQUAL "xNEWx")
|
|
set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
endif()
|
|
unset(_BISON_CMP0088)
|
|
|
|
list(APPEND BISON_TARGET_cmdopt "--verbose")
|
|
list(APPEND BISON_TARGET_outputs
|
|
"${BISON_TARGET_verbose_file}")
|
|
if (NOT "${filename}" STREQUAL "")
|
|
if(IS_ABSOLUTE "${filename}")
|
|
set(BISON_TARGET_verbose_extra_file "${filename}")
|
|
else()
|
|
set(BISON_TARGET_verbose_extra_file "${_BISON_WORKING_DIRECTORY}/${filename}")
|
|
endif()
|
|
|
|
add_custom_command(OUTPUT ${BISON_TARGET_verbose_extra_file}
|
|
COMMAND ${CMAKE_COMMAND} -E copy
|
|
"${BISON_TARGET_verbose_file}"
|
|
"${filename}"
|
|
VERBATIM
|
|
DEPENDS
|
|
"${BISON_TARGET_verbose_file}"
|
|
COMMENT "[BISON][${Name}] Copying bison verbose table to ${filename}"
|
|
WORKING_DIRECTORY ${_BISON_WORKING_DIRECTORY})
|
|
list(APPEND BISON_TARGET_extraoutputs
|
|
"${BISON_TARGET_verbose_extra_file}")
|
|
unset(BISON_TARGET_verbose_extra_file)
|
|
unset(_BISON_WORKING_DIRECTORY)
|
|
endif()
|
|
endmacro()
|
|
|
|
#============================================================
|
|
# bison_target() public macro
|
|
#============================================================
|
|
#
|
|
macro(BISON_TARGET Name BisonInput BisonOutput)
|
|
set(BISON_TARGET_outputs "${BisonOutput}")
|
|
set(BISON_TARGET_extraoutputs "")
|
|
|
|
# Parsing parameters
|
|
set(BISON_TARGET_PARAM_OPTIONS
|
|
)
|
|
set(BISON_TARGET_PARAM_ONE_VALUE_KEYWORDS
|
|
COMPILE_FLAGS
|
|
DEFINES_FILE
|
|
REPORT_FILE
|
|
)
|
|
set(BISON_TARGET_PARAM_MULTI_VALUE_KEYWORDS
|
|
OPTIONS
|
|
VERBOSE
|
|
)
|
|
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")
|
|
elseif("${BISON_TARGET_ARG_VERBOSE}" MATCHES ";")
|
|
# [VERBOSE [<file>] hack: <file> is non-multi value by usage
|
|
message(SEND_ERROR "Usage")
|
|
else()
|
|
|
|
BISON_TARGET_option_extraopts("${BISON_TARGET_ARG_COMPILE_FLAGS}")
|
|
|
|
if(BISON_TARGET_ARG_OPTIONS)
|
|
list(APPEND BISON_TARGET_cmdopt ${BISON_TARGET_ARG_OPTIONS})
|
|
endif()
|
|
|
|
BISON_TARGET_option_defines("${BisonOutput}" "${BISON_TARGET_ARG_DEFINES_FILE}")
|
|
BISON_TARGET_option_report_file("${BisonOutput}" "${BISON_TARGET_ARG_REPORT_FILE}")
|
|
if(NOT "${BISON_TARGET_ARG_VERBOSE}" STREQUAL "")
|
|
BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${BISON_TARGET_ARG_VERBOSE}")
|
|
else()
|
|
# [VERBOSE [<file>]] is used with no argument or is not used
|
|
set(BISON_TARGET_args "${ARGN}")
|
|
list(FIND BISON_TARGET_args "VERBOSE" BISON_TARGET_args_indexof_verbose)
|
|
if(${BISON_TARGET_args_indexof_verbose} GREATER -1)
|
|
# VERBOSE is used without <file>
|
|
BISON_TARGET_option_verbose(${Name} ${BisonOutput} "")
|
|
endif()
|
|
endif()
|
|
|
|
list(APPEND BISON_TARGET_outputs "${BISON_TARGET_output_header}")
|
|
|
|
cmake_policy(GET CMP0088 _BISON_CMP0088
|
|
PARENT_SCOPE # undocumented, do not use outside of CMake
|
|
)
|
|
set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
|
set(_BisonInput "${BisonInput}")
|
|
if("x${_BISON_CMP0088}x" STREQUAL "xNEWx")
|
|
set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
if(NOT IS_ABSOLUTE "${_BisonInput}")
|
|
set(_BisonInput "${CMAKE_CURRENT_SOURCE_DIR}/${_BisonInput}")
|
|
endif()
|
|
endif()
|
|
unset(_BISON_CMP0088)
|
|
|
|
# Bison cannot create output directories. Create any missing determined
|
|
# directories where the files will be generated if they don't exist yet.
|
|
set(_BisonMakeDirectoryCommand "")
|
|
foreach(output IN LISTS BISON_TARGET_outputs)
|
|
cmake_path(GET output PARENT_PATH dir)
|
|
if(dir)
|
|
list(APPEND _BisonMakeDirectoryCommand ${dir})
|
|
endif()
|
|
unset(dir)
|
|
endforeach()
|
|
if(_BisonMakeDirectoryCommand)
|
|
list(REMOVE_DUPLICATES _BisonMakeDirectoryCommand)
|
|
list(
|
|
PREPEND
|
|
_BisonMakeDirectoryCommand
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory
|
|
)
|
|
endif()
|
|
|
|
add_custom_command(OUTPUT ${BISON_TARGET_outputs}
|
|
${_BisonMakeDirectoryCommand}
|
|
COMMAND ${BISON_EXECUTABLE} ${BISON_TARGET_cmdopt} -o ${BisonOutput} ${_BisonInput}
|
|
VERBATIM
|
|
DEPENDS ${_BisonInput}
|
|
COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}"
|
|
WORKING_DIRECTORY ${_BISON_WORKING_DIRECTORY}
|
|
COMMAND_EXPAND_LISTS)
|
|
|
|
unset(_BISON_WORKING_DIRECTORY)
|
|
|
|
# define target variables
|
|
set(BISON_${Name}_DEFINED TRUE)
|
|
set(BISON_${Name}_INPUT ${_BisonInput})
|
|
set(BISON_${Name}_OUTPUTS ${BISON_TARGET_outputs} ${BISON_TARGET_extraoutputs})
|
|
set(BISON_${Name}_OPTIONS ${BISON_TARGET_cmdopt})
|
|
set(BISON_${Name}_COMPILE_FLAGS ${BISON_TARGET_cmdopt})
|
|
set(BISON_${Name}_OUTPUT_SOURCE "${BisonOutput}")
|
|
set(BISON_${Name}_OUTPUT_HEADER "${BISON_TARGET_output_header}")
|
|
|
|
unset(_BisonInput)
|
|
unset(_BisonMakeDirectoryCommand)
|
|
endif()
|
|
endmacro()
|
|
#
|
|
#============================================================
|
|
|
|
endif()
|
|
|
|
include(FindPackageHandleStandardArgs)
|
|
find_package_handle_standard_args(BISON REQUIRED_VARS BISON_EXECUTABLE
|
|
VERSION_VAR BISON_VERSION)
|