cmake: add '--install <dir>' option

Fixes: #19023
This commit is contained in:
Jiang Yi 2019-03-06 20:49:51 +08:00
parent 7358f317e3
commit 73f23d1e00
12 changed files with 204 additions and 3 deletions

View File

@ -96,7 +96,7 @@ _cmake()
_filedir
return
;;
--build|--open)
--build|--install|--open)
_filedir -d
return
;;

View File

@ -16,6 +16,9 @@ Synopsis
`Build a Project`_
cmake --build <dir> [<options>] [-- <build-tool-options>]
`Install a Project`_
cmake --install <dir> [<options>]
`Open a Project`_
cmake --open <dir>
@ -39,8 +42,8 @@ buildsystem generator CMake. The above `Synopsis`_ lists various actions
the tool can perform as described in sections below.
To build a software project with CMake, `Generate a Project Buildsystem`_.
Optionally use **cmake** to `Build a Project`_ or just run the
corresponding build tool (e.g. ``make``) directly. **cmake** can also
Optionally use **cmake** to `Build a Project`_, `Install a Project`_ or just
run the corresponding build tool (e.g. ``make``) directly. **cmake** can also
be used to `View Help`_.
The other actions are meant for use by software developers writing
@ -302,6 +305,41 @@ following options:
Run ``cmake --build`` with no options for quick help.
Install a Project
=================
CMake provides a command-line signature to install an already-generated
project binary tree:
.. code-block:: shell
cmake --install <dir> [<options>]
This may be used after building a project to run installation without
using the generated build system or the native build tool.
The options are:
``--install <dir>``
Project binary directory to install. This is required and must be first.
``--config <cfg>``
For multi-configuration tools, choose configuration ``<cfg>``.
``--component <comp>``
Component-based install. Only install component ``<comp>``.
``--prefix <prefix>``
The installation prefix CMAKE_INSTALL_PREFIX.
``--strip``
Strip before installing by setting CMAKE_INSTALL_DO_STRIP.
``-v, --verbose``
Enable verbose output.
This option can be omitted if :envvar:`VERBOSE` environment variable is set.
Run ``cmake --install`` with no options for quick help.
Open a Project
==============

View File

@ -0,0 +1,6 @@
cmake--install-option
---------------------
* A new ``--install`` option was added to :manual:`cmake(1)`.
This may be used after building a project to run installation without
using the generated build system or the native build tool.

View File

