macOS制作C/C++ app
C/C++制作macOS .app
一、 .app
APP其实是一个文件夹结构,只不过mac的界面中让它看起来像一个单独的文件。
在shell终端或者右键查看包结构即可看到APP的目录结构。
通常的app目录结构如下:
_CodeSignature
,CodeResources
- 一般为Mac APP Store上架程序所包含。里面含有数字签名,以防非法篡改。
Frameworks
- 一般放置了此程序所使用的第三方FrameWork。
Info.plist
- 包含了一个程序的基本信息,如最低系统版本要求、版本号,copyright。
- 也可能包含程序的类型信息,比如这个文件如果有LSUIElement字段并且值为TRUE,则这个程序启动后不会在Dock上显示图标或图标下有表示此程序正在运行的小亮点。
MacOS
文件夹- 包含了此应用程序真正的可执行文件。一个程序可能包含不只一个可执行文件。
Resources
- 资源文件,图标,语言包等其他文件,这个没有严格的限制。
参考博客:https://blog.51cto.com/maxma/5708529
二、 实例分析
例如WPS,可以观察到,wps中有一个SharedSupport
目录,还包含多个.app:
QQ也是,不过.app在别的路径:
ToDesk.app的Info.plist,可以看到里面还包含摄像头、麦克风权限的获取:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict><key>Application is agent(UI Element)</key><false/><key>BuildMachineOSBuild</key><string>22A380</string><key>CFBundleDevelopmentRegion</key><string>en</string><key>CFBundleDisplayName</key><string>ToDesk</string><key>CFBundleExecutable</key><string>ToDesk</string><key>CFBundleIconFile</key><string>ToDesk</string><key>CFBundleIconName</key><string>ToDesk</string><key>CFBundleIdentifier</key><string>com.youqu.todesk.mac</string><key>CFBundleInfoDictionaryVersion</key><string>6.0</string><key>CFBundleName</key><string>ToDesk</string><key>CFBundlePackageType</key><string>APPL</string><key>CFBundleShortVersionString</key><string>4.7.2.1</string><key>CFBundleSupportedPlatforms</key><array><string>MacOSX</string></array><key>CFBundleURLTypes</key><array><dict><key>CFBundleTypeRole</key><string>Editor</string><key>CFBundleURLName</key><string>toc</string><key>CFBundleURLSchemes</key><array><string>todesk</string></array></dict></array><key>CFBundleVersion</key><string>921</string><key>DTCompiler</key><string>com.apple.compilers.llvm.clang.1_0</string><key>DTPlatformBuild</key><string>14B47b</string><key>DTPlatformName</key><string>macosx</string><key>DTPlatformVersion</key><string>13.0</string><key>DTSDKBuild</key><string>22A372</string><key>DTSDKName</key><string>macosx13.0</string><key>DTXcode</key><string>1410</string><key>DTXcodeBuild</key><string>14B47b</string><key>ITSAppUsesNonExemptEncryption</key><false/><key>LSApplicationCategoryType</key><string>public.app-category.utilities</string><key>LSMinimumSystemVersion</key><string>10.11</string><key>NSAppTransportSecurity</key><dict><key>NSAllowsArbitraryLoads</key><true/></dict><key>NSCameraUsageDescription</key><string>是否允许访问摄像头?</string><key>NSMainNibFile</key><string>MainMenu</string><key>NSMainStoryboardFile</key><string>MainMenu</string><key>NSMicrophoneUsageDescription</key><string>是否允许访问麦克风?</string><key>NSPrincipalClass</key><string>NSApplication</string><key>NSRequiresAquaSystemAppearance</key><string>true</string><key>SUAllowsAutomaticUpdates</key><false/><key>SUAutomaticallyUpdate</key><false/><key>SUEnableInstallerLauncherService</key><true/><key>SUEnableSystemProfiling</key><true/><key>SUFeedURL</key><string>http://dl.todesk.com/macos/sparkletestcast.xml</string><key>SUPublicEDKey</key><string>pz7QOaRHU3QI0Nq7IElJPP8WFl52KAFfRNz1D+j1McA=</string>
</dict>
</plist>
三、 用cmake 构建 .app
下载demo示例
以构建具有两个可执行程序的.app为例:
1. 目录结构
其中MacOSXBundleInfo.plist.in
是cmake安装目录下自带的Info.plist
模板(例如通过homebrew安装的路径是/opt/homebrew/share/cmake/Modules/MacOSXBundleInfo.plist.in
)
cmake中
.in
文件一般是模板文件,在执行cmake时,会用CMakeLists.txt
中的变量替换模板中的变量。
yq@yqdeMac:~/desktop/ipc$ ls -l
total 72
-rw-r--r--@ 1 yq staff 986 4 8 19:10 CMakeLists.txt
-rw-r--r-- 1 yq staff 1214 4 8 15:51 MacOSXBundleInfo.plist.in
-rw-r--r--@ 1 yq staff 27 4 8 17:56 ReaderWindow.cpp
-rw-r--r--@ 1 yq staff 1061 4 8 20:09 ReaderWindow.hpp
-rw-r--r--@ 1 yq staff 27 4 8 17:55 WriterWindow.cpp
-rw-r--r--@ 1 yq staff 1331 4 8 19:08 WriterWindow.hpp
-rw-r--r--@ 1 yq staff 48 4 8 18:01 config.hpp
-rw-r--r--@ 1 yq staff 172 4 8 19:10 reader.cpp
-rw-r--r--@ 1 yq staff 821 4 8 19:50 writer.cpp
2. CMakeLists.txt:
cmake_minimum_required(VERSION 3.20)
project(TestIPC)set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)set(CMAKE_PREFIX_PATH "/Library/Qt/5.15.4_macos_arm64")
find_package(Qt5 REQUIRED COMPONENTS Widgets)##### Write端
##添加writer构建目标,同时作为app的主程序
add_executable(${PROJECT_NAME} MACOSX_BUNDLE writer.cpp WriterWindow.cpp)##填写.app的信息
set(MACOSX_BUNDLE_ICON_FILE MyIcon.icns)
set(MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/MacOSXBundleInfo.plist.in)
set_target_properties(${PROJECT_NAME} PROPERTIESMACOSX_BUNDLE_INFO_PLIST ${MACOSX_BUNDLE_INFO_PLIST}MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}MACOSX_BUNDLE_BUNDLE_VERSION "5.20"MACOSX_BUNDLE_SHORT_VERSION_STRING "VersionString"MACOSX_BUNDLE_GUI_IDENTIFIER "com.yangqing.Test"XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES
)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Widgets)## 链接Qt#### Read端
set(EXE2 reader)
add_executable(${EXE2} reader.cpp ReaderWindow.cpp)## 添加reader构建目标
target_link_libraries(${EXE2} PRIVATE Qt::Widgets)## 链接Qt##修改生成路径
#set_target_properties(${EXE2} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PROJECT_NAME}.app/Contents/MacOS")
3. 构建
$ mkdir build && cd build
$ cmake ../
$ cmake --build .
生成了TestIPC
以及一个可执行文件reader
。
若要将reader
也加入到TestIPC
,可以额外编写脚本。
或者,在CMakeLists.txt一并完成:
set_target_properties(${EXE2} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PROJECT_NAME}.app/Contents/MacOS")
四、将app制作成dmg
-
在启动器选择“磁盘工具”;
-
顶部栏选择新建映像–>空白映像
3.命名后点存储
4.右键打开TestIPC,把app拖进去,Applications的软链接也拖进去
-
推出
-
在磁盘工具顶部选择"映像"–>“转换”
即可得到制作后的dmg,还可以更换背景图片等。
相关文章:

