CMake CPack NSIS 如何将安装位置传递给项目?
CMake CPack NSIS How to pass install location to project?
我有一个用 C 编写的项目。目前它正在使用 UNIX makefile 为 Linux 编译自身,但最近我一直在研究 CMake,以使其更具可移植性。
可执行文件在 运行ning 时需要访问项目中的一些资产文件。使用 makefile 时,我将只编译项目:
make prefix=/usr
make prefix=/usr install
因此,在编译项目时,它知道它将在 /usr
中结束,而当 运行ning 时,它会在那里搜索自己的项目文件(在类似 /usr/share/my-project/
).
我创建了一个非常基本的 CMakeLists.txt
,它编译 .exe
文件,并将它与另一个资产文件一起安装在安装目录中。然后我 运行 以下命令为 Windows 创建一个 NSIS 安装程序:
cmake.exe --build --config Release .
cpack.exe
这成功地为我提供了 NSIS 安装程序。当运行时,它会向用户显示几个步骤,其中之一是决定项目的安装位置,用户可以修改。
所以我的问题是,此时项目已经编译,那么我如何将它自己的安装位置传递给我的项目,以便它可以访问项目中包含的文件?其他项目如何做到这一点?我在网上找不到太多关于它的信息,这让我觉得我可能采取了错误的方法。
对于遇到类似问题的任何人,我找到了一个解决方案。
网上看了一下,Unix系统好像不太推荐,编译时设置安装位置比较标准。
然而,对于 windows,我找到了函数 GetModuleFileNameW
(GetModuleFileNameW function (libloaderapi.h)).
它returns 当前可执行文件的路径(类似于C:\Program Files\<my-app>\bin\my-app.exe
)。我已经确认它 returns 是正确的路径,即使我将项目安装在不同的目录中也是如此。它 returns 使用 wchar_t
的结果,因此也支持 unicode 目录。
这是一个如何使用它的小例子:
// to keep the example simple, this is assuming maximum 1000 characters in the path
wchar_t dynamicProjectLocationW[1000];
GetModuleFileNameW(NULL, dynamicProjectLocationW, 999);
dynamicProjectLocationW[999] = L'[=10=]';
// given a path like "C:\X\Y\bin\myapp.exe" find the second to last slash
// so we can get the path "C:\X\Y\"
wchar_t *pointer = dynamicProjectLocationW;
wchar_t *secondToLastSlash = 0;
wchar_t *lastSlash = 0;
while (pointer[0] != L'[=10=]') {
if (pointer[0] == L'\') {
secondToLastSlash = lastSlash;
lastSlash = pointer;
}
pointer++;
}
// cut the path short, so we can use the project path to find other files
if (secondToLastSlash) {
secondToLastSlash++;
secondToLastSlash[0] = L'[=10=]';
}
这暂时解决了我的问题,所以在找到更好的解决方案之前我会一直使用它。
我有一个用 C 编写的项目。目前它正在使用 UNIX makefile 为 Linux 编译自身,但最近我一直在研究 CMake,以使其更具可移植性。
可执行文件在 运行ning 时需要访问项目中的一些资产文件。使用 makefile 时,我将只编译项目:
make prefix=/usr
make prefix=/usr install
因此,在编译项目时,它知道它将在 /usr
中结束,而当 运行ning 时,它会在那里搜索自己的项目文件(在类似 /usr/share/my-project/
).
我创建了一个非常基本的 CMakeLists.txt
,它编译 .exe
文件,并将它与另一个资产文件一起安装在安装目录中。然后我 运行 以下命令为 Windows 创建一个 NSIS 安装程序:
cmake.exe --build --config Release .
cpack.exe
这成功地为我提供了 NSIS 安装程序。当运行时,它会向用户显示几个步骤,其中之一是决定项目的安装位置,用户可以修改。
所以我的问题是,此时项目已经编译,那么我如何将它自己的安装位置传递给我的项目,以便它可以访问项目中包含的文件?其他项目如何做到这一点?我在网上找不到太多关于它的信息,这让我觉得我可能采取了错误的方法。
对于遇到类似问题的任何人,我找到了一个解决方案。
网上看了一下,Unix系统好像不太推荐,编译时设置安装位置比较标准。
然而,对于 windows,我找到了函数 GetModuleFileNameW
(GetModuleFileNameW function (libloaderapi.h)).
它returns 当前可执行文件的路径(类似于C:\Program Files\<my-app>\bin\my-app.exe
)。我已经确认它 returns 是正确的路径,即使我将项目安装在不同的目录中也是如此。它 returns 使用 wchar_t
的结果,因此也支持 unicode 目录。
这是一个如何使用它的小例子:
// to keep the example simple, this is assuming maximum 1000 characters in the path
wchar_t dynamicProjectLocationW[1000];
GetModuleFileNameW(NULL, dynamicProjectLocationW, 999);
dynamicProjectLocationW[999] = L'[=10=]';
// given a path like "C:\X\Y\bin\myapp.exe" find the second to last slash
// so we can get the path "C:\X\Y\"
wchar_t *pointer = dynamicProjectLocationW;
wchar_t *secondToLastSlash = 0;
wchar_t *lastSlash = 0;
while (pointer[0] != L'[=10=]') {
if (pointer[0] == L'\') {
secondToLastSlash = lastSlash;
lastSlash = pointer;
}
pointer++;
}
// cut the path short, so we can use the project path to find other files
if (secondToLastSlash) {
secondToLastSlash++;
secondToLastSlash[0] = L'[=10=]';
}
这暂时解决了我的问题,所以在找到更好的解决方案之前我会一直使用它。