diff options
-rw-r--r-- | common/project.cc | 62 | ||||
-rw-r--r-- | common/project.h | 5 | ||||
-rw-r--r-- | ecp5/project.cc | 2 | ||||
-rw-r--r-- | generic/project.cc | 2 | ||||
-rw-r--r-- | gui/ecp5/mainwindow.h | 1 | ||||
-rw-r--r-- | gui/ice40/mainwindow.cc | 2 | ||||
-rw-r--r-- | ice40/main.cc | 5 | ||||
-rw-r--r-- | ice40/pcf.cc | 3 | ||||
-rw-r--r-- | ice40/pcf.h | 2 | ||||
-rw-r--r-- | ice40/project.cc | 10 | ||||
-rw-r--r-- | json/jsonparse.cc | 1 |
11 files changed, 68 insertions, 27 deletions
diff --git a/common/project.cc b/common/project.cc index 244ca761..949f6878 100644 --- a/common/project.cc +++ b/common/project.cc @@ -26,19 +26,53 @@ NEXTPNR_NAMESPACE_BEGIN +boost::filesystem::path make_relative(boost::filesystem::path child, boost::filesystem::path parent) +{ + boost::filesystem::path::const_iterator parentIter = parent.begin(); + boost::filesystem::path::const_iterator childIter = child.begin(); + + while (parentIter != parent.end() && childIter != child.end() && (*childIter) == (*parentIter)) { + ++childIter; + ++parentIter; + } + + boost::filesystem::path finalPath; + while (parentIter != parent.end()) { + finalPath /= ".."; + ++parentIter; + } + + while (childIter != child.end()) { + finalPath /= *childIter; + ++childIter; + } + + return finalPath; +} + void ProjectHandler::save(Context *ctx, std::string filename) { - std::ofstream f(filename); - pt::ptree root; - root.put("project.version", 1); - root.put("project.name", boost::filesystem::basename(filename)); - root.put("project.arch.name", ctx->archId().c_str(ctx)); - root.put("project.arch.type", ctx->archArgsToId(ctx->archArgs()).c_str(ctx)); - /* root.put("project.input.json", );*/ - root.put("project.params.freq", int(ctx->target_freq / 1e6)); - root.put("project.params.seed", ctx->rngstate); - saveArch(ctx, root); - pt::write_json(f, root); + try { + boost::filesystem::path proj(filename); + std::ofstream f(filename); + pt::ptree root; + + log_info("Saving project %s...\n", filename.c_str()); + log_break(); + + root.put("project.version", 1); + root.put("project.name", boost::filesystem::basename(filename)); + root.put("project.arch.name", ctx->archId().c_str(ctx)); + root.put("project.arch.type", ctx->archArgsToId(ctx->archArgs()).c_str(ctx)); + std::string fn = ctx->settings[ctx->id("project/input/json")]; + root.put("project.input.json", make_relative(fn, proj.parent_path()).string()); + root.put("project.params.freq", int(ctx->target_freq / 1e6)); + root.put("project.params.seed", ctx->rngstate); + saveArch(ctx, root, proj.parent_path().string()); + pt::write_json(f, root); + } catch (...) { + log_error("Error saving project file.\n"); + } } std::unique_ptr<Context> ProjectHandler::load(std::string filename) @@ -63,10 +97,10 @@ std::unique_ptr<Context> ProjectHandler::load(std::string filename) auto project = root.get_child("project"); auto input = project.get_child("input"); - std::string filename = input.get<std::string>("json"); - boost::filesystem::path json = proj.parent_path() / filename; + std::string fn = input.get<std::string>("json"); + boost::filesystem::path json = proj.parent_path() / fn; std::ifstream f(json.string()); - if (!parse_json_file(f, filename, ctx.get())) + if (!parse_json_file(f, fn, ctx.get())) log_error("Loading design failed.\n"); if (project.count("params")) { diff --git a/common/project.h b/common/project.h index 14f03ecd..03b4b7b5 100644 --- a/common/project.h +++ b/common/project.h @@ -20,6 +20,7 @@ #ifndef PROJECT_H #define PROJECT_H +#include <boost/filesystem/convenience.hpp> #include <boost/property_tree/ptree.hpp> #include "nextpnr.h" @@ -32,11 +33,13 @@ struct ProjectHandler void save(Context *ctx, std::string filename); std::unique_ptr<Context> load(std::string filename); // implemented per arch - void saveArch(Context *ctx, pt::ptree &root); + void saveArch(Context *ctx, pt::ptree &root, std::string path); std::unique_ptr<Context> createContext(pt::ptree &root); void loadArch(Context *ctx, pt::ptree &root, std::string path); }; +boost::filesystem::path make_relative(boost::filesystem::path child, boost::filesystem::path parent); + NEXTPNR_NAMESPACE_END #endif // PROJECT_H diff --git a/ecp5/project.cc b/ecp5/project.cc index 6c1f6a94..bca21643 100644 --- a/ecp5/project.cc +++ b/ecp5/project.cc @@ -25,7 +25,7 @@ NEXTPNR_NAMESPACE_BEGIN -void ProjectHandler::saveArch(Context *ctx, pt::ptree &root) +void ProjectHandler::saveArch(Context *ctx, pt::ptree &root, std::string path) { root.put("project.arch.package", ctx->archArgs().package); root.put("project.arch.speed", ctx->archArgs().speed); diff --git a/generic/project.cc b/generic/project.cc index 8103e91f..342fcac3 100644 --- a/generic/project.cc +++ b/generic/project.cc @@ -24,7 +24,7 @@ NEXTPNR_NAMESPACE_BEGIN -void ProjectHandler::saveArch(Context *ctx, pt::ptree &root) {} +void ProjectHandler::saveArch(Context *ctx, pt::ptree &root, std::string path) {} std::unique_ptr<Context> ProjectHandler::createContext(pt::ptree &root) { diff --git a/gui/ecp5/mainwindow.h b/gui/ecp5/mainwindow.h index aa1af17b..f85c2abc 100644 --- a/gui/ecp5/mainwindow.h +++ b/gui/ecp5/mainwindow.h @@ -52,7 +52,6 @@ class MainWindow : public BaseMainWindow ArchArgs chipArgs;
- std::string currentProj;
std::string currentBaseConfig;
};
diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc index 35ad5768..bf6e4b4c 100644 --- a/gui/ice40/mainwindow.cc +++ b/gui/ice40/mainwindow.cc @@ -150,7 +150,7 @@ void MainWindow::load_pcf(std::string filename) disableActions();
currentPCF = filename;
std::ifstream f(filename);
- if (apply_pcf(ctx.get(), f)) {
+ if (apply_pcf(ctx.get(), filename, f)) {
log("Loading PCF successful.\n");
actionPack->setEnabled(true);
} else {
diff --git a/ice40/main.cc b/ice40/main.cc index 2818a3ad..8bab360d 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -79,8 +79,9 @@ void Ice40CommandHandler::validate() void Ice40CommandHandler::customAfterLoad(Context *ctx) { if (vm.count("pcf")) { - std::ifstream pcf(vm["pcf"].as<std::string>()); - if (!apply_pcf(ctx, pcf)) + std::string filename = vm["pcf"].as<std::string>(); + std::ifstream pcf(filename); + if (!apply_pcf(ctx, filename, pcf)) log_error("Loading PCF failed.\n"); } } diff --git a/ice40/pcf.cc b/ice40/pcf.cc index 410fa1c9..d9fc4e68 100644 --- a/ice40/pcf.cc +++ b/ice40/pcf.cc @@ -27,7 +27,7 @@ NEXTPNR_NAMESPACE_BEGIN // Read a w // Apply PCF constraints to a pre-packing design -bool apply_pcf(Context *ctx, std::istream &in) +bool apply_pcf(Context *ctx, std::string filename, std::istream &in) { try { if (!in) @@ -66,6 +66,7 @@ bool apply_pcf(Context *ctx, std::istream &in) log_error("unsupported pcf command '%s'\n", cmd.c_str()); } } + ctx->settings.emplace(ctx->id("project/input/pcf"), filename); return true; } catch (log_execution_error_exception) { return false; diff --git a/ice40/pcf.h b/ice40/pcf.h index 315f6270..ecc81e59 100644 --- a/ice40/pcf.h +++ b/ice40/pcf.h @@ -27,7 +27,7 @@ NEXTPNR_NAMESPACE_BEGIN // Apply PCF constraints to a pre-packing design -bool apply_pcf(Context *ctx, std::istream &in); +bool apply_pcf(Context *ctx, std::string filename, std::istream &in); NEXTPNR_NAMESPACE_END diff --git a/ice40/project.cc b/ice40/project.cc index d1f1674a..8ca10e36 100644 --- a/ice40/project.cc +++ b/ice40/project.cc @@ -25,11 +25,13 @@ NEXTPNR_NAMESPACE_BEGIN -void ProjectHandler::saveArch(Context *ctx, pt::ptree &root) +void ProjectHandler::saveArch(Context *ctx, pt::ptree &root, std::string path) { root.put("project.arch.package", ctx->archArgs().package); - // if(!pcfFilename.empty()) - // root.put("project.input.pcf", pcfFilename); + if (ctx->settings.find(ctx->id("project/input/pcf")) != ctx->settings.end()) { + std::string fn = ctx->settings[ctx->id("project/input/pcf")]; + root.put("project.input.pcf", make_relative(fn, path).string()); + } } std::unique_ptr<Context> ProjectHandler::createContext(pt::ptree &root) @@ -64,7 +66,7 @@ void ProjectHandler::loadArch(Context *ctx, pt::ptree &root, std::string path) auto input = root.get_child("project").get_child("input"); boost::filesystem::path pcf = boost::filesystem::path(path) / input.get<std::string>("pcf"); std::ifstream f(pcf.string()); - if (!apply_pcf(ctx, f)) + if (!apply_pcf(ctx, input.get<std::string>("pcf"), f)) log_error("Loading PCF failed.\n"); } diff --git a/json/jsonparse.cc b/json/jsonparse.cc index 89c2b8d9..9e86f93e 100644 --- a/json/jsonparse.cc +++ b/json/jsonparse.cc @@ -754,6 +754,7 @@ bool parse_json_file(std::istream &f, std::string &filename, Context *ctx) log_info("Checksum: 0x%08x\n", ctx->checksum()); log_break(); + ctx->settings.emplace(ctx->id("project/input/json"), filename); return true; } catch (log_execution_error_exception) { return false; |