Objective-C 项目的 CMakeLists.txt

bha*_*ley 8 xcode objective-c cmake

我正在使用 Objective-C 和 CMake 在 macOS 上简单地创建一个 hello world 可执行文件。据我了解,CMake 本身并不支持构建 Objective-C。您必须首先添加

\n
set(CMAKE_C_FLAGS "-x objective-c")\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
set(CMAKE_CXX_FLAGS "-x objective-c++")\n
Run Code Online (Sandbox Code Playgroud)\n

甚至可以创建 Makefile。我遇到困难的部分是如何适当地链接现有框架。我已遵循这篇文章中的说明以及它所基于的教程:无法将 MacOS 框架与 CMake 链接\n我还尝试将库链接到:

\n
set(CMAKE_EXE_LINKER_FLAGS "-framework fm1-framework fm2\xe2\x80\xa6")\n
Run Code Online (Sandbox Code Playgroud)\n

我现在可以成功获得 CMake 生成的 Xcode 项目,但是当我打开该项目时,我在 CMakeLists.txt 文件中指定的框架都不在 \'resources\' 文件夹中。使用此 Xcode 项目,我可以编译该项目,但是当我运行可执行文件时,出现错误:

\n
\n

“2014-01-06 18:02:35.859 HelloWorld[62641:303] 应用程序包中没有 Info.plist 文件或 Info.plist 文件中没有 NSPrincipalClass,正在退出
\n程序以退出代码结束:1”

\n
\n

我还尝试在终端中手动运行 CMake 生成的 makefile,并收到许多警告(在链接期间),所有警告都说:

\n
\n

CMakeFiles/HelloWorld.dir/AppDelegate.mo:3:2252: 警告: 空字符
\ignored [-Wnull-character]
\n...

\n
\n
\n

CMakeFiles/HelloWorld.dir/AppDelegate.mo:3:2263: 警告: 空字符
\ignored [-Wnull-character]
\n...

\n
\n

和 7 个错误(在链接期间):

\n
\n

CMakeFiles/HelloWorld.dir/AppDelegate.mo:1:1: 错误: 预期的不合格 ID\n<U+0007>

\n
\n
\n

CMakeFiles/HelloWorld.dir/AppDelegate.mo:3:90:错误:预期的不合格 ID\n...H<89>uH<89>U]fffff.<U+000F><U+001F><84>

\n
\n
\n

