cmake find_package:找不到头文件

问题描述 投票:0回答:1

我正在结合 Visual Studio Code 学习 cmake。今天我开始将其应用到一个使用 SDL2 包的旧项目中。我很高兴发现 find_project 函数,并使用它。

这是我的 cmakelists.txt:

# version 3.11 or later of CMake or needed later for installing GoogleTest
# so let's require it now.
cmake_minimum_required(VERSION 3.11-3.18)

project(Drawbox)

add_library(Drawbox Drawbox.SDL.cpp)

find_package(SDL2 REQUIRED)
if(SDL2_FOUND)
    message(STATUS "SDL2_DIR : ${SDL2_DIR}")
    message(STATUS "SDL2_INCLUDE_DIRS" : ${SDL2_INCLUDE_DIRS})
    message(STATUS "INTERACE_INCLUDE_DIRECTORIES : ${INTERACE_INCLUDE_DIRECTORIES}")
    message(STATUS "INTERACE_LINK_DIRECTORIES : ${INTERACE_LINK_DIRECTORIES}")
endif(SDL2_FOUND)

include_directories(${SDL2_INCLUDE_DIRS} "AP Classes")
target_link_libraries(Drawbox ${SDL2_LIBRARIES})

target_include_directories(${PROJECT_NAME}
    PUBLIC ${PROJECT_SOURCE_DIR})

target_compile_features(Drawbox PUBLIC cxx_std_98)

这是一些输出:

[cmake] -- SDL2_DIR : /opt/local/lib/cmake/SDL2 
[cmake] -- SDL2_INCLUDE_DIRS:/opt/local/include/SDL2 
[cmake] -- INTERACE_INCLUDE_DIRECTORIES :   
[cmake] -- INTERACE_LINK_DIRECTORIES :

(如果它在 /Library/Frameworks/SDL2.framework , 这是可用的。如何让它更喜欢那个?)

但是然后我构建,并得到错误:

构建 CXX 对象 CMakeFiles/Drawbox.dir/Drawbox.SDL.cpp.o [build] /Users/ken/Programs/SDL/Drawbox.SDL.cpp:23:10:致命错误: 找不到“SDL2/SDL.h”文件 [build] #include [build]
^~~~~~~~~~~~ [build] 生成 1 个错误。

我可以确认文件 /opt/local/include/SDL2/SDL.h 确实存在。那我做错了什么?

这是文件 /opt/local/lib/cmake/SDL2/sdl2-config.cmake ,它似乎已随软件包一起安装:

# sdl2 cmake project-config input for ./configure scripts

set(prefix "/opt/local") 
set(exec_prefix "${prefix}")
set(libdir "${exec_prefix}/lib")
set(includedir "${prefix}/include")
set(SDL2_PREFIX "${prefix}")
set(SDL2_EXEC_PREFIX "${exec_prefix}")
set(SDL2_LIBDIR "${libdir}")
set(SDL2_INCLUDE_DIRS "${includedir}/SDL2")
set(SDL2_LIBRARIES "-L${SDL2_LIBDIR}  -lSDL2")
string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)

if(NOT TARGET SDL2::SDL2)
  # provide SDL2::SDL2, SDL2::SDL2main and SDL2::SDL2-static targets, like SDL2Config.cmake does, for compatibility

  # Remove -lSDL2 as that is handled by CMake, note the space at the end so it does not replace e.g. -lSDL2main
  # This may require "libdir" beeing set (from above)
  string(REPLACE "-lSDL2 " "" SDL2_EXTRA_LINK_FLAGS " -lSDL2 ")
  # also get rid of -lSDL2main, if you want to link against that use both SDL2::SDL2main and SDL2::SDL2 (in that order)
  # (SDL2Config.cmake has the same behavior)
  string(REPLACE "-lSDL2main" "" SDL2_EXTRA_LINK_FLAGS ${SDL2_EXTRA_LINK_FLAGS})
  string(STRIP "${SDL2_EXTRA_LINK_FLAGS}" SDL2_EXTRA_LINK_FLAGS)
  string(REPLACE "-lSDL2 " "" SDL2_EXTRA_LINK_FLAGS_STATIC " -lm -liconv  -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-weak_framework,CoreHaptics -Wl,-weak_framework,GameController -Wl,-framework,ForceFeedback -lobjc -Wl,-framework,CoreVideo -Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,IOKit -Wl,-weak_framework,QuartzCore -Wl,-weak_framework,Metal ")
  string(STRIP "${SDL2_EXTRA_LINK_FLAGS_STATIC}" SDL2_EXTRA_LINK_FLAGS_STATIC)

