如何在 macOS 上使用 cmake 和 find_package 链接到 FreeGlut 而不是 Glut?

问题描述

我有最新版本的 macOS Big Sur,运行基于英特尔的 cpu、clang12、cmake 3.19 和 brew。我已经通过 brew 安装了 freeglut。

但是,每当我调用 find_package(gluT) 时,它总会找到我的系统 gluT (/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/System/Library/Frameworks /gluT.framework) 已安装在 FreegluT brew 上。我尝试将 find_package 更改为 Freeglut,但没有成功。

我确信它是我遗漏的一些非常简单的东西,但对 macOS 链接过程知之甚少,这让我感到很困惑。

这是我使用的 cmake 命令行...

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -G Ninja

这是我的 cmake 文件

# Set cmake minimum version.
cmake_minimum_required(VERSION 3.15)

# Set the project details.
set(PROJECT_NAME Project)
project(${PROJECT_NAME} LANGUAGES C)

# Treat warnings as errors.
option(WarningsAsErrors "WarningsAsErrors" OFF)

# If enabled,the post build symlink will copy instead.
option(copyResources "copyResources" OFF)

option(GenerateDoxygen "GenerateDoxygen" OFF)

# disable in-source builds.
set(CMAKE_disABLE_IN_SOURCE_BUILD ON)
set(CMAKE_disABLE_SOURCE_CHANGES ON)

# Set build type to debug by default.
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Debug)
endif()

# Add Linux flag.
if(UNIX AND NOT APPLE)
    set(LINUX TRUE)
endif()

# Define the executable.
add_executable(${PROJECT_NAME})

set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 11)

# Find dependencies.
# find_package(OpenGL required COMPONENTS OpenGL)
find_package(OpenGL required)
find_package(gluT required)

# Build 3rd Party Libraries
add_subdirectory(lib)

# Define source files.
add_subdirectory(src)

if (MSVC)
    string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()

# Treat warnings as errors if enabled.
if (WarningsAsErrors)
    target_compile_options(${PROJECT_NAME} PRIVATE
            $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:-Werror>
            $<$<CXX_COMPILER_ID:MSVC>:/WX>
            )
endif(WarningsAsErrors)

# Set compile flags.
target_compile_options(${PROJECT_NAME} PRIVATE
    # Clang
    $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
        -Weverything -fcolor-diagnostics
        # disable specific warnings.
        -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded
        -Wno-deprecated-declarations -Wno-exit-time-destructors
        -Wno-switch-enum -Wno-weak-vtables -Wno-global-constructors>
    # GCC
    $<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wpedantic -fdiagnostics-color=always>
    # Visual Studio
    $<$<CXX_COMPILER_ID:MSVC>:/W4>
    # Enable the clang sanitizer.
    $<$<AND:$<CONfig:Debug>,$<CXX_COMPILER_ID:Clang>,$<PLATFORM_ID:${SANITIZER_OS}>>:${SANITIZER_FLAGS}>
)

# Link against the clang sanitizer.
target_link_options(${PROJECT_NAME} PRIVATE
    $<$<AND:$<CONfig:Debug>,$<PLATFORM_ID:${SANITIZER_OS}>>:${SANITIZER_FLAGS}>
)

if (LINUX)
    target_link_libraries(${PROJECT_NAME} PRIVATE -lm)
endif()

# Include and link against dependencies.
target_link_libraries(${PROJECT_NAME} PRIVATE OpenGL::GL OpenGL::glu gluT::gluT stb OpenAL SndFile::sndfile BigBalls::Physics lua ${CMAKE_DL_LIBS})

if (GenerateDoxygen)
    find_package(Doxygen)
    if (DOXYGEN_FOUND)
        set(DOXYGEN_IN ${CMAKE_SOURCE_DIR}/.doxyconf)

        configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
        add_custom_target(doc ALL
                COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_IN}
                WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
                COMMENT "Generating API documentation with Doxygen"
                VERBATIM)
    endif (DOXYGEN_FOUND)
endif (GenerateDoxygen)

# Symlink or copy the resources to the binary location.
if (NOT disablePostBuild)
    if (NOT copyResources)
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E create_symlink
                ${CMAKE_SOURCE_DIR}/res $<TARGET_FILE_DIR:${PROJECT_NAME}>/res)
    else()
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy_directory
                ${CMAKE_SOURCE_DIR}/res $<TARGET_FILE_DIR:${PROJECT_NAME}>/res)
    endif()
endif()

解决方法

所以 FindGLUT 是一个内置模块 参考:https://cmake.org/cmake/help/latest/module/FindGLUT.html

看源码: 见https://github.com/Kitware/CMake/blob/master/Modules/FindGLUT.cmake

所以它似乎使用 find_path()

find_path(GLUT_INCLUDE_DIR glut.h ${OPENGL_LIBRARY_DIR})

您可以尝试将 GLUT_ROOTOPENGL_LIBRARY_DIR 设置为默认路径,以帮助 CMake 找到正确的路径... 参考https://cmake.org/cmake/help/latest/command/find_path.html