macOS制作C/C++ app
C/C制作macOS .app 一、 .app APP其实是一个文件夹结构,只不过mac的界面中让它看起来像一个单独的文件。 在shell终端或者右键查看包结构即可看到APP的目录结构。 通常的app目录结构如下: _CodeSignature, CodeResources 一般为Mac APP Store上架程序…...
学习笔记——C语言基本概念链表——(12)
在介绍链表之前先介绍一下数据结构的分类: 线性结构:数组,链表,栈,队列 顺序结构:数组 链式结构:链表 非线性结构:树,二叉树 1、链表 特点:利用碎片化空…...
开发环境解决跨域问题
跨域 为什么? 浏览器的同源策略(协议,域名,端口必须相等) http://localhost:9528/ (前端页面) ---------------------》后端接口(https://heimahr.itheima.net/api) 后端没有开启CORS 在后端没有开启CO…...

物理服务器与云服务器的租用对比
物理服务器:每个基于 Web 的应用程序都依赖于一个服务器,该服务器提供网络中的数据存储,并可根据请求提供给客户端。例如,用户使用浏览器访问 Web 应用程序。服务器可确保托管客户端可以使用该硬件组件。与其他托管可能性相比&…...
Ubuntu Desktop Server - Resource temporarily unavailable
Ubuntu Desktop Server - Resource temporarily unavailable 1. 问题2. 解决方案References 1. 问题 foreverstrongubuntu:~$ sudo apt-get install libatlas-base-dev [sudo] password for foreverstrong: E: Could not get lock /var/lib/dpkg/lock - open (11: Resource t…...

用Wireshark工具对gRPC接口进行本地抓包
前言: 本人一名敲代码的程序员,突然领导安排研究gRPC接口,并且抓包分析, 抓包工具试了Charles、mitmproxy都不行,浪费很多时间,最后使用Wireshark工具对本地启动的gRPC接口成功抓包,关于安装W…...

科技动态人工智能应用太空探索生物科技
根据最新的科技资讯,以下是一些值得关注的科技动态: 人工智能领域 智能体热潮 :随着大模型的研发热潮,AI智能体的发展迅速,它们被用作认知核心,具备强大的学习和迁移能力。智能体的架构和交互方式也在不断进…...

如何让MacOS「终端」走代理
在 MacOS 操作系统中,默认情况下,终端命令行不会通过代理进行网络连接。这导致在应用软件研发过程中,许多需要通过命令行下载安装的软件或依赖包无法成功安装。经常出现Failed to connect to xxx port 443 after 75329 ms: Couldnt connect t…...

数码相框-显示JPG图片
LCD控制器会将LCD上的屏幕数据映射在相应的显存位置上。 通过libjpeg把jpg图片解压出来RGB原始数据。 libjpeg是使用c语言实现的读写jpeg文件的库。 使用libjpeg的应用程序是以"scanline"为单位进行图像处理的。 libjpeg解压图片的步骤: libjpeg的使…...
PHP自带的密码加密函数Password_verify 和password_hash
Password_verify 和password_hash 这两个函数都是PHP自带的密码加密函数,通过底层实现,无法查看源代码 password_hash函数用于对用户输入的密码进行加密 Password_verify验证用户输入的密码是否正确 Tips:看到密码验证用的Password_verify&a…...
UVA1596 Bug Hunt 找Bug 解题报告
题目链接 https://vjudge.net/problem/UVA-1596 题目大意 输入并模拟执行一段程序,输出第一个bug所在的行。每行程序有两种可能: 数组定义,格式为arr[size]。例如a[10]或者b[5],可用下标分别是0~9和0~4…...
Java编程题 | 提取整数的特定位数
大家可以关注一下专栏,方便大家需要的时候直接查找,专栏将持续更新~ 题目描述 编写一个Java程序,用于接收一个整数作为输入,然后从该整数的右端开始提取第4到第7位数字。 程序需要接收一个整数作为输入,然后输…...

设置你的第一个React应用
目录 一、React入门 1.1 你好React 1.2 创建React 1.3 应用结构 二、总结 2.1 定义组件 2.2 组件源码 三、组件详解 注意事项 3.1 组件三部曲 3.2 组件通信 —— props 3.3 对象数组迭代 —— map() 3.4 事件处理 3.5 钩子函数 —— useState() 初次学习最终效果…...

【黑马头条】-day07APP端文章搜索-ES-mongoDB
文章目录 今日内容1 搭建es环境1.1 拉取es镜像1.2 创建容器1.3 配置中文分词器ik1.4 测试 2 app文章搜索2.1 需求说明2.2 思路分析2.3 创建索引和映射2.3.1 PUT请求添加映射2.3.2 其他操作 2.4 初始化索引库数据2.4.1 导入es-init2.4.2 es-init配置2.4.3 导入数据2.4.4 查询已导…...

SSL数字证书
SSL数字证书产品提供商主要来自于国外,尤其是美国,原理和使用操作系统一样,区别在于SSL数字证书目前无法替代性,要想达到兼容性99%的机构目前全球才3-4家,目前国内的主流网站主要使用的是国际证书,除了考虑…...

番茄 abogus rpc调用
声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!wx a15018601872 本文章…...
CSS设置元素的宽高比
aspect-ratio 是一个CSS属性,它允许你指定一个元素的期望宽高比。当元素的宽度变化时,其高度会自动调整以保持指定的宽高比。这个属性非常有用,特别是当你想要确保某个元素(如视频或图像容器)始终保持特定的宽高比时。…...

jenkins+docker实现可持续自动化部署springboot项目
目录 一、前言 二、微服务带来的挑战 2.1 微服务有哪些问题 2.2 微服务给运维带来的挑战 三、可持续集成与交付概述 3.1 可持续集成与交付概念 3.1.1 持续集成 3.1.2 持续交付 3.1.3 可持续集成与交付核心理念 3.2 可持续集成优点 3.3 微服务为什么需要可持续集成 四…...

【LAMMPS学习】八、基本知识的讨论(1.8)键的断裂
8. 基本知识的讨论 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语,以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和…...

GPT提示词分享 —— 中医
👉 中医诊断涉及因素较多,治疗方案仅供参考,具体的方子需由医生提供。AI建议不能替代专业医疗意见,如果症状严重或持续,建议咨询专业医生。 我希望你能扮演一位既是老中医同时又是一个营养学专家,我讲描述…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...