jmgonet
jmgonet

Reputation: 1261

How to have Info.plist bundled in a MacOSX application with CMake?

I'm developing an application accessing the camera. The project is written in C++ and I'm using CMake to package it.

To deploy the project in a Mac, I use the command below, and then open the project in Xcode:

cmake -G Xcode ../src

It worked fine until last update, when it started complaining about:

[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

So I created a new Info.plist file with the following content:

<?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>

My question is: What should I add in CMakeLists.txt to take this file and put it in the proper place? And... is it possible that cmake -G Xcode would include it correctly in the Xcode project?

EDIT Following recommendations, I tried this:

  # 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"
)

EDIT To be sure the Info.plist is correct I manually added it in the Xcode project:

And then it worked.

But I would still like to have project configuration in CMake.

Upvotes: 4

Views: 5143

Answers (1)

jmgonet
jmgonet

Reputation: 1261

Official Cmake's documentation (see cmake-properties-7) mentions 2 families of MACOSX target properties:

  • FRAMEWORK, FRAMEWORK_VERSION and MACOSX_FRAMEWORK_INFO_PLIST
  • MACOSX_BUNDLE_INFO_PLIST and MACOSX_BUNDLE

Now, the inclusion of Info.plist is managed by the latter Bundle family.

To have a complete example, let say your application is called fpv, and your directory structure is:

/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

This is how your application's CMakeLists.txt could look like:

# 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
)

To build the XCode project, create a xcode folder besides the main src folder:

mkdir xcode
cd xcode
cmake -G Xcode ../src

Now you can open it as a project from Xcode. To execute in debug mode:

  • Select your application's target (top left-ish side, by default it is set to ALL_BUILD). You'll notice that the icon has changed to a stylized A.
  • Run it.
  • If all went well, you should be requested to allow your application to access camera.
  • Also, you should see the Info.plist file as a resource

Upvotes: 5

Related Questions