in Source/cmcmd.cxx [623:1575]
int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
std::unique_ptr<cmConsoleBuf> consoleBuf)
{
// IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx
if (args.size() > 1) {
// Copy file
if (args[1] == "copy" && args.size() > 3) {
// If multiple source files specified,
// then destination must be directory
if ((args.size() > 4) &&
(!cmSystemTools::FileIsDirectory(args.back()))) {
std::cerr << "Error: Target (for copy command) \"" << args.back()
<< "\" is not a directory.\n";
return 1;
}
// If error occurs we want to continue copying next files.
bool return_value = false;
for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
if (!cmsys::SystemTools::CopyFileAlways(arg, args.back())) {
std::cerr << "Error copying file \"" << arg << "\" to \""
<< args.back() << "\".\n";
return_value = true;
}
}
return return_value;
}
// Copy file if different.
if (args[1] == "copy_if_different" && args.size() > 3) {
// If multiple source files specified,
// then destination must be directory
if ((args.size() > 4) &&
(!cmSystemTools::FileIsDirectory(args.back()))) {
std::cerr << "Error: Target (for copy_if_different command) \""
<< args.back() << "\" is not a directory.\n";
return 1;
}
// If error occurs we want to continue copying next files.
bool return_value = false;
for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
if (!cmSystemTools::CopyFileIfDifferent(arg, args.back())) {
std::cerr << "Error copying file (if different) from \"" << arg
<< "\" to \"" << args.back() << "\".\n";
return_value = true;
}
}
return return_value;
}
// Copy directory content
if (args[1] == "copy_directory" && args.size() > 3) {
// If error occurs we want to continue copying next files.
bool return_value = false;
for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
if (!cmSystemTools::CopyADirectory(arg, args.back())) {
std::cerr << "Error copying directory from \"" << arg << "\" to \""
<< args.back() << "\".\n";
return_value = true;
}
}
return return_value;
}
// Rename a file or directory
if (args[1] == "rename" && args.size() == 4) {
if (!cmSystemTools::RenameFile(args[2], args[3])) {
std::string e = cmSystemTools::GetLastSystemError();
std::cerr << "Error renaming from \"" << args[2] << "\" to \""
<< args[3] << "\": " << e << "\n";
return 1;
}
return 0;
}
// Compare files
if (args[1] == "compare_files" && (args.size() == 4 || args.size() == 5)) {
bool filesDiffer;
if (args.size() == 4) {
filesDiffer = cmSystemTools::FilesDiffer(args[2], args[3]);
} else if (args[2] == "--ignore-eol") {
filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
} else {
CMakeCommandUsage(args[0]);
return 2;
}
if (filesDiffer) {
return 1;
}
return 0;
}
#if !defined(CMAKE_BOOTSTRAP)
if (args[1] == "__create_def") {
if (args.size() < 4) {
std::cerr << "__create_def Usage: -E __create_def outfile.def "
"objlistfile [--nm=nm-path]\n";
return 1;
}
cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary);
if (!fin) {
std::cerr << "could not open object list file: " << args[3] << "\n";
return 1;
}
std::vector<std::string> files;
{
std::string file;
cmFileTime outTime;
bool outValid = outTime.Load(args[2]);
while (cmSystemTools::GetLineFromStream(fin, file)) {
files.push_back(file);
if (outValid) {
cmFileTime inTime;
outValid = inTime.Load(file) && inTime.Older(outTime);
}
}
if (outValid) {
// The def file already exists and all input files are older than
// the existing def file.
return 0;
}
}
FILE* fout = cmsys::SystemTools::Fopen(args[2], "w+");
if (!fout) {
std::cerr << "could not open output .def file: " << args[2] << "\n";
return 1;
}
bindexplib deffile;
if (args.size() >= 5) {
std::string const& a = args[4];
if (cmHasLiteralPrefix(a, "--nm=")) {
deffile.SetNmPath(a.substr(5));
} else {
std::cerr << "unknown argument: " << a << "\n";
}
}
for (std::string const& file : files) {
std::string const& ext = cmSystemTools::GetFilenameLastExtension(file);
if (cmSystemTools::LowerCase(ext) == ".def") {
if (!deffile.AddDefinitionFile(file.c_str())) {
return 1;
}
} else {
if (!deffile.AddObjectFile(file.c_str())) {
return 1;
}
}
}
deffile.WriteFile(fout);
fclose(fout);
return 0;
}
#endif
if (args[1] == "__run_co_compile") {
return cmcmd::HandleCoCompileCommands(args);
}
// Echo string
if (args[1] == "echo") {
std::cout << cmJoin(cmMakeRange(args).advance(2), " ") << std::endl;
return 0;
}
// Echo string no new line
if (args[1] == "echo_append") {
std::cout << cmJoin(cmMakeRange(args).advance(2), " ");
return 0;
}
if (args[1] == "env") {
auto ai = args.cbegin() + 2;
auto ae = args.cend();
for (; ai != ae; ++ai) {
std::string const& a = *ai;
if (cmHasLiteralPrefix(a, "--unset=")) {
// Unset environment variable.
cmSystemTools::UnPutEnv(a.substr(8));
} else if (!a.empty() && a[0] == '-') {
// Environment variable and command names cannot start in '-',
// so this must be an unknown option.
std::cerr << "cmake -E env: unknown option '" << a << '\''
<< std::endl;
return 1;
} else if (a.find('=') != std::string::npos) {
// Set environment variable.
cmSystemTools::PutEnv(a);
} else {
// This is the beginning of the command.
break;
}
}
if (ai == ae) {
std::cerr << "cmake -E env: no command given" << std::endl;
return 1;
}
// Execute command from remaining arguments.
std::vector<std::string> cmd(ai, ae);
int retval;
if (cmSystemTools::RunSingleCommand(cmd, nullptr, nullptr, &retval,
nullptr,
cmSystemTools::OUTPUT_PASSTHROUGH)) {
return retval;
}
return 1;
}
#if !defined(CMAKE_BOOTSTRAP)
if (args[1] == "environment") {
for (auto const& env : cmSystemTools::GetEnvironmentVariables()) {
std::cout << env << std::endl;
}
return 0;
}
#endif
if (args[1] == "make_directory" && args.size() > 2) {
// If an error occurs, we want to continue making directories.
bool return_value = false;
for (auto const& arg : cmMakeRange(args).advance(2)) {
if (!cmSystemTools::MakeDirectory(arg)) {
std::cerr << "Error creating directory \"" << arg << "\".\n";
return_value = true;
}
}
return return_value;
}
if (args[1] == "remove_directory" && args.size() > 2) {
// If an error occurs, we want to continue removing directories.
bool return_value = false;
for (auto const& arg : cmMakeRange(args).advance(2)) {
if (cmSystemTools::FileIsDirectory(arg)) {
if (!cmRemoveDirectory(arg)) {
return_value = true;
}
}
}
return return_value;
}
// Remove file
if (args[1] == "remove" && args.size() > 2) {
bool force = false;
for (auto const& arg : cmMakeRange(args).advance(2)) {
if (arg == "\\-f" || arg == "-f") {
force = true;
} else {
// Complain if the file could not be removed, still exists,
// and the -f option was not given.
if (!cmSystemTools::RemoveFile(arg) && !force &&
cmSystemTools::FileExists(arg)) {
return 1;
}
}
}
return 0;
}
// Remove directories or files with rm
if (args[1] == "rm" && args.size() > 2) {
// If an error occurs, we want to continue removing the remaining
// files/directories.
int return_value = 0;
bool force = false;
bool recursive = false;
bool doing_options = true;
bool at_least_one_file = false;
for (auto const& arg : cmMakeRange(args).advance(2)) {
if (doing_options && cmHasLiteralPrefix(arg, "-")) {
if (arg == "--") {
doing_options = false;
}
if (arg.find('f') != std::string::npos) {
force = true;
}
if (arg.find_first_of("rR") != std::string::npos) {
recursive = true;
}
if (arg.find_first_not_of("-frR") != std::string::npos) {
cmSystemTools::Error("Unknown -E rm argument: " + arg);
return 1;
}
} else {
if (arg.empty()) {
continue;
}
at_least_one_file = true;
// Complain if the -f option was not given and
// either file does not exist or
// file could not be removed and still exists
bool file_exists_or_forced_remove = cmSystemTools::FileExists(arg) ||
cmSystemTools::FileIsSymlink(arg) || force;
if (cmSystemTools::FileIsDirectory(arg)) {
if (!cmRemoveDirectory(arg, recursive)) {
return_value = 1;
}
} else if ((!file_exists_or_forced_remove) ||
(!cmSystemTools::RemoveFile(arg) &&
cmSystemTools::FileExists(arg))) {
if (!file_exists_or_forced_remove) {
cmSystemTools::Error(
"File to remove does not exist and force is not set: " + arg);
} else {
cmSystemTools::Error("File can't be removed and still exist: " +
arg);
}
return_value = 1;
}
}
}
if (!at_least_one_file) {
cmSystemTools::Error("Missing file/directory to remove");
return 1;
}
return return_value;
}
// Touch file
if (args[1] == "touch" && args.size() > 2) {
for (auto const& arg : cmMakeRange(args).advance(2)) {
if (!cmSystemTools::Touch(arg, true)) {
std::cerr << "cmake -E touch: failed to update \"";
std::cerr << arg << "\".\n";
return 1;
}
}
return 0;
}
// Touch file
if (args[1] == "touch_nocreate" && args.size() > 2) {
for (auto const& arg : cmMakeRange(args).advance(2)) {
if (!cmSystemTools::Touch(arg, false)) {
std::cerr << "cmake -E touch_nocreate: failed to update \"";
std::cerr << arg << "\".\n";
return 1;
}
}
return 0;
}
// capabilities
if (args[1] == "capabilities") {
if (args.size() > 2) {
std::cerr << "-E capabilities accepts no additional arguments\n";
return 1;
}
cmake cm(cmake::RoleInternal, cmState::Unknown);
std::cout << cm.ReportCapabilities();
return 0;
}
// Sleep command
if (args[1] == "sleep" && args.size() > 2) {
double total = 0;
for (auto const& arg : cmMakeRange(args).advance(2)) {
double num = 0.0;
char unit;
char extra;
int n = sscanf(arg.c_str(), "%lg%c%c", &num, &unit, &extra);
if ((n == 1 || (n == 2 && unit == 's')) && num >= 0) {
total += num;
} else {
std::cerr << "Unknown sleep time format \"" << arg << "\".\n";
return 1;
}
}
if (total > 0) {
cmSystemTools::Delay(static_cast<unsigned int>(total * 1000));
}
return 0;
}
// Clock command
if (args[1] == "time" && args.size() > 2) {
std::vector<std::string> command(args.begin() + 2, args.end());
clock_t clock_start;
clock_t clock_finish;
time_t time_start;
time_t time_finish;
time(&time_start);
clock_start = clock();
int ret = 0;
cmSystemTools::RunSingleCommand(command, nullptr, nullptr, &ret);
clock_finish = clock();
time(&time_finish);
double clocks_per_sec = static_cast<double>(CLOCKS_PER_SEC);
std::cout << "Elapsed time: "
<< static_cast<long>(time_finish - time_start) << " s. (time)"
<< ", "
<< static_cast<double>(clock_finish - clock_start) /
clocks_per_sec
<< " s. (clock)"
<< "\n";
return ret;
}
// Command to calculate the md5sum of a file
if (args[1] == "md5sum" && args.size() >= 3) {
return HashSumFile(args, cmCryptoHash::AlgoMD5);
}
// Command to calculate the sha1sum of a file
if (args[1] == "sha1sum" && args.size() >= 3) {
return HashSumFile(args, cmCryptoHash::AlgoSHA1);
}
if (args[1] == "sha224sum" && args.size() >= 3) {
return HashSumFile(args, cmCryptoHash::AlgoSHA224);
}
if (args[1] == "sha256sum" && args.size() >= 3) {
return HashSumFile(args, cmCryptoHash::AlgoSHA256);
}
if (args[1] == "sha384sum" && args.size() >= 3) {
return HashSumFile(args, cmCryptoHash::AlgoSHA384);
}
if (args[1] == "sha512sum" && args.size() >= 3) {
return HashSumFile(args, cmCryptoHash::AlgoSHA512);
}
// Command to concat files into one
if (args[1] == "cat" && args.size() >= 3) {
int return_value = 0;
for (auto const& arg : cmMakeRange(args).advance(2)) {
if (cmHasLiteralPrefix(arg, "-")) {
if (arg != "--") {
cmSystemTools::Error(arg + ": option not handled");
return_value = 1;
}
} else if (!cmSystemTools::TestFileAccess(arg,
cmsys::TEST_FILE_READ) &&
cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) {
cmSystemTools::Error(arg + ": permission denied (ignoring)");
return_value = 1;
} else if (cmSystemTools::FileIsDirectory(arg)) {
cmSystemTools::Error(arg + ": is a directory (ignoring)");
return_value = 1;
} else if (!cmSystemTools::FileExists(arg)) {
cmSystemTools::Error(arg + ": no such file or directory (ignoring)");
return_value = 1;
} else if (cmSystemTools::FileLength(arg) == 0) {
// Ignore empty files, this is not an error
} else {
// Destroy console buffers to drop cout/cerr encoding transform.
consoleBuf.reset();
cmCatFile(arg);
}
}
return return_value;
}
// Command to change directory and run a program.
if (args[1] == "chdir" && args.size() >= 4) {
std::string const& directory = args[2];
if (!cmSystemTools::FileExists(directory)) {
cmSystemTools::Error("Directory does not exist for chdir command: " +
directory);
return 1;
}
std::string command =
cmWrap('"', cmMakeRange(args).advance(3), '"', " ");
int retval = 0;
if (cmSystemTools::RunSingleCommand(
command, nullptr, nullptr, &retval, directory.c_str(),
cmSystemTools::OUTPUT_PASSTHROUGH, cmDuration::zero())) {
return retval;
}
return 1;
}
// Command to start progress for a build
if (args[1] == "cmake_progress_start" && args.size() == 4) {
// basically remove the directory
std::string dirName = cmStrCat(args[2], "/Progress");
cmSystemTools::RemoveADirectory(dirName);
// is the last argument a filename that exists?
FILE* countFile = cmsys::SystemTools::Fopen(args[3], "r");
int count;
if (countFile) {
if (1 != fscanf(countFile, "%i", &count)) {
cmSystemTools::Message("Could not read from count file.");
}
fclose(countFile);
} else {
count = atoi(args[3].c_str());
}
if (count) {
cmSystemTools::MakeDirectory(dirName);
// write the count into the directory
std::string fName = cmStrCat(dirName, "/count.txt");
FILE* progFile = cmsys::SystemTools::Fopen(fName, "w");
if (progFile) {
fprintf(progFile, "%i\n", count);
fclose(progFile);
}
}
return 0;
}
// Command to report progress for a build
if (args[1] == "cmake_progress_report" && args.size() >= 3) {
// This has been superseded by cmake_echo_color --progress-*
// options. We leave it here to avoid errors if somehow this
// is invoked by an existing makefile without regenerating.
return 0;
}
// Command to create a symbolic link. Fails on platforms not
// supporting them.
if (args[1] == "create_symlink" && args.size() == 4) {
std::string const& destinationFileName = args[3];
if ((cmSystemTools::FileExists(destinationFileName) ||
cmSystemTools::FileIsSymlink(destinationFileName)) &&
!cmSystemTools::RemoveFile(destinationFileName)) {
std::string emsg = cmSystemTools::GetLastSystemError();
std::cerr << "failed to create symbolic link '" << destinationFileName
<< "' because existing path cannot be removed: " << emsg
<< "\n";
return 1;
}
if (!cmSystemTools::CreateSymlink(args[2], destinationFileName)) {
return 1;
}
return 0;
}
// Command to create a hard link. Fails on platforms not
// supporting them.
if (args[1] == "create_hardlink" && args.size() == 4) {
std::string const& sourceFileName = args[2];
std::string const& destinationFileName = args[3];
if (!cmSystemTools::FileExists(sourceFileName)) {
std::cerr << "failed to create hard link because source path '"
<< sourceFileName << "' does not exist \n";
return 1;
}
if ((cmSystemTools::FileExists(destinationFileName) ||
cmSystemTools::FileIsSymlink(destinationFileName)) &&
!cmSystemTools::RemoveFile(destinationFileName)) {
std::string emsg = cmSystemTools::GetLastSystemError();
std::cerr << "failed to create hard link '" << destinationFileName
<< "' because existing path cannot be removed: " << emsg
<< "\n";
return 1;
}
if (!cmSystemTools::CreateLink(sourceFileName, destinationFileName)) {
return 1;
}
return 0;
}
// Command to do nothing with an exit code of 0.
if (args[1] == "true") {
return 0;
}
// Command to do nothing with an exit code of 1.
if (args[1] == "false") {
return 1;
}
// Internal CMake shared library support.
if (args[1] == "cmake_symlink_library" && args.size() == 5) {
return cmcmd::SymlinkLibrary(args);
}
// Internal CMake versioned executable support.
if (args[1] == "cmake_symlink_executable" && args.size() == 4) {
return cmcmd::SymlinkExecutable(args);
}
// Internal CMake dependency scanning support.
if (args[1] == "cmake_depends" && args.size() >= 6) {
const bool verbose = isCMakeVerbose();
// Create a cmake object instance to process dependencies.
// All we need is the `set` command.
cmake cm(cmake::RoleScript, cmState::Unknown);
std::string gen;
std::string homeDir;
std::string startDir;
std::string homeOutDir;
std::string startOutDir;
std::string depInfo;
bool color = false;
if (args.size() >= 8) {
// Full signature:
//
// -E cmake_depends <generator>
// <home-src-dir> <start-src-dir>
// <home-out-dir> <start-out-dir>
// <dep-info> [--color=$(COLOR)]
//
// All paths are provided.
gen = args[2];
homeDir = args[3];
startDir = args[4];
homeOutDir = args[5];
startOutDir = args[6];
depInfo = args[7];
if (args.size() >= 9 && cmHasLiteralPrefix(args[8], "--color=")) {
// Enable or disable color based on the switch value.
color = (args[8].size() == 8 || cmIsOn(args[8].substr(8)));
}
} else {
// Support older signature for existing makefiles:
//
// -E cmake_depends <generator>
// <home-out-dir> <start-out-dir>
// <dep-info>
//
// Just pretend the source directories are the same as the
// binary directories so at least scanning will work.
gen = args[2];
homeDir = args[3];
startDir = args[4];
homeOutDir = args[3];
startOutDir = args[3];
depInfo = args[5];
}
// Create a local generator configured for the directory in
// which dependencies will be scanned.
homeDir = cmSystemTools::CollapseFullPath(homeDir);
startDir = cmSystemTools::CollapseFullPath(startDir);
homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir);
startOutDir = cmSystemTools::CollapseFullPath(startOutDir);
cm.SetHomeDirectory(homeDir);
cm.SetHomeOutputDirectory(homeOutDir);
cm.GetCurrentSnapshot().SetDefaultDefinitions();
if (auto ggd = cm.CreateGlobalGenerator(gen)) {
cm.SetGlobalGenerator(std::move(ggd));
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(startOutDir);
snapshot.GetDirectory().SetCurrentSource(startDir);
cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);
// FIXME: With advanced add_subdirectory usage, these are
// not necessarily the same as the generator originally used.
// We should pass all these directories through an info file.
lgd->SetRelativePathTopSource(homeDir);
lgd->SetRelativePathTopBinary(homeOutDir);
// Actually scan dependencies.
return lgd->UpdateDependencies(depInfo, verbose, color) ? 0 : 2;
}
return 1;
}
#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_MAKEFILES)
// Internal CMake compiler dependencies filtering
if (args[1] == "cmake_cl_compile_depends") {
return CLCompileAndDependencies(args);
}
#endif
// Internal CMake link script support.
if (args[1] == "cmake_link_script" && args.size() >= 3) {
return cmcmd::ExecuteLinkScript(args);
}
#if !defined(CMAKE_BOOTSTRAP)
// Internal CMake ninja dependency scanning support.
if (args[1] == "cmake_ninja_depends") {
return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end());
}
// Internal CMake ninja dyndep support.
if (args[1] == "cmake_ninja_dyndep") {
return cmcmd_cmake_ninja_dyndep(args.begin() + 2, args.end());
}
#endif
// Internal CMake unimplemented feature notification.
if (args[1] == "cmake_unimplemented_variable") {
std::cerr << "Feature not implemented for this platform.";
if (args.size() == 3) {
std::cerr << " Variable " << args[2] << " is not set.";
}
std::cerr << std::endl;
return 1;
}
if (args[1] == "vs_link_exe") {
return cmcmd::VisualStudioLink(args, 1);
}
if (args[1] == "vs_link_dll") {
return cmcmd::VisualStudioLink(args, 2);
}
if (args[1] == "cmake_llvm_rc") {
return cmcmd::RunLLVMRC(args);
}
// Internal CMake color makefile support.
if (args[1] == "cmake_echo_color") {
return cmcmd::ExecuteEchoColor(args);
}
#ifndef CMAKE_BOOTSTRAP
if ((args[1] == "cmake_autogen") && (args.size() >= 4)) {
cm::string_view const infoFile = args[2];
cm::string_view const config = args[3];
return cmQtAutoMocUic(infoFile, config) ? 0 : 1;
}
if ((args[1] == "cmake_autorcc") && (args.size() >= 3)) {
cm::string_view const infoFile = args[2];
cm::string_view const config =
(args.size() > 3) ? cm::string_view(args[3]) : cm::string_view();
return cmQtAutoRcc(infoFile, config) ? 0 : 1;
}
#endif
// Tar files
if (args[1] == "tar" && args.size() > 3) {
const char* knownFormats[] = { "7zip", "gnutar", "pax", "paxr", "zip" };
std::string const& flags = args[2];
std::string const& outFile = args[3];
std::vector<std::string> files;
std::string mtime;
std::string format;
cmSystemTools::cmTarCompression compress =
cmSystemTools::TarCompressNone;
int nCompress = 0;
bool doing_options = true;
for (auto const& arg : cmMakeRange(args).advance(4)) {
if (doing_options && cmHasLiteralPrefix(arg, "--")) {
if (arg == "--") {
doing_options = false;
} else if (arg == "--zstd") {
compress = cmSystemTools::TarCompressZstd;
++nCompress;
} else if (cmHasLiteralPrefix(arg, "--mtime=")) {
mtime = arg.substr(8);
} else if (cmHasLiteralPrefix(arg, "--files-from=")) {
std::string const& files_from = arg.substr(13);
if (!cmTarFilesFrom(files_from, files)) {
return 1;
}
} else if (cmHasLiteralPrefix(arg, "--format=")) {
format = arg.substr(9);
if (!cm::contains(knownFormats, format)) {
cmSystemTools::Error("Unknown -E tar --format= argument: " +
format);
return 1;
}
} else {
cmSystemTools::Error("Unknown option to -E tar: " + arg);
return 1;
}
} else {
files.push_back(arg);
}
}
cmSystemTools::cmTarAction action = cmSystemTools::TarActionNone;
bool verbose = false;
for (auto flag : flags) {
switch (flag) {
case '-':
case 'f': {
// Keep for backward compatibility. Ignored
} break;
case 'j': {
compress = cmSystemTools::TarCompressBZip2;
++nCompress;
} break;
case 'J': {
compress = cmSystemTools::TarCompressXZ;
++nCompress;
} break;
case 'z': {
compress = cmSystemTools::TarCompressGZip;
++nCompress;
} break;
case 'v': {
verbose = true;
} break;
case 't': {
action = cmSystemTools::TarActionList;
} break;
case 'c': {
action = cmSystemTools::TarActionCreate;
} break;
case 'x': {
action = cmSystemTools::TarActionExtract;
} break;
default: {
cmSystemTools::Message(
std::string("tar: Unknown argument: ") + flag, "Warning");
}
}
}
if ((format == "7zip" || format == "zip") && nCompress > 0) {
cmSystemTools::Error("Can not use compression flags with format: " +
format);
return 1;
}
if (nCompress > 1) {
cmSystemTools::Error("Can only compress a tar file one way; "
"at most one flag of z, j, or J may be used");
return 1;
}
if (action == cmSystemTools::TarActionList) {
if (!cmSystemTools::ListTar(outFile, files, verbose)) {
cmSystemTools::Error("Problem listing tar: " + outFile);
return 1;
}
} else if (action == cmSystemTools::TarActionCreate) {
if (files.empty()) {
cmSystemTools::Message("tar: No files or directories specified",
"Warning");
}
if (!cmSystemTools::CreateTar(outFile, files, compress, verbose, mtime,
format)) {
cmSystemTools::Error("Problem creating tar: " + outFile);
return 1;
}
} else if (action == cmSystemTools::TarActionExtract) {
if (!cmSystemTools::ExtractTar(outFile, files, verbose)) {
cmSystemTools::Error("Problem extracting tar: " + outFile);
return 1;
}
#ifdef _WIN32
// OK, on windows 7 after we untar some files,
// sometimes we can not rename the directory after
// the untar is done. This breaks the external project
// untar and rename code. So, by default we will wait
// 1/10th of a second after the untar. If CMAKE_UNTAR_DELAY
// is set in the env, its value will be used instead of 100.
int delay = 100;
std::string delayVar;
if (cmSystemTools::GetEnv("CMAKE_UNTAR_DELAY", delayVar)) {
delay = atoi(delayVar.c_str());
}
if (delay) {
cmSystemTools::Delay(delay);
}
#endif
} else {
cmSystemTools::Error("tar: No action specified. Please choose: 't' "
"(list), 'c' (create) or 'x' (extract)");
return 1;
}
return 0;
}
if (args[1] == "server") {
cmSystemTools::Error(
"CMake server mode has been removed in favor of the file-api.");
return 1;
}
#if !defined(CMAKE_BOOTSTRAP)
// Internal CMake Fortran module support.
if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4) {
return cmDependsFortran::CopyModule(args) ? 0 : 1;
}
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
// Write registry value
if (args[1] == "write_regv" && args.size() > 3) {
return cmSystemTools::WriteRegistryValue(args[2], args[3]) ? 0 : 1;
}
// Delete registry value
if (args[1] == "delete_regv" && args.size() > 2) {
return cmSystemTools::DeleteRegistryValue(args[2]) ? 0 : 1;
}
// Remove file
if (args[1] == "comspec" && args.size() > 2) {
std::cerr << "Win9x helper \"cmake -E comspec\" no longer supported\n";
return 1;
}
if (args[1] == "env_vs8_wince" && args.size() == 3) {
return cmcmd::WindowsCEEnvironment("8.0", args[2]);
}
if (args[1] == "env_vs9_wince" && args.size() == 3) {
return cmcmd::WindowsCEEnvironment("9.0", args[2]);
}
#endif
// Internal depfile transformation
if (args[1] == "cmake_transform_depfile" && args.size() == 10) {
auto format = cmDepfileFormat::GccDepfile;
if (args[3] == "gccdepfile") {
format = cmDepfileFormat::GccDepfile;
} else if (args[3] == "makedepfile") {
format = cmDepfileFormat::MakeDepfile;
} else if (args[3] == "MSBuildAdditionalInputs") {
format = cmDepfileFormat::MSBuildAdditionalInputs;
} else {
return 1;
}
// Create a cmake object instance to process dependencies.
// All we need is the `set` command.
cmake cm(cmake::RoleScript, cmState::Unknown);
std::string homeDir;
std::string startDir;
std::string homeOutDir;
std::string startOutDir;
homeDir = cmSystemTools::CollapseFullPath(args[4]);
startDir = cmSystemTools::CollapseFullPath(args[5]);
homeOutDir = cmSystemTools::CollapseFullPath(args[6]);
startOutDir = cmSystemTools::CollapseFullPath(args[7]);
cm.SetHomeDirectory(homeDir);
cm.SetHomeOutputDirectory(homeOutDir);
cm.GetCurrentSnapshot().SetDefaultDefinitions();
if (auto ggd = cm.CreateGlobalGenerator(args[2])) {
cm.SetGlobalGenerator(std::move(ggd));
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(startOutDir);
snapshot.GetDirectory().SetCurrentSource(startDir);
cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);
// FIXME: With advanced add_subdirectory usage, these are
// not necessarily the same as the generator originally used.
// We should pass all these directories through an info file.
lgd->SetRelativePathTopSource(homeDir);
lgd->SetRelativePathTopBinary(homeOutDir);
return cmTransformDepfile(format, *lgd, args[8], args[9]) ? 0 : 2;
}
return 1;
}
}
CMakeCommandUsage(args[0]);
return 1;
}