diff options
author | Robert Maynard <robert.maynard@kitware.com> | 2020-12-30 14:05:14 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2021-01-06 14:11:18 (GMT) |
commit | 75ac6dfbce50800e12ed165ca65e91be3d0a6182 (patch) | |
tree | dfc0163f7443000634e10126742c89754f429352 /Source | |
parent | 5ab0b5448265355fcd1f88dfd49bfac075afd1c9 (diff) | |
download | CMake-75ac6dfbce50800e12ed165ca65e91be3d0a6182.zip CMake-75ac6dfbce50800e12ed165ca65e91be3d0a6182.tar.gz CMake-75ac6dfbce50800e12ed165ca65e91be3d0a6182.tar.bz2 |
cmake: --build now uses cmCommandLineArgument
This makes `--build` use the same parsing rules as the rest of the
the cmake executable
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmakemain.cxx | 178 |
1 files changed, 95 insertions, 83 deletions
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index fc740a9..4934fce 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -387,16 +387,9 @@ int do_cmake(int ac, char const* const* av) } #ifndef CMAKE_BOOTSTRAP -int extract_job_number(int& index, char const* current, char const* next, - int len_of_flag) +int extract_job_number(std::string const& command, + std::string const& jobString) { - std::string command(current); - std::string jobString = command.substr(len_of_flag); - if (jobString.empty() && next && isdigit(next[0])) { - ++index; // skip parsing the job number - jobString = std::string(next); - } - int jobs = -1; unsigned long numJobs = 0; if (jobString.empty()) { @@ -411,8 +404,8 @@ int extract_job_number(int& index, char const* current, char const* next, jobs = int(numJobs); } } else { - std::cerr << "'" << command.substr(0, len_of_flag) << "' invalid number '" - << jobString << "' given.\n\n"; + std::cerr << "'" << command << "' invalid number '" << jobString + << "' given.\n\n"; } return jobs; } @@ -429,88 +422,107 @@ int do_build(int ac, char const* const* av) std::string config; std::string dir; std::vector<std::string> nativeOptions; + bool nativeOptionsPassed = false; bool cleanFirst = false; bool foundClean = false; bool foundNonClean = false; bool verbose = cmSystemTools::HasEnv("VERBOSE"); - enum Doing - { - DoingNone, - DoingDir, - DoingTarget, - DoingConfig, - DoingNative + auto jLambda = [&](std::string const& value) -> bool { + jobs = extract_job_number("-j", value); + if (jobs < 0) { + dir.clear(); + } + return true; }; - Doing doing = DoingDir; - for (int i = 2; i < ac; ++i) { - if (doing == DoingNative) { - nativeOptions.emplace_back(av[i]); - } else if (cmHasLiteralPrefix(av[i], "-j")) { - const char* nextArg = ((i + 1 < ac) ? av[i + 1] : nullptr); - jobs = extract_job_number(i, av[i], nextArg, sizeof("-j") - 1); - if (jobs < 0) { - dir.clear(); - } - doing = DoingNone; - } else if (cmHasLiteralPrefix(av[i], "--parallel")) { - const char* nextArg = ((i + 1 < ac) ? av[i + 1] : nullptr); - jobs = extract_job_number(i, av[i], nextArg, sizeof("--parallel") - 1); - if (jobs < 0) { - dir.clear(); + auto parallelLambda = [&](std::string const& value) -> bool { + jobs = extract_job_number("--parallel", value); + if (jobs < 0) { + dir.clear(); + } + return true; + }; + auto targetLambda = [&](std::string const& value) -> bool { + if (!value.empty()) { + std::vector<std::string> values = cmExpandedList(value); + for (auto const& v : values) { + targets.emplace_back(v); + if (v == "clean") { + foundClean = true; + } else { + foundNonClean = true; + } } - doing = DoingNone; - } else if ((strcmp(av[i], "--target") == 0) || - (strcmp(av[i], "-t") == 0)) { - doing = DoingTarget; - } else if (strcmp(av[i], "--config") == 0) { - doing = DoingConfig; - } else if (strcmp(av[i], "--clean-first") == 0) { - cleanFirst = true; - doing = DoingNone; - } else if ((strcmp(av[i], "--verbose") == 0) || - (strcmp(av[i], "-v") == 0)) { - verbose = true; - doing = DoingNone; - } else if (strcmp(av[i], "--use-stderr") == 0) { - /* tolerate legacy option */ - } else if (strcmp(av[i], "--") == 0) { - doing = DoingNative; - } else { - switch (doing) { - case DoingDir: - dir = cmSystemTools::CollapseFullPath(av[i]); - doing = DoingNone; - break; - case DoingTarget: - if (strlen(av[i]) == 0) { - std::cerr << "Warning: Argument number " << i - << " after --target option is empty." << std::endl; - } else { - targets.emplace_back(av[i]); - if (strcmp(av[i], "clean") == 0) { - foundClean = true; - } else { - foundNonClean = true; - } - } - if (foundClean && foundNonClean) { - std::cerr << "Error: Building 'clean' and other targets together " - "is not supported." - << std::endl; - dir.clear(); - } - break; - case DoingConfig: - config = av[i]; - doing = DoingNone; - break; - default: - std::cerr << "Unknown argument " << av[i] << std::endl; - dir.clear(); + return true; + } + return false; + }; + auto verboseLambda = [&](std::string const&) -> bool { + verbose = true; + return true; + }; + + using CommandArgument = + cmCommandLineArgument<bool(std::string const& value)>; + + std::vector<CommandArgument> arguments = { + CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne, jLambda }, + CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne, + parallelLambda }, + CommandArgument{ "-t", CommandArgument::Values::OneOrMore, targetLambda }, + CommandArgument{ "--target", CommandArgument::Values::OneOrMore, + targetLambda }, + CommandArgument{ "--config", CommandArgument::Values::One, + [&](std::string const& value) -> bool { + config = value; + return true; + } }, + CommandArgument{ "--clean-first", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + cleanFirst = true; + return true; + } }, + CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda }, + CommandArgument{ "--verbose", CommandArgument::Values::Zero, + verboseLambda }, + /* legacy option no-op*/ + CommandArgument{ "--use-stderr", CommandArgument::Values::Zero, + [](std::string const&) -> bool { return true; } }, + CommandArgument{ "--", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + nativeOptionsPassed = true; + return true; + } }, + }; + + if (ac >= 3) { + dir = cmSystemTools::CollapseFullPath(av[2]); + + std::vector<std::string> inputArgs; + inputArgs.reserve(ac - 3); + cm::append(inputArgs, av + 3, av + ac); + + decltype(inputArgs.size()) i = 0; + for (; i < inputArgs.size() && !nativeOptionsPassed; ++i) { + + std::string const& arg = inputArgs[i]; + for (auto const& m : arguments) { + if (m.matches(arg) && m.parse(arg, i, inputArgs)) { break; + } } } + + if (nativeOptionsPassed) { + cm::append(nativeOptions, inputArgs.begin() + i, inputArgs.end()); + } + } + + if (foundClean && foundNonClean) { + std::cerr << "Error: Building 'clean' and other targets together " + "is not supported." + << std::endl; + dir.clear(); } if (jobs == cmake::NO_BUILD_PARALLEL_LEVEL) { |