什么是CMake相当于'configure --prefix = DIR && make all install'?

And*_*rei 362 cmake

我知道cmake . && make all install.这有效,但安装到/usr/local.

我需要安装到不同的前缀(例如,to /usr).

什么是cmakemake命令行安装,以/usr代替/usr/local

Mar*_*ell 415

您可以在命令行上传入任何CMake变量,或使用ccmake/cmake-gui编辑缓存变量.在命令行上,

cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr . && make all install

将配置项目,构建所有目标并安装到/ usr前缀.类型(PATH)不是严格必需的,但会导致基于Qt的cmake-gui显示目录选择器对话框.

作为评论的一些小的补充清楚地表明,提供简单的等价对某些人来说是不够的.最佳做法是使用外部构建目录,即不直接使用源代码.还要使用更通用的CMake语法来抽象生成器.

mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr .. && cmake --build . --target install --config Release

您可以看到它变得相当长,并且不再直接等效,但是以相当简洁的形式更接近最佳实践...... --config仅由多配置生成器(即MSVC)使用,被忽略由他人.

  • 想知道:PATH是什么?它对cmake-gui很有用,有助于为该变量选择小部件.请参阅http://linux.die.net/man/1/cmake-gui中的文档(设置部分) (19认同)
  • 您还可以使用:"cmake --build --target install".而不是制造. (12认同)
  • @bodacydo我们正在生成的CMakeLists.txt文件夹的位置. (5认同)
  • 它们如上所述为CMake GUI提供提示,CMake中的所有内容实际上都是字符串,但设置PATH,FILEPATH,STRING,BOOL等可帮助GUI呈现更合适的小部件. (2认同)
  • / usr之后的点是什么?`/ usr .` (2认同)

use*_*370 39

可以省略接受的答案中的":PATH"部分.这种语法可能更令人难忘:

cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install
Run Code Online (Sandbox Code Playgroud)

