aboutsummaryrefslogtreecommitdiffstats
path: root/icetime
diff options
context:
space:
mode:
authorNathan Rossi <nathan@nathanrossi.com>2018-09-03 22:50:03 +1000
committerNathan Rossi <nathan@nathanrossi.com>2018-09-03 23:11:26 +1000
commitc1c13f3b3e14a392fbfbb63add2d55aa642f6018 (patch)
treec15605b695f68208ed9939c042135fcf1a5f3496 /icetime
parent3681ade2c7bfb2e4befee1ff6909608752f91d92 (diff)
downloadicestorm-c1c13f3b3e14a392fbfbb63add2d55aa642f6018.tar.gz
icestorm-c1c13f3b3e14a392fbfbb63add2d55aa642f6018.tar.bz2
icestorm-c1c13f3b3e14a392fbfbb63add2d55aa642f6018.zip
icetime: Add support for searching for chipdb relative to binary
Like yosys and arachne-pnr, allow for searching for the desired chipdb file relative to the executing binaries directory. This allows for portable builds of icetime without needing to specify the exact path to the needed chipdb file with the -C arg. In order to support this icetime must be able to get the "proc_self_dirname" path just like yosys and arachne-pnr. As such copy the equivalent code to get this path information. To avoid cluttering the icetime.cc file with this code, place it in a separate iceutil.cc file. Signed-off-by: Nathan Rossi <nathan@nathanrossi.com>
Diffstat (limited to 'icetime')
-rw-r--r--icetime/Makefile3
-rw-r--r--icetime/icetime.cc33
-rw-r--r--icetime/iceutil.cc179
3 files changed, 190 insertions, 25 deletions
diff --git a/icetime/Makefile b/icetime/Makefile
index d260681..b1cd18d 100644
--- a/icetime/Makefile
+++ b/icetime/Makefile
@@ -26,10 +26,11 @@ share/$(CHIPDB_SUBDIR)/chipdb-5k.txt: ../icebox/chipdb-5k.txt
override LDFLAGS += --embed-file share
endif
-icetime$(EXE): icetime.o
+icetime$(EXE): icetime.o iceutil.o
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
icetime.o: icetime.cc timings.inc
+iceutil.o: iceutil.cc
timings.inc: timings.py ../icefuzz/timings_*.txt
python3 timings.py > timings.inc.new
diff --git a/icetime/icetime.cc b/icetime/icetime.cc
index 35ce99a..16ad142 100644
--- a/icetime/icetime.cc
+++ b/icetime/icetime.cc
@@ -38,6 +38,8 @@
#include <emscripten.h>
#endif
+std::string find_chipdb(std::string config_device);
+
// add this number of ns as estimate for clock distribution mismatch
#define GLOBAL_CLK_DIST_JITTER 0.1
@@ -322,35 +324,18 @@ void read_config()
void read_chipdb()
{
char buffer[1024];
+ std::string filepath = chipdbfile;
- if (!chipdbfile.empty()) {
- snprintf(buffer, 1024, "%s", chipdbfile.c_str());
- } else
- if (PREFIX[0] == '~' && PREFIX[1] == '/') {
- std::string homedir;
-#ifdef _WIN32
- if (getenv("USERPROFILE") != nullptr) {
- homedir += getenv("USERPROFILE");
- }
- else {
- if (getenv("HOMEDRIVE") != nullptr &&
- getenv("HOMEPATH") != nullptr) {
- homedir += getenv("HOMEDRIVE");
- homedir += getenv("HOMEPATH");
- }
- }
-#else
- homedir += getenv("HOME");
-#endif
- snprintf(buffer, 1024, "%s%s/share/" CHIPDB_SUBDIR "/chipdb-%s.txt", homedir.c_str(), PREFIX+1, config_device.c_str());
- } else {
- snprintf(buffer, 1024, PREFIX "/share/" CHIPDB_SUBDIR "/chipdb-%s.txt", config_device.c_str());
+ if (filepath.empty())
+ filepath = find_chipdb(config_device);
+ if (filepath.empty()) {
+ fprintf(stderr, "Can't find chipdb file for device %s\n", config_device.c_str());
+ exit(1);
}
- FILE *fdb = fopen(buffer, "r");
+ FILE *fdb = fopen(filepath.c_str(), "r");
if (fdb == nullptr) {
perror("Can't open chipdb file");
- fprintf(stderr, " %s\n", buffer);
exit(1);
}
diff --git a/icetime/iceutil.cc b/icetime/iceutil.cc
new file mode 100644
index 0000000..ad8d662
--- /dev/null
+++ b/icetime/iceutil.cc
@@ -0,0 +1,179 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include <errno.h>
+#include <string>
+#include <sstream>
+#include <cstring>
+
+#ifdef _WIN32
+# include <windows.h>
+# include <io.h>
+#elif defined(__APPLE__)
+# include <mach-o/dyld.h>
+# include <unistd.h>
+#else
+# include <unistd.h>
+#endif
+
+#ifdef __FreeBSD__
+# include <sys/sysctl.h>
+#endif
+
+#include <limits.h>
+
+#if defined(__linux__) || defined(__CYGWIN__)
+std::string proc_self_dirname()
+{
+ char path[PATH_MAX];
+ ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path));
+ if (buflen < 0) {
+ fprintf(stderr, "fatal error: readlink(\"/proc/self/exe\") failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ while (buflen > 0 && path[buflen-1] != '/')
+ buflen--;
+ return std::string(path, buflen);
+}
+#elif defined(__FreeBSD__)
+std::string proc_self_dirname()
+{
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
+ size_t buflen;
+ char *buffer;
+ std::string path;
+ if (sysctl(mib, 4, NULL, &buflen, NULL, 0) != 0) {
+ fprintf(stderr, "fatal error: sysctl failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ buffer = (char*)malloc(buflen);
+ if (buffer == NULL) {
+ fprintf(stderr, "fatal error: malloc failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ if (sysctl(mib, 4, buffer, &buflen, NULL, 0) != 0) {
+ fprintf(stderr, "fatal error: sysctl failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ while (buflen > 0 && buffer[buflen-1] != '/')
+ buflen--;
+ path.assign(buffer, buflen);
+ free(buffer);
+ return path;
+}
+#elif defined(__APPLE__)
+std::string proc_self_dirname()
+{
+ char *path = NULL;
+ uint32_t buflen = 0;
+ while (_NSGetExecutablePath(path, &buflen) != 0)
+ path = (char *) realloc((void *) path, buflen);
+ while (buflen > 0 && path[buflen-1] != '/')
+ buflen--;
+ return std::string(path, buflen);
+}
+#elif defined(_WIN32)
+std::string proc_self_dirname()
+{
+ int i = 0;
+# ifdef __MINGW32__
+ char longpath[MAX_PATH + 1];
+ char shortpath[MAX_PATH + 1];
+# else
+ WCHAR longpath[MAX_PATH + 1];
+ TCHAR shortpath[MAX_PATH + 1];
+# endif
+ if (!GetModuleFileName(0, longpath, MAX_PATH+1)) {
+ fprintf(stderr, "fatal error: GetModuleFileName() failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ if (!GetShortPathName(longpath, shortpath, MAX_PATH+1)) {
+ fprintf(stderr, "fatal error: GetShortPathName() failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ while (shortpath[i] != 0)
+ i++;
+ while (i > 0 && shortpath[i-1] != '/' && shortpath[i-1] != '\\')
+ shortpath[--i] = 0;
+ std::string path;
+ for (i = 0; shortpath[i]; i++)
+ path += char(shortpath[i]);
+ return path;
+}
+#elif defined(EMSCRIPTEN)
+std::string proc_self_dirname()
+{
+ return "/";
+}
+#else
+ #error Dont know how to determine process executable base path!
+#endif
+
+bool file_test_open(std::string path)
+{
+ FILE *fdb = fopen(path.c_str(), "r");
+ if (fdb == nullptr) {
+ return false;
+ }
+ fclose(fdb);
+ return true;
+}
+
+extern bool verbose;
+
+std::string find_chipdb(std::string config_device)
+{
+ if (PREFIX[0] == '~' && PREFIX[1] == '/') {
+ std::string homepath;
+#ifdef _WIN32
+ if (getenv("USERPROFILE") != nullptr) {
+ homepath += getenv("USERPROFILE");
+ }
+ else {
+ if (getenv("HOMEDRIVE") != nullptr &&
+ getenv("HOMEPATH") != nullptr) {
+ homepath += getenv("HOMEDRIVE");
+ homepath += getenv("HOMEPATH");
+ }
+ }
+#else
+ homepath += getenv("HOME");
+#endif
+ homepath += std::string(PREFIX + 1) + "/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
+ if (verbose)
+ fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), homepath.c_str());
+ if (file_test_open(homepath))
+ return homepath;
+ }
+
+ std::string prefixpath = PREFIX "/share/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
+ if (verbose)
+ fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), prefixpath.c_str());
+ if (file_test_open(prefixpath))
+ return prefixpath;
+
+ std::string relbinarypath = proc_self_dirname() + "../share/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt";
+ if (verbose)
+ fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), relbinarypath.c_str());
+ if (file_test_open(relbinarypath))
+ return relbinarypath;
+
+ return "";
+}
+