[cmake] What is CMake equivalent of 'configure --prefix=DIR && make all install '?

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?

This question is related to cmake

The answer is


Starting with CMake 3.15, the correct way of achieving this would be using:

cmake --install <dir> --prefix "/usr"

Official Documentation


It is considered bad practice to invoke the actual generator (e.g. via make) if using CMake. It is highly recommended to do it like this:

  1. Configure phase:

    cmake -Hfoo -B_builds/foo/debug -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX=/usr
    
  2. Build and Install phases

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

When following this approach, the generator can be easily switched (e.g. -GNinja for Ninja) without having to remember any generator-specific commands.


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 <config> flag.
  • 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...


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.


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.


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.).