I do cmake . && make all install
. This works, but installs to /usr/local
.
I need to install to a different prefix (for example, to /usr
).
What is the cmake
and make
command line to install to /usr
instead of /usr/local
?
CMakeLists.txt
so you can set it and forget it. I'm not saying there isn't a common use case for changing the install directory on the fly -- clearly there is judging by the number of votes -- I'm just fairly new to CMake and curious when this problem comes up.
make install
to a temporary path to make sure everything that needs to be installed, got installed to the right location without messing up my development machine. Just one example. Another case is cross-compiling for another architecture.
CMakeLists.txt
, then I need to patch the original source. Just having a command line option allows me to get the paths right in the Fedora spec
file.
CMakeLists.txt
file if you're just building and installing software - overriding/setting variables from command line or initial cache file, etc. is the preferred "consumer" way of setting options.
You can pass in any CMake variable on the command line, or edit cached variables using ccmake/cmake-gui. On the command line,
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr . && make all install
Would configure the project, build all targets and install to the /usr prefix. The type (PATH) is not strictly necessary, but would cause the Qt based cmake-gui to present the directory chooser dialog.
Some minor additions as comments make it clear that providing a simple equivalence is not enough for some. Best practice would be to use an external build directory, i.e. not the source directly. Also to use more generic CMake syntax abstracting the generator.
mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr .. && cmake --build . --target install --config Release
You can see it gets quite a bit longer, and isn't directly equivalent anymore, but is closer to best practices in a fairly concise form... The --config is only used by multi-configuration generators (i.e. MSVC), ignored by others.
The ":PATH" part in the accepted answer can be omitted. This syntax may be more memorable:
cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install
...as used in the answers here.
Note that in both CMake and Autotools you don't always have to set the installation path at configure time. You can use DESTDIR
at install time (see also here) instead as in:
make DESTDIR=<installhere> install
See also this question which explains the subtle difference between DESTDIR
and PREFIX
.
This is intended for staged installs and to allow for storing programs in a different location from where they are run e.g. /etc/alternatives
via symbolic links.
However, if your package is relocatable and doesn't need any hard-coded (prefix) paths set via the configure stage you may be able to skip it. So instead of:
cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install
you would run:
cmake . && make DESTDIR=/usr all install
Note that, as user7498341 points out, this is not appropriate for cases where you really should be using PREFIX
.
DESTDIR
. But actually this is wrong. You should refer to the cmake docs cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ... make DESTDIR=/home/john install
which will install the concerned software using the installation prefix, e.g. “/usr/local” prepended with the DESTDIR value which finally gives “/home/john/usr/local”.
cmake --build build --target install -- DESTDIR=/usr
note: this should also work with Ninja generator (rules seems to contains $ENV{DESTDIR}
)
The way I build CMake projects cross platform is the following:
/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
The first two lines create the out-of-source build directory
The third line generates the build system specifying where to put the installation result (which I always place in ./project-root/build/stage - the path is always considered relative to the current directory if it is not absolute)
The fourth line builds the project configured in . with the buildsystem configured in the line before. It will execute the install target which also builds all necessary dependent targets if they need to be built and then copies the files into the CMAKE_INSTALL_PREFIX (which in this case is ./project-root/build/stage. For multi-configuration builds, like in Visual Studio, you can also specify the configuration with the optional --config
The good part when using the cmake --build command is that it works for all generators (i.e. makefiles and Visual Studio) without needing different commands.
Afterwards I use the installed files to create packages or include them in other projects...
cmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
make -j $(nproc)
, to specify the number of build threads, do cmake --build . --target=install --config=Release -- -j 8
for Makefile generator or cmake --build . --target=install --config=Release -- /m:8
for Visual Studio generator with 8 threads. Actually, you can pass any commandline parameters after --
-j
is not a flag for cmake, all flags come after --
is passing to the underlying build system...
Starting with CMake 3.15, the correct way of achieving this would be using:
cmake --install <dir> --prefix "/usr"
Regarding Bruce Adams answer:
Your answer creates dangerous confusion. DESTDIR is intended for installs out of the root tree. It allows one to see what would be installed in the root tree if one did not specify DESTDIR. PREFIX is the base directory upon which the real installation is based.
For example, PREFIX=/usr/local indicates that the final destination of a package is /usr/local. Using DESTDIR=$HOME will install the files as if $HOME was the root (/). If, say DESTDIR, was /tmp/destdir, one could see what 'make install' would affect. In that spirit, DESTDIR should never affect the built objects.
A makefile segment to explain it:
install:
cp program $DESTDIR$PREFIX/bin/program
Programs must assume that PREFIX is the base directory of the final (i.e. production) directory. The possibility of symlinking a program installed in DESTDIR=/something only means that the program does not access files based upon PREFIX as it would simply not work. cat(1) is a program that (in its simplest form) can run from anywhere. Here is an example that won't:
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
If you tried to run prog from elsewhere than $PREFIX/bin/prog, prog.db would never be found as it is not in its expected location.
Finally, /etc/alternatives really does not work this way. There are symlinks to programs installed in the root tree (e.g. vi -> /usr/bin/nvi, vi -> /usr/bin/vim, etc.).
It is considered bad practice to invoke the actual build system (e.g. via the make
command) if using CMake. It is highly recommended to do it like this:
Configure + Generation stages: 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 Build and Install stages: cmake --build _builds/foo/debug --config Debug --target install
When following this approach, the generator can be easily switched (e.g. -G Ninja
for Ninja) without having to remember any generator-specific commands.
Note that the CMAKE_BUILD_TYPE
variable is only used by single-config generators and the --config
argument of the build command is only used by multi-config generators.
--config
argument?
-H
flag. The officially supported replacement is -S
CMAKE_BUILD_TYPE
established during configuration. The second class relies on --config
argument provided during building (and then also installing). This is because with multi-configuration generators, unsurprisingly, you can build many types out of single CMake configuration.
Starting with CMake 3.21 you can use the --install-prefix
option instead of manually setting CMAKE_INSTALL_PREFIX
.
The modern equivalent of configure --prefix=DIR && make all install
would now be:
cmake -S . -B build --install-prefix=DIR
cmake --build build
cmake --install build
Success story sharing
/usr .