if(WIN32 AND NOT MSVC)
  # MINGW needs very special handling, because the link order must be exactly -lmingw32 -lSDL2main -lSDL2
  # for it to work at all (and -mwindows somewhere); a normal SHARED IMPORTED or STATIC IMPORTED library always puts itself first
  # so handle this like a header-only lib and put everything in INTERFACE_LINK_LIBRARIES

  add_library(SDL2::SDL2 INTERFACE IMPORTED)
  set_target_properties(SDL2::SDL2 PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
    INTERFACE_LINK_LIBRARIES "-L${SDL2_LIBDIR} -lSDL2")

  add_library(SDL2::SDL2main INTERFACE IMPORTED)
  set_target_properties(SDL2::SDL2main PROPERTIES
    INTERFACE_LINK_LIBRARIES "-L${SDL2_LIBDIR} -lmingw32 -lSDL2main -mwindows")

else() # (not WIN32) or MSVC

  add_library(SDL2::SDL2 SHARED IMPORTED)
  set_target_properties(SDL2::SDL2 PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_LOCATION "${SDL2_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}SDL2${CMAKE_SHARED_LIBRARY_SUFFIX}")

  if(MSVC)
    # This file is generated when building SDL2 with autotools and MinGW, and MinGW/dlltool
    # isn't able to generate .lib files that are usable by recent MSVC versions 
    # (something about "module unsafe for SAFESEH"; SAFESEH is enabled by default in MSVC).
    # The .lib file for SDL2.dll *could* be generated with `gendef SDL2.dll` and then
    # `lib.exe /machine:x86 /def:SDL2.def /out:SDL2.lib` (or /machine:amd64)
    # but that requires lib.exe from a Visual Studio installation - and that still doesn't
    # give you a static SDL2main.lib with SAFESEH support that you'll need (unless you don't use SDL2main)
    # Note that when building SDL2 with CMake and MSVC, the result works with both MinGW and MSVC.

    message(FATAL_ERROR, "This build of libSDL2 only supports MinGW, not MSVC (Visual C++), because it lacks .lib files!")
    # MSVC needs SDL2.lib set as IMPORTED_IMPLIB to link against (comment out message() call above if you added SDL2.lib yourself)
    set_target_properties(SDL2::SDL2 PROPERTIES IMPORTED_IMPLIB "${SDL2_LIBDIR}/SDL2.lib")
  else()
    # this mustn't be set for MSVC, so do it here in an extra call here
    set_target_properties(SDL2::SDL2 PROPERTIES INTERFACE_LINK_LIBRARIES  "${SDL2_EXTRA_LINK_FLAGS}")
  endif()

  add_library(SDL2::SDL2main STATIC IMPORTED)
  set_target_properties(SDL2::SDL2main PROPERTIES
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_LOCATION "${SDL2_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2main${CMAKE_STATIC_LIBRARY_SUFFIX}")

endif() # (not WIN32) or MSVC

  add_library(SDL2::SDL2-static STATIC IMPORTED)
  set_target_properties(SDL2::SDL2-static PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_LOCATION "${SDL2_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2${CMAKE_STATIC_LIBRARY_SUFFIX}"
    INTERFACE_LINK_LIBRARIES "${SDL2_EXTRA_LINK_FLAGS_STATIC}")

endif() # 不是目标 SDL2::SDL2

c++ cmake include
1个回答
0
投票

include_directories
仅适用于其后定义的目标。

将您的

add_library
调用靠近底部,它会神奇地起作用。更好的是:明确使用
target_include_directories
在目标上设置该属性。

© www.soinside.com 2019 - 2024. All rights reserved.