为了使 GTK 程序在他人的 Windows 系统上运行,需要将该程序进行打包发布。
打包程序的关键只有两步,一,将执行程序需要和动态链接库放置在同一目录;二,设置程序可以直接点击运行,不会同时启用控制台窗口。
1. 放置动态链接库
1)准备工作,新建文件夹用来放置配置文件、执行程序及动态链接库。
2)使用 Listdlls.exe (微软网站下载)查看程序所依赖的动态链接库。具体做法为:在一个控制台下启动 04.config_themes.c.exe 文件,而后新增一个控制台,在 Listdll.exe 目录下输入如下代码。此时便可在控制台看到 04.config_themes.c.exe 对应的动态链接库(图中为部分动态链接库)。
.\Listdlls.exe 04.config_themes.c.exe
3)将除 /WINDOWS/SYSTEM32 外的动态链接库全部复制到 bin 目录下。可以手动复制,也可写一个脚本进行复制(此处利用了老师写的脚本)。脚本内容如下,大致逻辑是获取 .\Listdlls.exe 04.config_themes.c.exe 的执行结果,将其中带有 mingw 的动态链接库的文件名全部获取,而后将链接库从源目录逐一复制到 bin 目录下。
import os
import re
import shutil
import subprocess
import sys
if len(sys.argv) < 2:
print("Input app name.")
exit(1)
lines = subprocess.check_output(["Listdlls.exe", sys.argv[1]]).decode(encoding="utf-8").split("\r\n")
output_path = None
collecting = False
mingw_dlls = []
for line in lines:
if collecting and "mingw" in line:
mingw_dlls.append(re.split(r"\s+", line)[2])
if line.startswith("Command line: "):
output_path = line[14:].strip('"')
output_path = os.path.dirname(output_path)
if line.startswith("Base Size Path"):
collecting = True
print(output_path)
print(mingw_dlls)
for dll_file in mingw_dlls:
dll_filename = os.path.basename(dll_file)
dest_file = f"{output_path}{os.sep}{dll_filename}"
if os.path.exists(dest_file):
print(f"Skip: {dest_file}")
else:
print(shutil.copy(dll_file, dest_file))
使用 python 脚本的命令为:
.\collect_dlls.py 04.config_themes.c.exe
2. Release
点击 .exe 后程序直接执行而不会同时启用控制台窗口,共分为两步:
1)修改 CMakeLists.txt 文件,使编译器得知程序不需要命令行窗口。由于命令行窗口消失后,程序内的控制台打印相关代码(printf 等)会全部失效,故修改为程序在 debug 时控制台不会失效,在 release 时控制台失效。在 CMakeLists.txt 文件中新增如下代码:
set(CMAKE_C_FLAGS_RELEASE -mwindows)
2)新建 Release 编译选项,便于程序执行时控制台失效。
验证结果,前往 bin 目录,直接点击 04.config_themes.c.exe,可以发现程序成功执行,且无控制台。