Cannot configure CMake to look for Homebrew installed version of Bison
Asked Answered
A

1

8

I'm running macOS 10.14 and I installed bison version 3.2 with brew, but it refuses to link:

$ brew link bison --force
Warning: Refusing to link macOS-provided software: bison
If you need to have bison first in your PATH run:
  echo 'export PATH="/usr/local/opt/bison/bin:$PATH"' >> ~/.bash_profile

For compilers to find bison you may need to set:
  export LDFLAGS="-L/usr/local/opt/bison/lib"

My CMakeLists.txt has the following lines:

find_package(BISON 3.2 REQUIRED)
...
message(STATUS "Found bison ${BISON_VERSION} at: ${BISON_EXECUTABLE}")

cmake fails with the following output:

Could NOT find BISON: Found unsuitable version "2.3", but required is at
least "3.2" (found /usr/bin/bison)

The system-installed bison is at version 2.3, and I know that the Homebrew-installed version is at version 3.2.

The FindBISON module apparently uses the find_program CMake directive, and I've tried adding /usr/local/opt/bison/bin to CMAKE_PROGRAM_PATH, but /usr/bin/bison is always selected first no matter what. How can I force CMake to favor the Homebrew installed version of the Bison executable?

Aponeurosis answered 20/12, 2018 at 23:20 Comment(0)
Y
13

Since some things in macos depend on the Apple-provided versions of flex and bison, homebrew installs them outside of the user's normal $PATH as a "keg". A manual solution is to make sure you (and your users) add the program's brew prefix to their path (can be found by running brew --prefix bison etc.).

An automatic solution is to put this logic in your CMake files. A couple open-source projects have worked around it like this. The earliest example of a fix for this that I could find is from this commit to STP (essential part copied below).

Be sure to clear your CMake cache when messing around with all this, as BISON_EXECUTABLE (etc.) is cached.

# On macOS, search Homebrew for keg-only versions of Bison and Flex. Xcode does
# not provide new enough versions for us to use.
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
    execute_process(
        COMMAND brew --prefix bison
        RESULT_VARIABLE BREW_BISON
        OUTPUT_VARIABLE BREW_BISON_PREFIX
        OUTPUT_STRIP_TRAILING_WHITESPACE
    )
    if (BREW_BISON EQUAL 0 AND EXISTS "${BREW_BISON_PREFIX}")
        message(STATUS "Found Bison keg installed by Homebrew at ${BREW_BISON_PREFIX}")
        set(BISON_EXECUTABLE "${BREW_BISON_PREFIX}/bin/bison")
    endif()

    execute_process(
        COMMAND brew --prefix flex
        RESULT_VARIABLE BREW_FLEX
        OUTPUT_VARIABLE BREW_FLEX_PREFIX
        OUTPUT_STRIP_TRAILING_WHITESPACE
    )
    if (BREW_FLEX EQUAL 0 AND EXISTS "${BREW_FLEX_PREFIX}")
        message(STATUS "Found Flex keg installed by Homebrew at ${BREW_FLEX_PREFIX}")
        set(FLEX_EXECUTABLE "${BREW_FLEX_PREFIX}/bin/flex")
    endif()
endif()

find_package(bison REQUIRED)
find_package(flex REQUIRED)
Yang answered 2/1, 2020 at 17:59 Comment(2)
Damn you saved me. The trick that did it was deleting the contents of CMakeCache.txt and when I ran the cmake operation again, it was able to scan for the correct. I also added /usr/local/opt to the file /usr/pathsWrinkle
Thank you very much. FWIW, I needed to capitalise the package names to find_package in the last two lines (I'm using CMake 3.29). Otherwise I get CMake warnings about package names passed to find_package_handle_standard_args not matching (bison / BISON, flex / FLEX) - although, curiously, it still seemed to work.Hundred

© 2022 - 2024 — McMap. All rights reserved.