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
|
||||
|
||||
added:
|
||||
* support for ccache symlinks
|
||||
* darling-dmg sdk packaging script
|
||||
* include path warnings for /usr/include and /usr/local/include
|
||||
(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: ###
|
||||
|
||||
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:**
|
||||
|
||||
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).
|
||||
|
||||
To achive this, add the following to your bashrc (or similar):
|
||||
@ -35,7 +35,7 @@ Then run `osxcross-macports <cmd>`.
|
||||
|
||||
**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.
|
||||
|
||||
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;
|
||||
|
||||
//
|
||||
// detectTarget():
|
||||
// detect target and setup invocation command
|
||||
//
|
||||
|
||||
void checkIncludePath(const char *opt, const char *path) {
|
||||
#ifndef __APPLE__
|
||||
constexpr const char *DangerousIncludePaths[] = { "/usr/include",
|
||||
"/usr/local/include" };
|
||||
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
@ -108,6 +104,11 @@ void warnExtension(const char *extension) {
|
||||
<< "'OSXCROSS_NO_EXTENSION_WARNINGS=1' (env)" << warninfo.endl();
|
||||
}
|
||||
|
||||
//
|
||||
// detectTarget():
|
||||
// detect target and setup invocation command
|
||||
//
|
||||
|
||||
#define PABREAK \
|
||||
else target.args.push_back(arg); \
|
||||
break
|
||||
@ -409,16 +410,17 @@ bool detectTarget(int argc, char **argv, Target &target) {
|
||||
};
|
||||
|
||||
auto checkCXXLib = [&]() {
|
||||
if (target.compiler.size() <= 7)
|
||||
if (target.compilername.size() <= 7)
|
||||
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) {
|
||||
warn << "'-stdlib=" << getStdLibString(target.stdlib)
|
||||
<< "' will be ignored" << warn.endl();
|
||||
}
|
||||
|
||||
target.compiler.resize(target.compiler.size() - 7);
|
||||
target.compilername.resize(target.compilername.size() - 7);
|
||||
target.stdlib = StdLib::libcxx;
|
||||
}
|
||||
};
|
||||
@ -452,13 +454,13 @@ bool detectTarget(int argc, char **argv, Target &target) {
|
||||
return false;
|
||||
|
||||
target.target = std::string(cmd, p - cmd);
|
||||
target.compiler = &p[1];
|
||||
target.compilername = &p[1];
|
||||
|
||||
if (target.compiler == "cc")
|
||||
target.compiler = getDefaultCompiler();
|
||||
else if (target.compiler == "c++")
|
||||
target.compiler = getDefaultCXXCompiler();
|
||||
else if (auto *prog = program::getprog(target.compiler))
|
||||
if (target.compilername == "cc")
|
||||
target.compilername = getDefaultCompiler();
|
||||
else if (target.compilername == "c++")
|
||||
target.compilername = getDefaultCXXCompiler();
|
||||
else if (auto *prog = program::getprog(target.compilername))
|
||||
(*prog)(argc, argv, target);
|
||||
|
||||
if (target.target != getDefaultTarget()) {
|
||||
@ -484,7 +486,7 @@ bool detectTarget(int argc, char **argv, Target &target) {
|
||||
return false;
|
||||
|
||||
if (const char *p = strchr(cmd, '-'))
|
||||
target.compiler = &cmd[p - cmd + 1];
|
||||
target.compilername = &cmd[p - cmd + 1];
|
||||
|
||||
if (!parseArgs())
|
||||
return false;
|
||||
@ -681,10 +683,10 @@ void generateMultiArchObjectFile(int &rc, int argc, char **argv, Target &target,
|
||||
lipo += getDefaultTarget();
|
||||
lipo += "-lipo";
|
||||
|
||||
if (getPathOfCommand(lipo.c_str(), path).empty()) {
|
||||
if (!getPathOfCommand(lipo.c_str(), path)) {
|
||||
lipo = "lipo";
|
||||
|
||||
if (getPathOfCommand(lipo.c_str(), path).empty()) {
|
||||
if (!getPathOfCommand(lipo.c_str(), path)) {
|
||||
err << "cannot find lipo binary" << err.endl();
|
||||
rc = 1;
|
||||
}
|
||||
@ -759,7 +761,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (debug >= 2) {
|
||||
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.endl();
|
||||
@ -789,8 +791,18 @@ int main(int argc, char **argv) {
|
||||
in += " ";
|
||||
}
|
||||
|
||||
for (auto &arg : target.fargs) {
|
||||
out += arg;
|
||||
out += target.compilerpath;
|
||||
|
||||
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 += " ";
|
||||
}
|
||||
|
||||
@ -831,7 +843,7 @@ int main(int argc, char **argv) {
|
||||
if (unittest == 2)
|
||||
return 0;
|
||||
|
||||
if (rc == -1 && execvp(cargs[0], cargs)) {
|
||||
if (rc == -1 && execvp(target.compilerpath.c_str(), cargs)) {
|
||||
err << "invoking compiler failed" << err.endl();
|
||||
|
||||
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 compiler.find("++") == std::string::npos && !isObjC(true);
|
||||
return compilername.find("++") == std::string::npos && !isObjC(true);
|
||||
}
|
||||
|
||||
bool Target::isCXX() {
|
||||
bool CXXCompiler = compiler.find("++") != std::string::npos;
|
||||
bool CXXCompiler = compilername.find("++") != std::string::npos;
|
||||
|
||||
if (!langGiven() && CXXCompiler && !isObjC(true))
|
||||
return true;
|
||||
@ -229,34 +229,37 @@ bool Target::isCXX11orNewer() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string Target::getFullCompilerName() const {
|
||||
std::string compiler;
|
||||
|
||||
void Target::setCompilerPath() {
|
||||
if (isGCC()) {
|
||||
compiler = execpath;
|
||||
compiler += "/";
|
||||
compiler += getTriple();
|
||||
compiler += "-";
|
||||
compilerpath = execpath;
|
||||
compilerpath += "/";
|
||||
compilerpath += getTriple();
|
||||
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) {
|
||||
std::string clangbin;
|
||||
static std::stringstream dir;
|
||||
|
||||
assert(isClang());
|
||||
|
||||
getPathOfCommand(compiler.c_str(), clangbin);
|
||||
|
||||
if (clangbin.empty())
|
||||
if (compilerpath.empty())
|
||||
return false;
|
||||
|
||||
std::string clangbindir = compilerpath;
|
||||
stripFileName(clangbindir);
|
||||
|
||||
static ClangVersion *clangversion;
|
||||
static std::string pathtmp;
|
||||
|
||||
@ -266,10 +269,8 @@ bool Target::findClangIntrinsicHeaders(std::string &path) {
|
||||
*clangversion = ClangVersion();
|
||||
pathtmp.clear();
|
||||
|
||||
auto check = []()->bool {
|
||||
|
||||
auto tryDir = [&]()->bool {
|
||||
listFiles(dir.str().c_str(), nullptr, [](const char *file) {
|
||||
|
||||
if (file[0] != '.' && isDirectory(file, dir.str().c_str())) {
|
||||
ClangVersion cv = parseClangVersion(file);
|
||||
|
||||
@ -303,20 +304,36 @@ bool Target::findClangIntrinsicHeaders(std::string &path) {
|
||||
checkDir(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
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()) {
|
||||
clear(dir);
|
||||
#define TRYDIR2(libdir) TRYDIR(clangbindir, libdir)
|
||||
#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__
|
||||
constexpr const char *OSXIntrinDirs[] = {
|
||||
@ -325,25 +342,17 @@ bool Target::findClangIntrinsicHeaders(std::string &path) {
|
||||
"XcodeDefault.xctoolchain/usr/lib/clang"
|
||||
};
|
||||
|
||||
for (auto intrindir : OSXIntrinDirs) {
|
||||
dir << intrindir;
|
||||
if (check()) {
|
||||
break;
|
||||
}
|
||||
clear(dir);
|
||||
}
|
||||
for (auto intrindir : OSXIntrinDirs)
|
||||
TRYDIR3(intrindir);
|
||||
#endif
|
||||
|
||||
if (!dir.rdbuf()->in_avail()) {
|
||||
dir << clangbin << "/../include/clang";
|
||||
TRYDIR2("/../include/clang");
|
||||
TRYDIR2("/usr/include/clang");
|
||||
|
||||
if (!check())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
path.swap(pathtmp);
|
||||
return *clangversion != ClangVersion();
|
||||
#undef TRYDIR
|
||||
#undef TRYDIR2
|
||||
#undef TRYDIR3
|
||||
}
|
||||
|
||||
void Target::setupGCCLibs(Arch arch) {
|
||||
@ -409,7 +418,7 @@ bool Target::setup() {
|
||||
OSVersion SDKOSNum = getSDKOSNum();
|
||||
|
||||
if (!isKnownCompiler())
|
||||
warn << "unknown compiler '" << compiler << "'" << warn.endl();
|
||||
warn << "unknown compiler '" << compilername << "'" << warn.endl();
|
||||
|
||||
if (!getSDKPath(SDKPath)) {
|
||||
err << "cannot find Mac OS X SDK (expected in: " << SDKPath << ")"
|
||||
@ -439,6 +448,8 @@ bool Target::setup() {
|
||||
otriple += "-";
|
||||
otriple += target;
|
||||
|
||||
setCompilerPath();
|
||||
|
||||
if (!OSNum.Num()) {
|
||||
if (haveArch(Arch::x86_64h)) {
|
||||
OSNum = OSVersion(10, 8); // Default to 10.8 for x86_64h
|
||||
@ -569,7 +580,7 @@ bool Target::setup() {
|
||||
abort();
|
||||
}
|
||||
|
||||
fargs.push_back(getFullCompilerName());
|
||||
fargs.push_back(compilerexecname);
|
||||
|
||||
if (isClang()) {
|
||||
std::string tmp;
|
||||
@ -585,7 +596,7 @@ bool Target::setup() {
|
||||
|
||||
#ifndef __APPLE__
|
||||
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();
|
||||
} else {
|
||||
fargs.push_back("-isystem");
|
||||
|
@ -75,7 +75,7 @@ struct Target {
|
||||
Target()
|
||||
: vendor(getDefaultVendor()), target(getDefaultTarget()),
|
||||
stdlib(StdLib::unset), usegcclibs(), nocodegen(),
|
||||
compiler(getDefaultCompiler()), lang(), langstd(), sourcefile(),
|
||||
compilername(getDefaultCompiler()), lang(), langstd(), sourcefile(),
|
||||
outputname() {
|
||||
if (!getExecutablePath(execpath, sizeof(execpath)))
|
||||
abort();
|
||||
@ -115,11 +115,11 @@ struct Target {
|
||||
}
|
||||
|
||||
bool isClang() const {
|
||||
return !strncmp(getFileName(compiler.c_str()), "clang", 5);
|
||||
return !strncmp(getFileName(compilername.c_str()), "clang", 5);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ struct Target {
|
||||
|
||||
const std::string &getTriple() const { return triple; }
|
||||
|
||||
const std::string getFullCompilerName() const;
|
||||
void setCompilerPath();
|
||||
bool findClangIntrinsicHeaders(std::string &path);
|
||||
|
||||
void setupGCCLibs(Arch arch);
|
||||
@ -149,7 +149,9 @@ struct Target {
|
||||
GCCVersion gccversion;
|
||||
bool usegcclibs;
|
||||
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 otriple;
|
||||
const char *lang;
|
||||
|
89
wrapper/tools.cpp
Executable file → Normal file
89
wrapper/tools.cpp
Executable file → Normal file
@ -144,7 +144,6 @@ const std::string &getParentProcessName() {
|
||||
|
||||
if (Process32First(h, &pe)) {
|
||||
do {
|
||||
std::cout << pe.szExeFile << " " << pe.th32ProcessID << std::endl;
|
||||
if (pe.th32ProcessID == ppid) {
|
||||
ppe = &pe;
|
||||
break;
|
||||
@ -336,54 +335,92 @@ bool isExecutable(const char *f, const struct stat &) {
|
||||
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");
|
||||
const char *p = PATH ? PATH : "";
|
||||
std::string sfile;
|
||||
struct stat st;
|
||||
|
||||
result.clear();
|
||||
|
||||
do {
|
||||
if (*p == ':')
|
||||
++p;
|
||||
|
||||
while (*p && *p != ':')
|
||||
sfile += *p++;
|
||||
result += *p++;
|
||||
|
||||
sfile += "/";
|
||||
sfile += file;
|
||||
|
||||
if (!stat(sfile.c_str(), &st) && (!cmp || cmp(sfile.c_str(), st)))
|
||||
break;
|
||||
|
||||
sfile.clear();
|
||||
} while (*p);
|
||||
result += "/";
|
||||
result += file;
|
||||
|
||||
if (!stat(result.c_str(), &st)) {
|
||||
#ifndef _WIN32
|
||||
if (!sfile.empty()) {
|
||||
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);
|
||||
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
|
||||
|
||||
result.swap(sfile);
|
||||
return result;
|
||||
if ((!cmp1 || cmp1(result.c_str(), st)) &&
|
||||
(!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;
|
||||
} while (*p);
|
||||
|
||||
return !result.empty();
|
||||
}
|
||||
|
||||
result.resize(result.size() - len);
|
||||
return result;
|
||||
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) {
|
||||
|
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. *
|
||||
***********************************************************************/
|
||||
|
||||
struct stat;
|
||||
|
||||
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);
|
||||
bool isExecutable(const char *f, const struct stat &);
|
||||
std::string &realPath(const char *file, std::string &result, realpathcmp cmp);
|
||||
std::string &getPathOfCommand(const char *command, std::string &result);
|
||||
bool ignoreCCACHE(const char *f, const struct stat &);
|
||||
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 *getFileExtension(const char *file);
|
||||
|
Loading…
Reference in New Issue
Block a user