@ -23,6 +23,7 @@
# include "cmsys/ConsoleBuf.hxx"
#endif
#include <cassert>
#include <ctype.h>
#include <iostream>
#include <string.h>
@ -71,11 +72,20 @@ static const char* cmDocumentationUsageNote[][2] = {
" the build commands to be executed. \n" \
" -- = Pass remaining options to the native tool.\n"
# define CMAKE_INSTALL_OPTIONS \
" <dir> = Project binary directory to install.\n" \
" --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \
" --component <comp> = Component-based install. Only install <comp>.\n" \
" --prefix <prefix> = The installation prefix CMAKE_INSTALL_PREFIX.\n" \
" --strip = Performing install/strip.\n" \
" -v --verbose = Enable verbose output.\n"
static const char* cmDocumentationOptions[][2] = {
CMAKE_STANDARD_OPTIONS_TABLE,
{ "-E", "CMake command mode." },
{ "-L[A][H]", "List non-advanced cached variables." },
{ "--build <dir>", "Build a CMake-generated project binary tree." },
{ "--install <dir>", "Install a CMake-generated project binary tree." },
{ "--open <dir>", "Open generated project in the associated application." },
{ "-N", "View mode only." },
{ "-P <file>", "Process script mode." },
@ -114,6 +124,7 @@ static int do_command(int ac, char const* const* av)
int do_cmake(int ac, char const* const* av);
static int do_build(int ac, char const* const* av);
static int do_install(int ac, char const* const* av);
static int do_open(int ac, char const* const* av);
static cmMakefile* cmakemainGetMakefile(cmake* cm)
@ -188,6 +199,9 @@ int main(int ac, char const* const* av)
if (strcmp(av[1], "--build") == 0) {
return do_build(ac, av);
}
if (strcmp(av[1], "--install") == 0) {
return do_install(ac, av);
}
if (strcmp(av[1], "--open") == 0) {
return do_open(ac, av);
}
@ -523,6 +537,117 @@ static int do_build(int ac, char const* const* av)
#endif
}
static int do_install(int ac, char const* const* av)
{
#ifndef CMAKE_BUILD_WITH_CMAKE
std::cerr << "This cmake does not support --install\n";
return -1;
#else
assert(1 < ac);
std::string config;
std::string component;
std::string prefix;
std::string dir;
bool strip = false;
bool verbose = cmSystemTools::HasEnv("VERBOSE");
enum Doing
{
DoingNone,
DoingDir,
DoingConfig,
DoingComponent,
DoingPrefix,
};
Doing doing = DoingDir;
for (int i = 2; i < ac; ++i) {
if (strcmp(av[i], "--config") == 0) {
doing = DoingConfig;
} else if (strcmp(av[i], "--component") == 0) {
doing = DoingComponent;
} else if (strcmp(av[i], "--prefix") == 0) {
doing = DoingPrefix;
} else if (strcmp(av[i], "--strip") == 0) {
strip = true;
doing = DoingNone;
} else if ((strcmp(av[i], "--verbose") == 0) ||
(strcmp(av[i], "-v") == 0)) {
verbose = true;
doing = DoingNone;
} else {
switch (doing) {
case DoingDir:
dir = cmSystemTools::CollapseFullPath(av[i]);
doing = DoingNone;
break;
case DoingConfig:
config = av[i];
doing = DoingNone;
break;
case DoingComponent:
component = av[i];
doing = DoingNone;
break;
case DoingPrefix:
prefix = av[i];
doing = DoingNone;
break;
default:
std::cerr << "Unknown argument " << av[i] << std::endl;
dir.clear();
break;
}
}
}
if (dir.empty()) {
std::cerr << "Usage: cmake --install <dir> "
"[options]\nOptions:\n" CMAKE_INSTALL_OPTIONS;
return 1;
}
cmake cm(cmake::RoleScript, cmState::Script);
cmSystemTools::SetMessageCallback(
[&cm](const std::string& msg, const char* title) {
cmakemainMessageCallback(msg, title, &cm);
});
cm.SetProgressCallback([&cm](const std::string& msg, float prog) {
cmakemainProgressCallback(msg, prog, &cm);
});
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
cm.SetDebugOutputOn(verbose);
cm.SetWorkingMode(cmake::SCRIPT_MODE);
std::vector<std::string> args{ av[0] };
if (!prefix.empty()) {
args.emplace_back("-DCMAKE_INSTALL_PREFIX=" + prefix);
}
if (!component.empty()) {
args.emplace_back("-DCMAKE_INSTALL_COMPONENT=" + component);
}
if (strip) {
args.emplace_back("-DCMAKE_INSTALL_DO_STRIP=1");
}
if (!config.empty()) {
args.emplace_back("-DCMAKE_INSTALL_CONFIG_NAME=" + config);
}
args.emplace_back("-P");
args.emplace_back(dir + "/cmake_install.cmake");
return cm.Run(args) ? 1 : 0;
#endif
}
static int do_open(int ac, char const* const* av)
{
#ifndef CMAKE_BUILD_WITH_CMAKE

View File

@ -54,6 +54,14 @@ run_cmake_command(build-bad-dir
run_cmake_command(build-bad-generator
${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-generator)
run_cmake_command(install-no-dir
${CMAKE_COMMAND} --install)
run_cmake_command(install-bad-dir
${CMAKE_COMMAND} --install dir-does-not-exist)
run_cmake_command(install-options-to-vars
${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-install-options-to-vars
--strip --prefix /var/test --config sample --component pack)
run_cmake_command(cache-bad-entry
${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-entry/)
run_cmake_command(cache-empty-entry

View File

@ -0,0 +1,15 @@
if(CMAKE_INSTALL_PREFIX)
message("CMAKE_INSTALL_PREFIX is ${CMAKE_INSTALL_PREFIX}")
endif()
if(CMAKE_INSTALL_COMPONENT)
message("CMAKE_INSTALL_COMPONENT is ${CMAKE_INSTALL_COMPONENT}")
endif()
if(CMAKE_INSTALL_CONFIG_NAME)
message("CMAKE_INSTALL_CONFIG_NAME is ${CMAKE_INSTALL_CONFIG_NAME}")
endif()
if(CMAKE_INSTALL_DO_STRIP)
message("CMAKE_INSTALL_DO_STRIP is ${CMAKE_INSTALL_DO_STRIP}")
endif()

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1 @@
^CMake Error: Error processing file:

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1 @@
^Usage: cmake --install <dir> \[options\]

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,4 @@
CMAKE_INSTALL_PREFIX is /var/test
CMAKE_INSTALL_COMPONENT is pack
CMAKE_INSTALL_CONFIG_NAME is sample
CMAKE_INSTALL_DO_STRIP is 1