diff options
author | Clifford Wolf <clifford@clifford.at> | 2018-10-30 11:28:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-30 11:28:34 +0100 |
commit | 90f0e40cb849e076a08bc9b6fdcd05899f88eeae (patch) | |
tree | e78f9e337b2bf890adee7bed1795bf9177819f29 /icetime | |
parent | 8f738342bc32e4fd0233f52a5282b4a1bfc72ba2 (diff) | |
parent | c1c13f3b3e14a392fbfbb63add2d55aa642f6018 (diff) | |
download | icestorm-90f0e40cb849e076a08bc9b6fdcd05899f88eeae.tar.gz icestorm-90f0e40cb849e076a08bc9b6fdcd05899f88eeae.tar.bz2 icestorm-90f0e40cb849e076a08bc9b6fdcd05899f88eeae.zip |
Merge pull request #184 from nathanrossi/nrossi/portable-chipdb
icetime: Add support for searching for chipdb relative to binary
Diffstat (limited to 'icetime')
-rw-r--r-- | icetime/Makefile | 3 | ||||
-rw-r--r-- | icetime/icetime.cc | 33 | ||||
-rw-r--r-- | icetime/iceutil.cc | 179 |
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 c49e2e2..a5a27a0 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 ""; +} + |