如何使用 CMake 将 Info.plist 捆绑到 MacOSX 应用程序中?

jmg*_*net 4 macos xcode cmake plist

我正在开发一个访问相机的应用程序。该项目是用 C++ 编写的,我使用 CMake 来打包它。

要在 Mac 中部署项目,我使用以下命令,然后在 Xcode 中打开项目:

cmake -G Xcode ../src
Run Code Online (Sandbox Code Playgroud)

它工作得很好,直到上次更新,当它开始抱怨:

[access] This app has crashed because it attempted to access 
privacy-sensitive data without a usage description.  The app's 
Info.plist must contain an NSCameraUsageDescription key with 
a string value explaining to the user how the app uses this data.
Program ended with exit code: 9
Run Code Online (Sandbox Code Playgroud)

所以我创建了一个新的 Info.plist 文件,其中包含以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
    <dict>
        <key>CFBundleIconFile</key>
        <string></string>
        <key>NSCameraUsageDescription</key>
        <string>This app requires to access your camera 
            to retrieve images and perform the demo</string>
    </dict>
</plist>
Run Code Online (Sandbox Code Playgroud)

我的问题是:我应该在 CMakeLists.txt 中添加什么来获取此文件并将其放在正确的位置?并且...是否有可能cmake -G Xcode将其正确包含在 Xcode 项目中?

编辑根据建议,我尝试了这个:

  # Compile files:
  add_executable(fpv 
    main.cpp

    files.cpp
    files.hpp

    more-files.cpp
    more-files.hpp
 )

# Link files:
target_link_libraries(fpv
   fpv-lib
   ${GTKMM_LIBRARIES}  
   ${OpenCV_LIBS} )

# Lets bundle it:
set_target_properties(fpv PROPERTIES
  FRAMEWORK TRUE
  FRAMEWORK_VERSION C
  MACOSX_FRAMEWORK_IDENTIFIER com.cmake.dynamicFramework
  MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
  # "current version" in semantic format in Mach-O binary file
  VERSION 16.4.0
  # "compatibility version" in semantic format in Mach-O binary file
  SOVERSION 1.0.0
  # XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Jean-Michel Gonet"
)
Run Code Online (Sandbox Code Playgroud)

编辑为了确保 Info.plist 正确,我手动将其添加到 Xcode 项目中:

  • 添加 Info.plist 作为项目中的源。
  • 在项目导航器中选择它。
  • 将其重命名(!)为 Info.cpp,以便我可以将其包含在目标中。
  • 将其重命名回 Info.plist。
  • 启动了该应用程序,该应用程序请求我允许访问相机。

然后它就起作用了。

但我仍然希望在 CMake 中进行项目配置。

jmg*_*net 5

官方 Cmake 文档(请参阅cmake-properties-7 )提到了 2 个MACOSX目标属性系列:

  • FRAMEWORKFRAMEWORK_VERSIONMACOSX_FRAMEWORK_INFO_PLIST
  • MACOSX_BUNDLE_INFO_PLISTMACOSX_BUNDLE

现在,包含Info.plist由后者Bundle系列管理。

为了获得完整的示例,假设您的应用程序名为fpv,并且您的目录结构是:

/src   <-- Root folder
 /lib  <-- There you may add sources for your application's library
      CMakeLists.txt <-- Library has its own configuration
      more-files.cpp
      lots-of-files.cpp
      etc.cpp
      ...
 /app  <-- This is where executable resides
      CMakeLists.txt <-- This is where you need to configure the bundle
      Info.plist    <-- I've placed the plist file just besides.
      main.cpp
      second.cpp
      more.cpp
Run Code Online (Sandbox Code Playgroud)

您的应用程序CMakeLists.txt可能如下所示:

# src/app
project( fpv )

# GTKMM has to be linked/included via pkg_config:
find_package(PkgConfig)
pkg_check_modules(GTKMM gtkmm-3.0) # Defines variables GTKMM_INCLUDE_DIRS, GTKMM_LIBRARY_DIRS and GTKMM_LIBRARIES.
link_directories( ${GTKMM_LIBRARY_DIRS} )
include_directories( ${GTKMM_INCLUDE_DIRS} )

# OpenCV can be linked as usual:
find_package( OpenCV REQUIRED )

# Compile files:
add_executable(fpv 
    main.cpp

    main-window.cpp
    main-window.hpp

    auto-viseur.cpp
    auto-viseur.hpp
 )

# Link files:
target_link_libraries(fpv
   fpv-lib
   ${GTKMM_LIBRARIES}  
   ${OpenCV_LIBS} )

# Lets bundle it:
set_target_properties(fpv PROPERTIES
  MACOSX_BUNDLE TRUE
  MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
)
Run Code Online (Sandbox Code Playgroud)

要构建 XCode 项目,请xcode在主src文件夹之外创建一个文件夹:

mkdir xcode
cd xcode
cmake -G Xcode ../src
Run Code Online (Sandbox Code Playgroud)

现在您可以从Xcode将其作为项目打开。在调试模式下执行:

  • 选择应用程序的目标(左上角,默认设置为 ALL_BUILD)。您会注意到图标已更改为风格化的 A。
  • 运行。
  • 如果一切顺利,您应该被要求允许您的应用程序访问相机。
  • 另外,您应该将该Info.plist文件视为资源