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=]';
}

这暂时解决了我的问题,所以在找到更好的解决方案之前我会一直使用它。