168 lines
5.1 KiB
C++
168 lines
5.1 KiB
C++
#include "vs_json.h"
|
|
|
|
#include <fstream>
|
|
#include <list>
|
|
#include <set>
|
|
|
|
JsonCommand::JsonCommand() = default;
|
|
JsonCommand::~JsonCommand() = default;
|
|
|
|
void JsonCommand::set_expect(const std::string& exp) { expect_ = exp; }
|
|
void JsonCommand::set_out(const std::string& out) { out_ = out; }
|
|
|
|
bool JsonCommand::generate(const std::vector<ProjectInfo>& projs) {
|
|
Json::Value json_root{};
|
|
for (const auto& item : projs) {
|
|
const auto& cpps = get_cpp_paths(item.proj_root_);
|
|
std::string command = get_command(&item, projs);
|
|
for (const auto& cpp : cpps) {
|
|
Json::Value jsn{};
|
|
jsn["directory"] = item.proj_root_;
|
|
jsn["command"] = command + " -c " + cpp; // NOLINT
|
|
jsn["file"] = cpp;
|
|
json_root.append(jsn);
|
|
}
|
|
}
|
|
std::ofstream jsf(out_, std::ios::out);
|
|
if (!jsf.is_open()) {
|
|
std::cout << "不能打开文件:" << std::endl;
|
|
return false;
|
|
}
|
|
jsf << json_root.toStyledString();
|
|
jsf.close();
|
|
return true;
|
|
}
|
|
|
|
std::string JsonCommand::get_command(const ProjectInfo* proj,
|
|
const std::vector<ProjectInfo>& projs) {
|
|
std::string result{};
|
|
result.append(
|
|
R"("C:\PROGRA~2\Microsoft Visual Studio 14.0\VC\bin\amd64\cl.exe")");
|
|
|
|
std::string co_include = proj->addtion_;
|
|
std::string co_predefinitions = proj->predefinition_;
|
|
|
|
std::string speciaA("$(IncludePath)");
|
|
std::string speciaB("%(PreprocessorDefinitions)");
|
|
std::string speciaC("%(AdditionalIncludeDirectories)");
|
|
std::string speciaD("$(WindowsSDK_IncludePath)");
|
|
std::string speciaE("$(VC_IncludePath)");
|
|
|
|
replaceAll(co_include, speciaA, "");
|
|
replaceAll(co_include, speciaC, "");
|
|
replaceAll(co_include, speciaD, "");
|
|
replaceAll(co_include, speciaE, "");
|
|
replaceAll(co_predefinitions, speciaB, "");
|
|
|
|
auto include_vec = split(co_include, ";");
|
|
auto prede_vec = split(co_predefinitions, ";");
|
|
|
|
for (const auto& str : prede_vec) {
|
|
if (str.empty()) {
|
|
continue;
|
|
}
|
|
result.append(" -D" + str);
|
|
}
|
|
|
|
for (const auto& str : include_vec) {
|
|
if (str.empty()) {
|
|
continue;
|
|
}
|
|
if (expect_.find(str) != std::string::npos) {
|
|
continue;
|
|
}
|
|
result.append(" -I" + fs::path(proj->proj_root_).append(str).string());
|
|
}
|
|
|
|
std::list<std::string> proj_list{};
|
|
std::vector<std::string> re_relate{};
|
|
auto handle = [&](const std::vector<std::string>& lrelate) {
|
|
for (const auto& str : lrelate) {
|
|
proj_list.push_back(str);
|
|
}
|
|
};
|
|
|
|
for (const auto& str : proj->guid_relate_) {
|
|
// 这里的relate 子项目有别的依赖的话都需要加上
|
|
// 这里假定不会出现循环引用的情况 (理论也不应该出现)
|
|
for (const auto& pj : projs) {
|
|
if (pj.guid_ == str) {
|
|
handle(pj.guid_relate_);
|
|
re_relate.push_back(pj.path_);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//std::string dir = fs::path(str).parent_path().string();
|
|
//result.append(" -I" + dir);
|
|
}
|
|
|
|
while (!proj_list.empty()) {
|
|
std::string& data = proj_list.front();
|
|
for (const auto& pj : projs) {
|
|
if (data == pj.guid_) {
|
|
handle(pj.guid_relate_);
|
|
re_relate.push_back(pj.path_);
|
|
break;
|
|
}
|
|
}
|
|
proj_list.pop_front();
|
|
}
|
|
|
|
// 去重
|
|
std::set<std::string> no_reply{};
|
|
for (const auto& str : re_relate) {
|
|
no_reply.insert(str);
|
|
}
|
|
for (const auto& str : no_reply) {
|
|
std::string dir = fs::path(str).parent_path().string();
|
|
result.append(" -I" + dir);
|
|
}
|
|
|
|
// std::cout << result << std::endl;
|
|
return result;
|
|
}
|
|
|
|
std::vector<std::string> JsonCommand::split(const std::string& source,
|
|
const std::string& sep) {
|
|
std::vector<std::string> tokens;
|
|
std::size_t start = 0;
|
|
std::size_t end = 0;
|
|
|
|
while ((end = source.find(sep, start)) != std::string::npos) {
|
|
tokens.push_back(source.substr(start, end - start));
|
|
start = end + sep.length();
|
|
}
|
|
|
|
tokens.push_back(source.substr(start));
|
|
return tokens;
|
|
}
|
|
|
|
std::vector<std::string> JsonCommand::get_cpp_paths(
|
|
const std::string& parent_path) {
|
|
std::vector<std::string> vec{};
|
|
try {
|
|
for (const auto& entry : fs::directory_iterator(parent_path)) {
|
|
if (!fs::is_regular_file(entry.path())) {
|
|
continue;
|
|
}
|
|
const fs::path& file_path(entry.path());
|
|
if (file_path.extension().string() == ".cpp") {
|
|
vec.push_back(file_path.string());
|
|
}
|
|
}
|
|
} catch (fs::filesystem_error& e) {
|
|
std::cout << "Error: " << e.what() << std::endl;
|
|
}
|
|
return vec;
|
|
}
|
|
|
|
void JsonCommand::replaceAll(std::string& str, const std::string& from,
|
|
const std::string& to) {
|
|
size_t start_pos = 0;
|
|
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
|
str.replace(start_pos, from.length(), to);
|
|
start_pos += to.length();
|
|
}
|
|
}
|