CMakeFiles/HelloWorld.dir/AppDelegate.mo:3:121: 错误: 无关的右大括号\n(\'}\')\n...}H<89>uH<8B>uH<8B>=

\n
\n
\n

CMakeFiles/HelloWorld.dir/AppDelegate.mo:3:122:错误:预期的不合格 ID\n...H<89>uH<8B>uH<8B>=

\n
\n
\n

CMakeFiles/HelloWorld.dir/AppDelegate.mo:3:169: 错误: 无关的右大括号\n(\'}\')\n...}H<89>uH<89>UH<8B>uH<8B> =

\n
\n
\n

CMakeFiles/HelloWorld.dir/AppDelegate.mo:3:170:错误:预期的不合格 ID\n...H<89>uH<89>UH<8B>uH<8B>=

\n
\n
\n

CMakeFiles/HelloWorld.dir/AppDelegate.mo:3:2246: 错误: 预期的不合格 ID\n...16@0:8

\n
\n

关于我做错了什么有什么想法吗?我花了一天的大部分时间寻找答案,我引用的帖子提供了最有用的信息,但它仍然没有解决我的问题。难道是因为原来的程序也是用Xcode写的?不知怎的,这搞乱了 CMake?

\n

这是我的 HelloWorld 应用程序的代码:

\n
#import <Cocoa/Cocoa.h>\n\nint main(int argc, const char * argv[])\n{\n    return NSApplicationMain(argc, argv);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

CMakeLists.txt 文件的代码:

\n
cmake_minimum_required(VERSION 2.8)\nproject(HelloWorld)\n\nset(src_files\n   AppDelegate.h\n   AppDelegate.m\n   main.m\n)\n\nset(CMAKE_C_FLAGS "-x objective-c")\nset(CMAKE_CXX_FLAGS "-x objective-c++")\nset(CMAKE_EXE_LINKER_FLAGS "-framework Cocoa -framework AppKit -framework CoreData -     framework Foundation")\n\nadd_executable(HelloWorld \n   ${src_files}\n)\n
Run Code Online (Sandbox Code Playgroud)\n

Bor*_*ein 5

Objective-C 的最小 CMake 项目

CMakeLists.txt从 CMake 3.16+ 开始,以下是Objective-C 项目的最低限度:

cmake_minimum_required(VERSION 3.16)
project(HelloWorld)

enable_language(OBJCXX)

add_executable(HelloWorld main.m)

target_link_libraries(HelloWorld
    "-framework Foundation"
)
Run Code Online (Sandbox Code Playgroud)

main.m

#import <Foundation/Foundation.h>

int main() {
    @autoreleasepool {
        NSLog(@"Hello, World!");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译、构建并运行:

mkdir build && cd build
cmake ..
cmake --build .
./HelloWorld
Run Code Online (Sandbox Code Playgroud)

输出:

2023-03-28 19:37:46.970 HelloWorld[10606:200462] Hello, World!
Run Code Online (Sandbox Code Playgroud)

混合 C++ 和 Objective-C++

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(HelloWorld)

set(CMAKE_CXX_STANDARD 17)
enable_language(OBJCXX)

add_executable(HelloWorld hello.mm main.cpp)

target_link_libraries(HelloWorld
    "-framework Foundation"
)
Run Code Online (Sandbox Code Playgroud)

main.cpp

#include "hello.h"

int main() {
    hello();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

hello.h

#ifndef HELLO_H
#define HELLO_H

void hello();

#endif
Run Code Online (Sandbox Code Playgroud)

hello.mm

#import "hello.h"
#import <Foundation/Foundation.h>

void hello() {
    @autoreleasepool {
        NSLog(@"Hello, World!");
    }
}
Run Code Online (Sandbox Code Playgroud)


bha*_*ley 4

间接感谢 ruslo 和位于此处的源代码: https: //github.com/forexample/cocoa-app我解决了问题。看来 CMake 要使用 Xcode 生成的 plist,必须使用上述存储库中 README.md 中指定的命令行指令。CMake 的 GUI 实现将无法工作,因为 GUI 无法解释 plist 文件。为了清楚起见,我将在这里列出它们:

cd 到包含 CMakeLists.txt 文件的目录。

cmake -H. -B_输出目录 -GXcode

cmake --build _OutputDirectory/

打开_OutputDirectory/HelloWorld.xcodeproj/

我遇到的另一个问题是我的 plist 和 MainWindow.xib 未包含在我的原始 CMake 文件中。添加 MainWindow.xib 和 HelloWorld-info.plist 必要的代码后,我能够生成一个可用的 Xcode 项目。这是供参考的代码:

cmake_minimum_required(VERSION 2.8)
project(HelloWorld)
set(NAME HelloWorld) 
set(CMAKE_C_FLAGS "-x objective-c")

set(HEADER_FILES 
    ./uhdplayerengine/HelloWorld/HelloWorld/AppDelegate.h
)
set(SOURCE_FILES 
    ./uhdplayerengine/HelloWorld/HelloWorld/AppDelegate.m
    ./uhdplayerengine/HelloWorld/HelloWorld/main.m
)
set(XIB_FILE
    ./uhdplayerengine/HelloWorld/HelloWorld/Base.lproj/MainMenu.xib
)

add_executable(
    ${NAME}
    MACOSX_BUNDLE
    ${HEADER_FILES}
    ${SOURCE_FILES}
    ${XIB_FILE}
)

set_source_files_properties(
    ${XIB_FILE}
    PROPERTIES
    MACOSX_PACKAGE_LOCATION
    Resources
)

set_target_properties(
    ${NAME}
    PROPERTIES
    MACOSX_BUNDLE_INFO_PLIST
    ./uhdplayerengine/HelloWorld/HelloWorld/HelloWorld-Info.plist
)

target_link_libraries(${NAME}
    "-framework Cocoa"
    "-framework AppKit"
    "-framework CoreData"
    "-framework Foundation"
)
Run Code Online (Sandbox Code Playgroud)

我希望这可以避免其他人的头痛!谢谢鲁斯洛!

  • 正如我之前提到的,没有必要添加此标志 `set(CMAKE_C_FLAGS "-x Objective-c")`。顺便说一句,这个变量可能不为空,所以如果你想**添加**一些标志,你需要使用命令:`set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -x Objective-c")` (2认同)