mirror of
https://github.com/Relintai/osxcross.git
synced 2025-02-03 22:45:56 +01:00
fix for #34
This commit is contained in:
parent
bae6ac72cd
commit
f5aaf9faf9
@ -4,6 +4,7 @@ changed:
|
|||||||
* improved and colorized wrapper error/warning/debug/info messages
|
* improved and colorized wrapper error/warning/debug/info messages
|
||||||
|
|
||||||
added:
|
added:
|
||||||
|
* support for ccache symlinks
|
||||||
* darling-dmg sdk packaging script
|
* darling-dmg sdk packaging script
|
||||||
* include path warnings for /usr/include and /usr/local/include
|
* include path warnings for /usr/include and /usr/local/include
|
||||||
(can be switched off via 'OSXCROSS_NO_INCLUDE_PATH_WARNINGS=1')
|
(can be switched off via 'OSXCROSS_NO_INCLUDE_PATH_WARNINGS=1')
|
||||||
|
@ -12,11 +12,11 @@ Also ensure that you are using the 10.6 SDK (or later).
|
|||||||
|
|
||||||
### INSTALLATION: ###
|
### INSTALLATION: ###
|
||||||
|
|
||||||
Run OSXCross's `./build.sh`, then you should have `osxcross-macports` in PATH.
|
Run OSXCross' `./build.sh`, then you should have `osxcross-macports` in PATH.
|
||||||
|
|
||||||
**Setting up osxcross-macports:**
|
**Setting up osxcross-macports:**
|
||||||
|
|
||||||
MacPorts doesn't support 10.5 anymore, so we need to change OSXCross's
|
MacPorts doesn't support 10.5 anymore, so we need to change OSXCross'
|
||||||
default target to 10.6 (better 10.7, or later).
|
default target to 10.6 (better 10.7, or later).
|
||||||
|
|
||||||
To achive this, add the following to your bashrc (or similar):
|
To achive this, add the following to your bashrc (or similar):
|
||||||
@ -35,7 +35,7 @@ Then run `osxcross-macports <cmd>`.
|
|||||||
|
|
||||||
**pkg-config:**
|
**pkg-config:**
|
||||||
|
|
||||||
OSXCross's `pkg-config` (`<arch>-apple-darwinXX-pkg-config`)
|
OSXCross' `pkg-config` (`<arch>-apple-darwinXX-pkg-config`)
|
||||||
is automatically aware of MacPorts packages.
|
is automatically aware of MacPorts packages.
|
||||||
|
|
||||||
If you want `pkg-config` to be unaware of MacPorts packages
|
If you want `pkg-config` to be unaware of MacPorts packages
|
||||||
|
54
wrapper/main.cpp
Executable file → Normal file
54
wrapper/main.cpp
Executable file → Normal file
@ -51,15 +51,11 @@ namespace {
|
|||||||
|
|
||||||
int unittest = 0;
|
int unittest = 0;
|
||||||
|
|
||||||
//
|
|
||||||
// detectTarget():
|
|
||||||
// detect target and setup invocation command
|
|
||||||
//
|
|
||||||
|
|
||||||
void checkIncludePath(const char *opt, const char *path) {
|
void checkIncludePath(const char *opt, const char *path) {
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
constexpr const char *DangerousIncludePaths[] = { "/usr/include",
|
constexpr const char *DangerousIncludePaths[] = { "/usr/include",
|
||||||
"/usr/local/include" };
|
"/usr/local/include" };
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -108,6 +104,11 @@ void warnExtension(const char *extension) {
|
|||||||
<< "'OSXCROSS_NO_EXTENSION_WARNINGS=1' (env)" << warninfo.endl();
|
<< "'OSXCROSS_NO_EXTENSION_WARNINGS=1' (env)" << warninfo.endl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// detectTarget():
|
||||||
|
// detect target and setup invocation command
|
||||||
|
//
|
||||||
|
|
||||||
#define PABREAK \
|
#define PABREAK \
|
||||||
else target.args.push_back(arg); \
|
else target.args.push_back(arg); \
|
||||||
break
|
break
|
||||||
@ -409,16 +410,17 @@ bool detectTarget(int argc, char **argv, Target &target) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto checkCXXLib = [&]() {
|
auto checkCXXLib = [&]() {
|
||||||
if (target.compiler.size() <= 7)
|
if (target.compilername.size() <= 7)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (target.compiler.rfind("-libc++") == (target.compiler.size() - 7)) {
|
if (target.compilername.rfind("-libc++") ==
|
||||||
|
(target.compilername.size() - 7)) {
|
||||||
if (target.stdlib != StdLib::unset && target.stdlib != StdLib::libcxx) {
|
if (target.stdlib != StdLib::unset && target.stdlib != StdLib::libcxx) {
|
||||||
warn << "'-stdlib=" << getStdLibString(target.stdlib)
|
warn << "'-stdlib=" << getStdLibString(target.stdlib)
|
||||||
<< "' will be ignored" << warn.endl();
|
<< "' will be ignored" << warn.endl();
|
||||||
}
|
}
|
||||||
|
|
||||||
target.compiler.resize(target.compiler.size() - 7);
|
target.compilername.resize(target.compilername.size() - 7);
|
||||||
target.stdlib = StdLib::libcxx;
|
target.stdlib = StdLib::libcxx;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -452,13 +454,13 @@ bool detectTarget(int argc, char **argv, Target &target) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
target.target = std::string(cmd, p - cmd);
|
target.target = std::string(cmd, p - cmd);
|
||||||
target.compiler = &p[1];
|
target.compilername = &p[1];
|
||||||
|
|
||||||
if (target.compiler == "cc")
|
if (target.compilername == "cc")
|
||||||
target.compiler = getDefaultCompiler();
|
target.compilername = getDefaultCompiler();
|
||||||
else if (target.compiler == "c++")
|
else if (target.compilername == "c++")
|
||||||
target.compiler = getDefaultCXXCompiler();
|
target.compilername = getDefaultCXXCompiler();
|
||||||
else if (auto *prog = program::getprog(target.compiler))
|
else if (auto *prog = program::getprog(target.compilername))
|
||||||
(*prog)(argc, argv, target);
|
(*prog)(argc, argv, target);
|
||||||
|
|
||||||
if (target.target != getDefaultTarget()) {
|
if (target.target != getDefaultTarget()) {
|
||||||
@ -484,7 +486,7 @@ bool detectTarget(int argc, char **argv, Target &target) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (const char *p = strchr(cmd, '-'))
|
if (const char *p = strchr(cmd, '-'))
|
||||||
target.compiler = &cmd[p - cmd + 1];
|
target.compilername = &cmd[p - cmd + 1];
|
||||||
|
|
||||||
if (!parseArgs())
|
if (!parseArgs())
|
||||||
return false;
|
return false;
|
||||||
@ -681,10 +683,10 @@ void generateMultiArchObjectFile(int &rc, int argc, char **argv, Target &target,
|
|||||||
lipo += getDefaultTarget();
|
lipo += getDefaultTarget();
|
||||||
lipo += "-lipo";
|
lipo += "-lipo";
|
||||||
|
|
||||||
if (getPathOfCommand(lipo.c_str(), path).empty()) {
|
if (!getPathOfCommand(lipo.c_str(), path)) {
|
||||||
lipo = "lipo";
|
lipo = "lipo";
|
||||||
|
|
||||||
if (getPathOfCommand(lipo.c_str(), path).empty()) {
|
if (!getPathOfCommand(lipo.c_str(), path)) {
|
||||||
err << "cannot find lipo binary" << err.endl();
|
err << "cannot find lipo binary" << err.endl();
|
||||||
rc = 1;
|
rc = 1;
|
||||||
}
|
}
|
||||||
@ -759,7 +761,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (debug >= 2) {
|
if (debug >= 2) {
|
||||||
dbg << "detected target triple: " << target.getTriple() << dbg.endl();
|
dbg << "detected target triple: " << target.getTriple() << dbg.endl();
|
||||||
dbg << "detected compiler: " << target.compiler << dbg.endl();
|
dbg << "detected compiler: " << target.compilername << dbg.endl();
|
||||||
|
|
||||||
dbg << "detected stdlib: " << getStdLibString(target.stdlib)
|
dbg << "detected stdlib: " << getStdLibString(target.stdlib)
|
||||||
<< dbg.endl();
|
<< dbg.endl();
|
||||||
@ -789,8 +791,18 @@ int main(int argc, char **argv) {
|
|||||||
in += " ";
|
in += " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &arg : target.fargs) {
|
out += target.compilerpath;
|
||||||
out += arg;
|
|
||||||
|
if (target.compilerpath != target.fargs[0]) {
|
||||||
|
out += " (";
|
||||||
|
out += target.fargs[0];
|
||||||
|
out += ") ";
|
||||||
|
} else {
|
||||||
|
out += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < target.fargs.size(); ++i) {
|
||||||
|
out += target.fargs[i];
|
||||||
out += " ";
|
out += " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,7 +843,7 @@ int main(int argc, char **argv) {
|
|||||||
if (unittest == 2)
|
if (unittest == 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (rc == -1 && execvp(cargs[0], cargs)) {
|
if (rc == -1 && execvp(target.compilerpath.c_str(), cargs)) {
|
||||||
err << "invoking compiler failed" << err.endl();
|
err << "invoking compiler failed" << err.endl();
|
||||||
|
|
||||||
if (!debug)
|
if (!debug)
|
||||||
|
0
wrapper/programs/osxcross-env.cpp
Executable file → Normal file
0
wrapper/programs/osxcross-env.cpp
Executable file → Normal file
0
wrapper/programs/osxcross-version.cpp
Executable file → Normal file
0
wrapper/programs/osxcross-version.cpp
Executable file → Normal file
0
wrapper/programs/pkg-config.cpp
Executable file → Normal file
0
wrapper/programs/pkg-config.cpp
Executable file → Normal file
0
wrapper/programs/sw_vers.cpp
Executable file → Normal file
0
wrapper/programs/sw_vers.cpp
Executable file → Normal file
@ -156,11 +156,11 @@ bool Target::isC(bool r) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compiler.find("++") == std::string::npos && !isObjC(true);
|
return compilername.find("++") == std::string::npos && !isObjC(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Target::isCXX() {
|
bool Target::isCXX() {
|
||||||
bool CXXCompiler = compiler.find("++") != std::string::npos;
|
bool CXXCompiler = compilername.find("++") != std::string::npos;
|
||||||
|
|
||||||
if (!langGiven() && CXXCompiler && !isObjC(true))
|
if (!langGiven() && CXXCompiler && !isObjC(true))
|
||||||
return true;
|
return true;
|
||||||
@ -229,34 +229,37 @@ bool Target::isCXX11orNewer() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string Target::getFullCompilerName() const {
|
void Target::setCompilerPath() {
|
||||||
std::string compiler;
|
|
||||||
|
|
||||||
if (isGCC()) {
|
if (isGCC()) {
|
||||||
compiler = execpath;
|
compilerpath = execpath;
|
||||||
compiler += "/";
|
compilerpath += "/";
|
||||||
compiler += getTriple();
|
compilerpath += getTriple();
|
||||||
compiler += "-";
|
compilerpath += "-";
|
||||||
|
compilerpath += "base-";
|
||||||
|
compilerpath += compilername;
|
||||||
|
|
||||||
|
compilerexecname = getTriple();
|
||||||
|
compilerexecname += "-";
|
||||||
|
compilerexecname += compilername;
|
||||||
|
} else {
|
||||||
|
if (!realPath(compilername.c_str(), compilerpath, ignoreCCACHE))
|
||||||
|
compilerpath = compilername;
|
||||||
|
|
||||||
|
compilerexecname += compilername;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isGCC())
|
|
||||||
compiler += "base-";
|
|
||||||
|
|
||||||
compiler += this->compiler;
|
|
||||||
return compiler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Target::findClangIntrinsicHeaders(std::string &path) {
|
bool Target::findClangIntrinsicHeaders(std::string &path) {
|
||||||
std::string clangbin;
|
|
||||||
static std::stringstream dir;
|
static std::stringstream dir;
|
||||||
|
|
||||||
assert(isClang());
|
assert(isClang());
|
||||||
|
|
||||||
getPathOfCommand(compiler.c_str(), clangbin);
|
if (compilerpath.empty())
|
||||||
|
|
||||||
if (clangbin.empty())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
std::string clangbindir = compilerpath;
|
||||||
|
stripFileName(clangbindir);
|
||||||
|
|
||||||
static ClangVersion *clangversion;
|
static ClangVersion *clangversion;
|
||||||
static std::string pathtmp;
|
static std::string pathtmp;
|
||||||
|
|
||||||
@ -266,10 +269,8 @@ bool Target::findClangIntrinsicHeaders(std::string &path) {
|
|||||||
*clangversion = ClangVersion();
|
*clangversion = ClangVersion();
|
||||||
pathtmp.clear();
|
pathtmp.clear();
|
||||||
|
|
||||||
auto check = []()->bool {
|
auto tryDir = [&]()->bool {
|
||||||
|
|
||||||
listFiles(dir.str().c_str(), nullptr, [](const char *file) {
|
listFiles(dir.str().c_str(), nullptr, [](const char *file) {
|
||||||
|
|
||||||
if (file[0] != '.' && isDirectory(file, dir.str().c_str())) {
|
if (file[0] != '.' && isDirectory(file, dir.str().c_str())) {
|
||||||
ClangVersion cv = parseClangVersion(file);
|
ClangVersion cv = parseClangVersion(file);
|
||||||
|
|
||||||
@ -303,20 +304,36 @@ bool Target::findClangIntrinsicHeaders(std::string &path) {
|
|||||||
checkDir(tmp);
|
checkDir(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
return *clangversion != ClangVersion();
|
return *clangversion != ClangVersion();
|
||||||
};
|
};
|
||||||
|
|
||||||
dir << clangbin << "/../lib/clang";
|
#define TRYDIR(basedir, subdir) \
|
||||||
|
do { \
|
||||||
|
dir << basedir << subdir; \
|
||||||
|
if (tryDir()) { \
|
||||||
|
path.swap(pathtmp); \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
clear(dir); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
if (!check()) {
|
#define TRYDIR2(libdir) TRYDIR(clangbindir, libdir)
|
||||||
clear(dir);
|
#define TRYDIR3(libdir) TRYDIR(std::string(), libdir)
|
||||||
|
|
||||||
|
TRYDIR2("/../lib/clang");
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#ifdef __x86_64__
|
||||||
|
// opensuse uses lib64 instead of lib on x86_64
|
||||||
|
TRYDIR2("/../lib64/clang");
|
||||||
|
#elif __i386__
|
||||||
|
TRYDIR2("/../lib32/clang");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
constexpr const char *OSXIntrinDirs[] = {
|
constexpr const char *OSXIntrinDirs[] = {
|
||||||
@ -325,25 +342,17 @@ bool Target::findClangIntrinsicHeaders(std::string &path) {
|
|||||||
"XcodeDefault.xctoolchain/usr/lib/clang"
|
"XcodeDefault.xctoolchain/usr/lib/clang"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto intrindir : OSXIntrinDirs) {
|
for (auto intrindir : OSXIntrinDirs)
|
||||||
dir << intrindir;
|
TRYDIR3(intrindir);
|
||||||
if (check()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
clear(dir);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!dir.rdbuf()->in_avail()) {
|
TRYDIR2("/../include/clang");
|
||||||
dir << clangbin << "/../include/clang";
|
TRYDIR2("/usr/include/clang");
|
||||||
|
|
||||||
if (!check())
|
|
||||||
return false;
|
return false;
|
||||||
}
|
#undef TRYDIR
|
||||||
}
|
#undef TRYDIR2
|
||||||
|
#undef TRYDIR3
|
||||||
path.swap(pathtmp);
|
|
||||||
return *clangversion != ClangVersion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Target::setupGCCLibs(Arch arch) {
|
void Target::setupGCCLibs(Arch arch) {
|
||||||
@ -409,7 +418,7 @@ bool Target::setup() {
|
|||||||
OSVersion SDKOSNum = getSDKOSNum();
|
OSVersion SDKOSNum = getSDKOSNum();
|
||||||
|
|
||||||
if (!isKnownCompiler())
|
if (!isKnownCompiler())
|
||||||
warn << "unknown compiler '" << compiler << "'" << warn.endl();
|
warn << "unknown compiler '" << compilername << "'" << warn.endl();
|
||||||
|
|
||||||
if (!getSDKPath(SDKPath)) {
|
if (!getSDKPath(SDKPath)) {
|
||||||
err << "cannot find Mac OS X SDK (expected in: " << SDKPath << ")"
|
err << "cannot find Mac OS X SDK (expected in: " << SDKPath << ")"
|
||||||
@ -439,6 +448,8 @@ bool Target::setup() {
|
|||||||
otriple += "-";
|
otriple += "-";
|
||||||
otriple += target;
|
otriple += target;
|
||||||
|
|
||||||
|
setCompilerPath();
|
||||||
|
|
||||||
if (!OSNum.Num()) {
|
if (!OSNum.Num()) {
|
||||||
if (haveArch(Arch::x86_64h)) {
|
if (haveArch(Arch::x86_64h)) {
|
||||||
OSNum = OSVersion(10, 8); // Default to 10.8 for x86_64h
|
OSNum = OSVersion(10, 8); // Default to 10.8 for x86_64h
|
||||||
@ -569,7 +580,7 @@ bool Target::setup() {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
fargs.push_back(getFullCompilerName());
|
fargs.push_back(compilerexecname);
|
||||||
|
|
||||||
if (isClang()) {
|
if (isClang()) {
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
@ -585,7 +596,7 @@ bool Target::setup() {
|
|||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
if (!findClangIntrinsicHeaders(tmp)) {
|
if (!findClangIntrinsicHeaders(tmp)) {
|
||||||
warn << "cannot find clang intrinsic headers, please report this "
|
warn << "cannot find clang intrinsic headers; please report this "
|
||||||
"issue to the OSXCross project" << warn.endl();
|
"issue to the OSXCross project" << warn.endl();
|
||||||
} else {
|
} else {
|
||||||
fargs.push_back("-isystem");
|
fargs.push_back("-isystem");
|
||||||
|
@ -75,7 +75,7 @@ struct Target {
|
|||||||
Target()
|
Target()
|
||||||
: vendor(getDefaultVendor()), target(getDefaultTarget()),
|
: vendor(getDefaultVendor()), target(getDefaultTarget()),
|
||||||
stdlib(StdLib::unset), usegcclibs(), nocodegen(),
|
stdlib(StdLib::unset), usegcclibs(), nocodegen(),
|
||||||
compiler(getDefaultCompiler()), lang(), langstd(), sourcefile(),
|
compilername(getDefaultCompiler()), lang(), langstd(), sourcefile(),
|
||||||
outputname() {
|
outputname() {
|
||||||
if (!getExecutablePath(execpath, sizeof(execpath)))
|
if (!getExecutablePath(execpath, sizeof(execpath)))
|
||||||
abort();
|
abort();
|
||||||
@ -115,11 +115,11 @@ struct Target {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isClang() const {
|
bool isClang() const {
|
||||||
return !strncmp(getFileName(compiler.c_str()), "clang", 5);
|
return !strncmp(getFileName(compilername.c_str()), "clang", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isGCC() const {
|
bool isGCC() const {
|
||||||
const char *c = getFileName(compiler.c_str());
|
const char *c = getFileName(compilername.c_str());
|
||||||
return (!strncmp(c, "gcc", 3) || !strncmp(c, "g++", 3));
|
return (!strncmp(c, "gcc", 3) || !strncmp(c, "g++", 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ struct Target {
|
|||||||
|
|
||||||
const std::string &getTriple() const { return triple; }
|
const std::string &getTriple() const { return triple; }
|
||||||
|
|
||||||
const std::string getFullCompilerName() const;
|
void setCompilerPath();
|
||||||
bool findClangIntrinsicHeaders(std::string &path);
|
bool findClangIntrinsicHeaders(std::string &path);
|
||||||
|
|
||||||
void setupGCCLibs(Arch arch);
|
void setupGCCLibs(Arch arch);
|
||||||
@ -149,7 +149,9 @@ struct Target {
|
|||||||
GCCVersion gccversion;
|
GCCVersion gccversion;
|
||||||
bool usegcclibs;
|
bool usegcclibs;
|
||||||
bool nocodegen;
|
bool nocodegen;
|
||||||
std::string compiler;
|
std::string compilerpath; // /usr/bin/clang | [...]/target/bin/*-gcc
|
||||||
|
std::string compilername; // clang | gcc
|
||||||
|
std::string compilerexecname; // clang | *-apple-darwin-gcc
|
||||||
std::string triple;
|
std::string triple;
|
||||||
std::string otriple;
|
std::string otriple;
|
||||||
const char *lang;
|
const char *lang;
|
||||||
|
95
wrapper/tools.cpp
Executable file → Normal file
95
wrapper/tools.cpp
Executable file → Normal file
@ -144,7 +144,6 @@ const std::string &getParentProcessName() {
|
|||||||
|
|
||||||
if (Process32First(h, &pe)) {
|
if (Process32First(h, &pe)) {
|
||||||
do {
|
do {
|
||||||
std::cout << pe.szExeFile << " " << pe.th32ProcessID << std::endl;
|
|
||||||
if (pe.th32ProcessID == ppid) {
|
if (pe.th32ProcessID == ppid) {
|
||||||
ppe = &pe;
|
ppe = &pe;
|
||||||
break;
|
break;
|
||||||
@ -336,54 +335,92 @@ bool isExecutable(const char *f, const struct stat &) {
|
|||||||
return !access(f, F_OK | X_OK);
|
return !access(f, F_OK | X_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string &realPath(const char *file, std::string &result, realpathcmp cmp) {
|
bool ignoreCCACHE(const char *f, const struct stat &) {
|
||||||
|
const char *name = getFileName(f);
|
||||||
|
return name && strstr(name, "ccache") != name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool realPath(const char *file, std::string &result,
|
||||||
|
realpathcmp cmp1, realpathcmp cmp2) {
|
||||||
char *PATH = getenv("PATH");
|
char *PATH = getenv("PATH");
|
||||||
const char *p = PATH ? PATH : "";
|
const char *p = PATH ? PATH : "";
|
||||||
std::string sfile;
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
result.clear();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (*p == ':')
|
if (*p == ':')
|
||||||
++p;
|
++p;
|
||||||
|
|
||||||
while (*p && *p != ':')
|
while (*p && *p != ':')
|
||||||
sfile += *p++;
|
result += *p++;
|
||||||
|
|
||||||
sfile += "/";
|
result += "/";
|
||||||
sfile += file;
|
result += file;
|
||||||
|
|
||||||
if (!stat(sfile.c_str(), &st) && (!cmp || cmp(sfile.c_str(), st)))
|
|
||||||
break;
|
|
||||||
|
|
||||||
sfile.clear();
|
|
||||||
} while (*p);
|
|
||||||
|
|
||||||
|
if (!stat(result.c_str(), &st)) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (!sfile.empty()) {
|
|
||||||
char buf[PATH_MAX + 1];
|
char buf[PATH_MAX + 1];
|
||||||
ssize_t len;
|
|
||||||
|
|
||||||
if ((len = readlink(sfile.c_str(), buf, PATH_MAX)) != -1)
|
if (realpath(result.c_str(), buf)) {
|
||||||
|
result.assign(buf);
|
||||||
|
} else {
|
||||||
|
ssize_t len;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
size_t pathlen;
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
pathlen = result.find_last_of(PATHDIV);
|
||||||
|
|
||||||
|
if (pathlen == std::string::npos)
|
||||||
|
pathlen = result.length();
|
||||||
|
else
|
||||||
|
++pathlen; // PATHDIV
|
||||||
|
|
||||||
|
memcpy(path, result.c_str(), pathlen); // not null terminated
|
||||||
|
|
||||||
|
while ((len = readlink(result.c_str(), buf, PATH_MAX)) != -1) {
|
||||||
|
if (buf[0] != PATHDIV) {
|
||||||
|
result.assign(path, pathlen);
|
||||||
|
result.append(buf, len);
|
||||||
|
} else {
|
||||||
result.assign(buf, len);
|
result.assign(buf, len);
|
||||||
|
pathlen = strrchr(buf, PATHDIV) - buf + 1; // + 1: PATHDIV
|
||||||
|
memcpy(path, buf, pathlen);
|
||||||
|
}
|
||||||
|
if (++n >= 1000) {
|
||||||
|
err << result << ": too many levels of symbolic links"
|
||||||
|
<< err.endl();
|
||||||
|
result.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
result.swap(sfile);
|
if ((!cmp1 || cmp1(result.c_str(), st)) &&
|
||||||
return result;
|
(!cmp2 || cmp2(result.c_str(), st)))
|
||||||
}
|
break;
|
||||||
|
|
||||||
std::string &getPathOfCommand(const char *command, std::string &result) {
|
|
||||||
realPath(command, result, isExecutable);
|
|
||||||
|
|
||||||
const size_t len = strlen(command) + 1;
|
|
||||||
|
|
||||||
if (result.size() < len) {
|
|
||||||
result.clear();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.resize(result.size() - len);
|
result.clear();
|
||||||
return result;
|
} while (*p);
|
||||||
|
|
||||||
|
return !result.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getPathOfCommand(const char *command, std::string &result,
|
||||||
|
realpathcmp cmp) {
|
||||||
|
if (realPath(command, result, isExecutable, cmp))
|
||||||
|
stripFileName(result);
|
||||||
|
|
||||||
|
return !result.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stripFileName(std::string &path) {
|
||||||
|
size_t lastpathdiv = path.find_last_of(PATHDIV);
|
||||||
|
if (lastpathdiv != 0 && lastpathdiv != std::string::npos)
|
||||||
|
path.resize(lastpathdiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *getFileName(const char *file) {
|
const char *getFileName(const char *file) {
|
||||||
|
11
wrapper/tools.h
Executable file → Normal file
11
wrapper/tools.h
Executable file → Normal file
@ -19,6 +19,8 @@
|
|||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
|
struct stat;
|
||||||
|
|
||||||
namespace tools {
|
namespace tools {
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -142,8 +144,13 @@ bool listFiles(const char *dir, std::vector<std::string> *files,
|
|||||||
|
|
||||||
typedef bool (*realpathcmp)(const char *file, const struct stat &st);
|
typedef bool (*realpathcmp)(const char *file, const struct stat &st);
|
||||||
bool isExecutable(const char *f, const struct stat &);
|
bool isExecutable(const char *f, const struct stat &);
|
||||||
std::string &realPath(const char *file, std::string &result, realpathcmp cmp);
|
bool ignoreCCACHE(const char *f, const struct stat &);
|
||||||
std::string &getPathOfCommand(const char *command, std::string &result);
|
bool realPath(const char *file, std::string &result,
|
||||||
|
realpathcmp cmp1 = nullptr, realpathcmp cmp2 = nullptr);
|
||||||
|
bool getPathOfCommand(const char *command, std::string &result,
|
||||||
|
realpathcmp cmp = nullptr);
|
||||||
|
|
||||||
|
void stripFileName(std::string &path);
|
||||||
|
|
||||||
const char *getFileName(const char *file);
|
const char *getFileName(const char *file);
|
||||||
const char *getFileExtension(const char *file);
|
const char *getFileExtension(const char *file);
|
||||||
|
Loading…
Reference in New Issue
Block a user