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


386

我做的cmake . && make all install。可以,但是安装到/usr/local

我需要安装到其他前缀(例如to /usr)。

安装到的cmakeand make命令行/usr/usr/local什么?


1
这是一个动态更改安装目录的好问题,但是为什么这显然是常见的需求?从我的角度来看,答案应该是不要使用命令行选项,而要编辑基础,CMakeLists.txt以便您可以设置它而忘记它。我并不是说没有即时更改安装目录的常见用例-显然是根据投票数来判断的-我对CMake还是很陌生,并且在出现此问题时感到好奇。
CivFan 2015年

8
@CivFan是为了迎合想要将项目构建并安装到特定位置但与项目的开发人员/维护人员不同的用户的。
DavidRöthlisberger'16

4
@CivFan因此,作为一名维护者,对我而言,将其测试make install到临时路径以确保需要安装的所有东西都安装到正确的位置而不会弄乱我的开发机器,这并不罕见。只是一个例子。另一种情况是针对另一体系结构进行交叉编译。
丹尼尔(Daniel)

5
@CivFan:我需要这个,因为我想构建一个RPM软件包。如果需要更改CMakeLists.txt,则需要修补原始源。仅使用命令行选项即可使我在Fedora spec文件中获得正确的路径。
Martin Ueding '16

1
@CivFan(和其他阅读此文章的人)仅供参考,CMakeLists.txt如果您只是在构建和安装软件,通常认为编辑文件是个坏主意-从命令行或初始缓存文件覆盖/设置变量等是首选的“消费者”设置选项的方式。
Ryan Pavlik

Answers:


444

您可以在命令行中传递任何CMake变量,也可以使用ccmake / cmake-gui编辑缓存的变量。在命令行上

cmake -DCMAKE_INSTALL_PREFIX:PATH = / usr。&&全部安装

将配置项目,构建所有目标并安装到/ usr前缀。类型(PATH)并非绝对必要,但是会导致基于Qt的cmake-gui出现目录选择器对话框。

一些小的补充说明清楚地表明,仅提供一些等效功能是不够的。最佳实践是使用外部构建目录,即不直接使用源目录。还可以使用更通用的CMake语法抽象生成器。

mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH = / usr .. && cmake --build。--target安装--config发布

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


21
想知道:PATH是什么?对于cmake-gui很有用,有助于选择该变量的小部件。参见linux.die.net/man/1/cmake-gui中的文档(设置部分)
albfan 2012年

2
如上所述,它们向CMake GUI提供了提示,CMake中的所有内容实际上都是字符串,但是设置PATH,FILEPATH,STRING,BOOL等有助于GUI显示更合适的小部件。
Marcus D. Hanwell

13
您还可以使用:“ cmake --build --target install。” 而不是make。
RobertJMaynard

2
/ usr之后的点是什么?/usr .
bodacydo

5
我们从中生成的带有CMakeLists.txt的文件夹的@bodacydo位置。
Kamiccolo 2014年


29

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

make DESTDIR=<installhere> install

也可以看看 见此问题该问题解释了DESTDIR和PREFIX之间的细微差别。

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

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

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

您将运行:

cmake . && make DESTDIR=/usr all install

请注意,正如user7498341指出的那样,这不适用于您确实应该使用PREFIX的情况。


9
我喜欢展示的使用DESTDIR。但是实际上这是错误的。您应该参考cmake docs cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ... make DESTDIR=/home/john install,它将使用安装前缀(例如,以DESTDIR值作为前缀的“ / usr / local”)安装相关软件最后给出“ / home / john / usr / local”。
Joakim

1
我认为这并不矛盾。如果您的程序包可重定位,则不需要CMAKE_INSTALL_PREFIX,或者可以选择其中一种方法。如果不是,您会这样做,因为CMAKE_INSTALL_PREFIX将在构建时烘焙到某个地方。
布鲁斯·亚当斯

如果您知道您的生成器是Makefile ...,我希望cmake --build build --target install -- DESTDIR=/usr注意:这也可以与Ninja生成器一起使用(规则似乎包含$ENV{DESTDIR}
Mizux

@Joakim就像我想使用CMAKE_INSTALL_PREFIX一样,将安装路径嵌入到已编译的文件中。碰巧的是,我只是构建一个.rpm包,所以不会这样做。DESTDIR就像将事物引入buildroot的一种魅力。
Redstoner先生

18

我跨平台构建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
  • 前两行创建源外构建目录
  • 第三行生成构建系统,指定将安装结果放置在何处(我一直将其放置在./project-root/build/stage-如果路径不是绝对路径,则始终将其视为相对于当前目录的路径)
  • 第四行.使用在前面的行中配置的构建系统来构建配置的项目。install如果需要构建所有必需的依赖目标,它将执行该目标,该目标还将构建所有必需的依赖目标,然后将文件复制到。CMAKE_INSTALL_PREFIX(在这种情况下为./project-root/build/stage。对于多配置构建,例如在Visual Studio中,也可以使用可选--config <config>标志。
  • 使用该cmake --build命令的好处在于,它适用于所有生成器(例如,makefile和Visual Studio),而无需使用其他命令。

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


感谢您的逐步说明!海事组织这是唯一的方法,否则将丢弃cmake(平台独立性)的整个观点……
helmesjo

1
您是否忘了在第3行中包含源(../)的路径?顺便说一句,这应该是公认的答案。
斯拉瓦

1
类别3应该为cmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
codenamezero

1
另外,实用上,人们使用make -j $(nproc)来指定cmake --build . --target=install --config=Release -- -j 8生成线程的数量,对Makefile生成器或cmake --build . --target=install --config=Release -- /m:8具有8个线程的Visual Studio生成器执行。实际上,您可以在--
Cloud

1
@MrRedstoner -j不是cmake的标志,所有标志都在--传递到基础的构建系统之后……
Cloud

4

关于布鲁斯·亚当斯(Bruce Adams)的答案:

您的答案会造成危险的混乱。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

程序必须假定PREFIX是最终(即生产)目录的基本目录。将DESTDIR = /某物中安装的程序进行符号链接的可能性仅表示该程序不访问基于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

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

最后,/ etc / alternatives确实无法通过这种方式工作。在根目录树中有指向安装的程序的符号链接(例如vi-> / usr / bin / nvi,vi-> / usr / bin / vim等)。



2

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

  1. 配置阶段:

    cmake -Hfoo -B_builds/foo/debug -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX=/usr
    
  2. 构建安装阶段

    cmake --build _builds/foo/debug --config Debug --target install
    

以下这种方法时,该发生器可以容易地切换(例如-GNinja用于),而不必记住任何发电机特有的命令。


1
如果对使用的所有参数及其使用原因进行解释,答案可能会更好。特别是,--config论点有什么意义?
德米特里·卡巴诺夫

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.