fixed crashes because smatch was referring to a dead string

fixed main help showing instead of command help
cmake command
This commit is contained in:
isanae
2020-05-17 19:21:26 -04:00
parent 80194fe611
commit 601fae8689
9 changed files with 229 additions and 68 deletions
+72 -1
View File
@@ -4,6 +4,7 @@
#include "conf.h"
#include "net.h"
#include "tasks/tasks.h"
#include "tools/tools.h"
namespace mob
{
@@ -90,6 +91,11 @@ void command::force_pick()
picked_ = true;
}
void command::force_help()
{
help_ = true;
}
bool command::picked() const
{
return picked_;
@@ -208,7 +214,8 @@ int help_command::do_run()
" options lists available options and default values\n"
" build builds tasks\n"
" release creates a release or a devbuild\n"
" git manages the git repos"
" git manages the git repos\n"
" cmake runs cmake in a directory\n"
"\n\n"
"Invoking `mob -d some/prefix build` builds everything. Do \n"
"`mob build <task name>...` to build specific tasks. See\n"
@@ -1104,4 +1111,68 @@ std::string git_command::make_url(const std::string& git_file)
return "git@github.com:" + username_ + "/" + git_file;
}
cmake_command::cmake_command()
: command(requires_options)
{
}
clipp::group cmake_command::do_group()
{
return clipp::group(
clipp::command("cmake").set(picked_),
(clipp::option("-h", "--help") >> help_)
% "shows this message",
(clipp::option("-G", "--generator")
& clipp::value("GEN") >> gen_)
% ("sets the -G option for cmake [default: VS]"),
(clipp::option("-c", "--cmd")
& clipp::value("CMD") >> cmd_)
% "overrides the cmake command line [default: \"..\"]",
(
clipp::option("--x64").set(x64_, true) |
clipp::option("--x86").set(x64_, false)
)
% "whether to use the x64 or x86 vcvars; if -G is not set, "
"whether to pass \"-A Win32\" or \"-A x64\" for the default "
"VS generator [default: x64]",
(clipp::option("--install-prefix")
& clipp::value("PATH") >> prefix_)
% "sets CMAKE_INSTALL_PREFIX [default: empty]",
(clipp::value("PATH") >> path_)
% "path from which to run `cmake`"
);
}
int cmake_command::do_run()
{
auto t = modorganizer::create_cmake_tool(fs::path(utf8_to_utf16(path_)));
t.generator(gen_);
t.cmd(cmd_);
t.prefix(prefix_);
t.output(path_);
if (!x64_)
t.architecture(arch::x86);
context cxcopy(gcx());
t.run(cxcopy);
return 0;
}
std::string cmake_command::do_doc()
{
return
"Runs `cmake ..` in the given directory with the same command line\n"
"as the one used for modorganizer projects.";
}
} // namespace
+20
View File
@@ -26,6 +26,7 @@ public:
void force_exit_code(int code);
void force_pick();
void force_help();
bool picked() const;
bool wants_help() const;
@@ -224,4 +225,23 @@ private:
std::string make_url(const std::string& git_file);
};
class cmake_command : public command
{
public:
cmake_command();
protected:
clipp::group do_group() override;
int do_run() override;
std::string do_doc() override;
private:
std::string gen_;
std::string cmd_;
bool x64_ = true;
std::string prefix_;
std::string path_;
};
} // namespace
+6 -9
View File
@@ -24,6 +24,7 @@ std::shared_ptr<command> handle_command_line(const std::vector<std::string>& arg
std::make_unique<list_command>(),
std::make_unique<release_command>(),
std::make_unique<git_command>(),
std::make_unique<cmake_command>()
};
@@ -44,18 +45,14 @@ std::shared_ptr<command> handle_command_line(const std::vector<std::string>& arg
if (!pr)
{
// some commands have mandatory options, like devbuild, which requires
// the build number
//
// doing `devbuild -h` therefore fails to parse because of the missing
// build number
//
// but options are actually still set correctly, so -h can be checked
// manually here
// if a command was picked, show its help instead of the main one
for (auto&& c : commands)
{
if (c->picked() && c->wants_help())
if (c->picked())
{
c->force_help();
return std::move(c);
}
}
// bad command line
+26 -20
View File
@@ -188,11 +188,20 @@ void boost::write_config_jam()
}
std::smatch boost::parse_boost_version()
boost::version_info boost::parsed_version()
{
// 1.72.0-b1-rc1
// everything but 1.72 is optional
std::regex re(R"((\d+)\.(\d+)(?:\.(\d+)(?:-(\w+)(?:-(\w+))?)?)?)");
std::regex re(
"(\\d+)\\." // 1.
"(\\d+)" // 72
"(?:"
"\\.(\\d+)" // .0
"(?:"
"-(.+)" // -b1-rc1
")?"
")?");
std::smatch m;
const auto s = version();
@@ -200,7 +209,7 @@ std::smatch boost::parse_boost_version()
if (!std::regex_match(s, m, re))
bail_out("bad boost version '{}'", s);
return m;
return {m[1], m[2], m[3], m[4]};
}
std::string boost::source_download_filename()
@@ -270,21 +279,21 @@ std::string boost::python_version_for_jam()
std::string boost::boost_version_no_patch_underscores()
{
const auto m = parse_boost_version();
const auto v = parsed_version();
// 1_72
return m[1].str() + "_" + m[2].str();
return v.major + "_" + v.minor;
}
std::string boost::boost_version_no_tags()
{
const auto m = parse_boost_version();
const auto v = parsed_version();
// 1.72.1
std::string s = m[1].str() + "." + m[2].str();
// 1.72[.1]
std::string s = v.major + "." + v.minor;
if (m[3] != "")
s += "." + m[3].str();
if (v.patch != "")
s += "." + v.patch;
return s;
}
@@ -296,19 +305,16 @@ std::string boost::boost_version_no_tags_underscores()
std::string boost::boost_version_all_underscores()
{
const auto m = parse_boost_version();
const auto v = parsed_version();
// boost_1_72_0_b1_rc1
std::string s = "boost_" + m[1].str() + "_" + m[2].str();
// boost_1_72[_0[_b1_rc1]]
std::string s = "boost_" + v.major + "_" + v.minor;
if (m[3] != "")
s += "_" + m[3].str();
if (v.patch != "")
s += "_" + v.patch;
if (m[4] != "")
s += "_" + m[4].str();
if (m[5] != "")
s += "_" + m[5].str();
if (v.rest != "")
s += "_" + replace_all(v.rest, "-", "_");
return s;
}
+26
View File
@@ -64,6 +64,32 @@ void modorganizer::do_fetch()
.output(this_source_path()));
}
cmake modorganizer::create_cmake_tool(const fs::path& root)
{
cmake m;
m
.generator(cmake::vs)
.def("CMAKE_INSTALL_PREFIX:PATH", paths::install())
.def("DEPENDENCIES_DIR", paths::build())
.def("BOOST_ROOT", boost::source_path())
.def("BOOST_LIBRARYDIR", boost::lib_path(arch::x64))
.def("FMT_ROOT", fmt::source_path())
.def("SPDLOG_ROOT", spdlog::source_path())
.def("LOOT_PATH", libloot::source_path())
.def("LZ4_ROOT", lz4::source_path())
.def("QT_ROOT", qt::installation_path())
.def("ZLIB_ROOT", zlib::source_path())
.def("PYTHON_ROOT", python::source_path())
.def("SEVENZ_ROOT", sevenz::source_path())
.def("LIBBSARCH_ROOT", libbsarch::source_path())
.def("BOOST_DI_ROOT", boost_di::source_path())
.def("GTEST_ROOT", gtest::source_path())
.root(root);
return m;
}
void modorganizer::do_build_and_install()
{
{
+19 -28
View File
@@ -194,16 +194,24 @@ std::vector<std::string> openssl::output_names()
{
return
{
"libcrypto-" + version_no_minor_underscores() + "-x64",
"libssl-" + version_no_minor_underscores() + "-x64"
"libcrypto-" + version_no_patch_underscores() + "-x64",
"libssl-" + version_no_patch_underscores() + "-x64"
};
}
std::smatch openssl::parse_version()
openssl::version_info openssl::parsed_version()
{
// 1.1.1d
// 1.2.3d
// everything but 1 is optional
std::regex re(R"((\d+)(?:\.(\d+)(?:\.(\d+)([a-zA-Z]+)?)?)?)");
std::regex re(
"(\\d+)" // 1
"(?:"
"\\.(\\d+)" // .2
"(?:"
"\\.(\\d+)([a-zA-Z]+)?" // .3d
")?"
")?");
std::smatch m;
const auto s = version();
@@ -211,36 +219,19 @@ std::smatch openssl::parse_version()
if (!std::regex_match(s, m, re))
bail_out("bad openssl version '{}'", s);
return m;
return {m[1], m[2], m[3]};
}
std::string openssl::version_no_tags()
std::string openssl::version_no_patch_underscores()
{
auto m = parse_version();
auto v = parsed_version();
// up to 4 so the tag is skipped if present
const std::size_t count = std::min<std::size_t>(m.size(), 4);
std::string s = v.major;
std::string s;
for (std::size_t i=1; i<count; ++i)
{
if (!s.empty())
s += ".";
s += m[i].str();
}
if (v.minor != "")
s += "_" + v.minor;
return s;
}
std::string openssl::version_no_minor_underscores()
{
auto m = parse_version();
if (m[2] == "")
return m[1].str();
else
return m[1].str() + "_" + m[2].str();
}
} // namespace
+15 -4
View File
@@ -12,8 +12,14 @@ namespace mob
class boost : public basic_task<boost>
{
public:
struct version_info
{
std::string major, minor, patch, rest;
};
boost();
static version_info parsed_version();
static std::string version();
static std::string version_vs();
static bool prebuilt();
@@ -41,7 +47,6 @@ private:
const std::vector<std::string>& components,
const std::string& link, const std::string& runtime_link, arch a);
static std::smatch parse_boost_version();
static std::string source_download_filename();
static fs::path config_jam_file();
static url prebuilt_url();
@@ -262,6 +267,8 @@ public:
static fs::path source_path();
static fs::path super_path();
static cmake create_cmake_tool(const fs::path& root);
bool is_super() const override;
protected:
@@ -314,8 +321,14 @@ protected:
class openssl : public basic_task<openssl>
{
public:
struct version_info
{
std::string major, minor, patch;
};
openssl();
static version_info parsed_version();
static std::string version();
static bool prebuilt();
@@ -344,9 +357,7 @@ private:
static url prebuilt_url();
static fs::path build_path();
static std::vector<std::string> output_names();
static std::smatch parse_version();
static std::string version_no_tags();
static std::string version_no_minor_underscores();
static std::string version_no_patch_underscores();
};
+40 -6
View File
@@ -36,12 +36,24 @@ cmake& cmake::generator(generators g)
return *this;
}
cmake& cmake::generator(const std::string& g)
{
genstring_ = g;
return *this;
}
cmake& cmake::root(const fs::path& p)
{
root_ = p;
return *this;
}
cmake& cmake::output(const fs::path& p)
{
output_ = p;
return *this;
}
cmake& cmake::prefix(const fs::path& s)
{
prefix_ = s;
@@ -72,6 +84,12 @@ cmake& cmake::architecture(arch a)
return *this;
}
cmake& cmake::cmd(const std::string& s)
{
cmd_ = s;
return *this;
}
fs::path cmake::result() const
{
return output_;
@@ -83,23 +101,39 @@ void cmake::do_run()
cx_->bail_out(context::generic, "cmake output path is empty");
const auto& g = get_generator(gen_);
output_ = root_ / (g.output_dir(arch_));
if (output_.empty())
output_ = root_ / (g.output_dir(arch_));
process_
.stdout_encoding(encodings::utf8)
.stderr_encoding(encodings::utf8)
.arg("-G", "\"" + g.name + "\"")
.arg("-DCMAKE_BUILD_TYPE=Release")
.arg("-DCMAKE_INSTALL_MESSAGE=NEVER", process::log_quiet)
.arg("--log-level", "WARNING", process::log_quiet)
.arg("--no-warn-unused-cli")
.arg(g.get_arch(arch_));
.arg("--no-warn-unused-cli");
if (genstring_.empty())
{
process_
.arg("-G", "\"" + g.name + "\"")
.arg(g.get_arch(arch_));
}
else
{
process_
.arg("-G", "\"" + genstring_ + "\"");
}
if (!prefix_.empty())
process_.arg("-DCMAKE_INSTALL_PREFIX=", prefix_, process::nospace);
if (cmd_.empty())
process_.arg("..");
else
process_.arg(cmd_);
process_
.arg("..")
.env(env::vs(arch_)
.set("CXXFLAGS", "/wd4566"))
.cwd(output_);
@@ -118,7 +152,7 @@ const std::map<cmake::generators, cmake::gen_info>& cmake::all_generators()
"Visual Studio " + vs::version() + " " + vs::year(),
"Win32",
"x64"
}}
}}
};
return map;
+5
View File
@@ -223,12 +223,15 @@ public:
static void clean(const context& cx, const fs::path& root);
cmake& generator(generators g);
cmake& generator(const std::string& g);
cmake& root(const fs::path& p);
cmake& output(const fs::path& p);
cmake& prefix(const fs::path& s);
cmake& def(const std::string& name, const std::string& value);
cmake& def(const std::string& name, const fs::path& p);
cmake& def(const std::string& name, const char* s);
cmake& architecture(arch a);
cmake& cmd(const std::string& s);
fs::path result() const;
@@ -249,9 +252,11 @@ private:
fs::path root_;
generators gen_;
std::string genstring_;
fs::path prefix_;
fs::path output_;
arch arch_;
std::string cmd_;
static const std::map<generators, gen_info>& all_generators();
static const gen_info& get_generator(generators g);