...在这里的答案中使用.

  • [`:PATH`不是错误(http://stackoverflow.com/questions/6003374/what-is-cmake-equivalent-of-configure-prefix-dir-make-all-install#comment17772293_6003937). (7认同)

Bru*_*ams 25

请注意,在CMake和Autotools中,您不必总是在配置时设置安装路径.您可以在安装时使用DESTDIR(另请参见此处),如下所示:

make DESTDIR=<installhere> install
Run Code Online (Sandbox Code Playgroud)

另请参阅此问题,该问题解释了DESTDIR和PREFIX之间的细微差别.

这适用于分阶段安装,并允许将程序存储在与其运行位置不同的位置,例如/etc/alternatives通过符号链接.

但是,如果您的程序包是可重定位的,并且不需要通过configure阶段设置的任何硬编码(前缀)路径,可以跳过它.所以代替:

cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install
Run Code Online (Sandbox Code Playgroud)

你会运行:

cmake . && make DESTDIR=/usr all install
Run Code Online (Sandbox Code Playgroud)

请注意,正如user7498341指出的那样,这不适合您真正应该使用PREFIX的情况.

  • 我喜欢展示`DESTDIR`的用法.但实际上这是错误的.您应该参考cmake docs https://cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ...`make DESTDIR =/home/john install`,它将使用安装安装相关软件前缀,例如"/ usr/local"前面加上DESTDIR值,最后给出"/ home/john/usr/local". (8认同)
  • 我认为这并不矛盾。如果您的包可重定位,则不需要 CMAKE_INSTALL_PREFIX,或者您可以选择任一方法。如果不是你做,因为 CMAKE_INSTALL_PREFIX 将在构建时的某个地方烘焙。 (2认同)

小智 16

我跨平台构建CMake项目的方式如下:

/project-root> mkdir build
/project-root> cd build
/project-root/build> cmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
/project-root/build> cmake --build . --target=install --config=Release
Run Code Online (Sandbox Code Playgroud)
  • 前两行创建了源外构建目录
  • 第三行生成构建系统,指定安装结果的放置位置(我总是放在其中./project-root/build/stage- 如果路径不是绝对的,则路径始终被认为是相对于当前目录的)
  • 第四行.使用之前配置的构建系统构建配置的项目.它将执行install目标,如果需要构建它们,还构建所有必需的依赖目标,然后将文件复制到CMAKE_INSTALL_PREFIX(在这种情况下是./project-root/build/stage.对于多配置构建,如在Visual Studio中,您还可以指定配置可选--config <config>标志.
  • 使用该cmake --build命令的好处是它适用于所有生成器(即makefile和Visual Studio),而不需要不同的命令.

之后我使用已安装的文件来创建包或将它们包含在其他项目中......


Tac*_*chi 13

从 CMake 3.21开始,您可以使用该--install-prefix选项而不是手动设置CMAKE_INSTALL_PREFIX

现在的现代等价物configure --prefix=DIR && make all install是:

cmake -B build --install-prefix=DIR
cmake --build build
cmake --install build
Run Code Online (Sandbox Code Playgroud)


小智 8

从 CMake 3.15 开始,实现这一目标的正确方法是使用:

cmake --install <dir> --prefix "/usr"
Run Code Online (Sandbox Code Playgroud)

官方文档

  • “支持”并不意味着“正确”——这有其用途,但由于构建和安装比生成构建系统更频繁,因此在生成构建系统时设置环境变量通常更安全。根据用例,两者都是“正确的”。 (2认同)

Flo*_*ers 6

make如果使用 CMake,则调用实际构建系统(例如通过命令)被认为是不好的做法。强烈建议这样做:

  1. 配置+生成阶段:

     cmake -S foo -B _builds/foo/debug -G "Unix Makefiles" -D CMAKE_BUILD_TYPE:STRING=Debug -D CMAKE_DEBUG_POSTFIX:STRING=d -D CMAKE_INSTALL_PREFIX:PATH=/usr
    
    Run Code Online (Sandbox Code Playgroud)
  2. 构建安装阶段:

     cmake --build _builds/foo/debug --config Debug --target install
    
    Run Code Online (Sandbox Code Playgroud)

当遵循这种方法时,可以轻松切换生成器(例如,-G Ninja对于 Ninja),而无需记住任何特定于生成器的命令。

请注意,该CMAKE_BUILD_TYPE变量仅由单配置生成器使用,--config构建命令的参数仅由多配置生成器使用。

  • 如果对所有使用的参数以及使用它们的原因进行解释,答案可能会更好。特别是,“--config”参数的意义是什么? (4认同)
  • 不要使用未记录的“-H”标志。官方支持的替换是`-S` (2认同)

小智 5

关于布鲁斯·亚当斯的回答:

你的回答会造成危险的混乱。DESTDIR 用于安装在根树之外。如果没有指定 DESTDIR,它允许人们查看将安装在根树中的内容。PREFIX 是实际安装所基于的基本目录。

例如,PREFIX=/usr/local 表示包的最终目的地是 /usr/local。使用 DESTDIR=$HOME 将安装文件,就好像 $HOME 是根 (/) 一样。如果 DESTDIR 是 /tmp/destdir,则可以看到“make install”会产生什么影响。本着这种精神,DESTDIR永远不应该影响构建的对象。

一个makefile段来解释它:

install:
    cp program $DESTDIR$PREFIX/bin/program
Run Code Online (Sandbox Code Playgroud)

程序必须假定 PREFIX 是最终(即生产)目录的基本目录。对安装在 DESTDIR=/something 中的程序进行符号链接的可能性仅意味着该程序不会访问基于 PREFIX 的文件,因为它根本不起作用。cat(1) 是一个(以最简单的形式)可以从任何地方运行的程序。这是一个不会的例子:

prog.pseudo.in:
    open("@prefix@/share/prog.db")
    ...

prog:
    sed -e "s/@prefix@/$PREFIX/" prog.pseudo.in > prog.pseudo
    compile prog.pseudo

install:
    cp prog $DESTDIR$PREFIX/bin/prog
    cp prog.db $DESTDIR$PREFIX/share/prog.db
Run Code Online (Sandbox Code Playgroud)

如果您尝试从 $PREFIX/bin/prog 之外的其他位置运行 prog,则永远不会找到 prog.db,因为它不在预期位置。

最后, /etc/alternatives 确实不能以这种方式工作。安装在根树中的程序有符号链接(例如 vi -> /usr/bin/nvi、vi -> /usr/bin/vim 等)。

  • 这个答案可能更适合作为 http://stackoverflow.com/questions/11307465/destdir-and-prefix-of-make 的答案 (2认同)