mirror of
https://github.com/Relintai/osxcross.git
synced 2025-03-09 07:46:59 +01:00
add support for new x86_64h architecture (haswell)
add support for multiple -arch flags with gcc (and clang + -oc-use-gcc-libs) fix an unwind issue with -oc-use-gcc-libs + -mmacosx-version-min <= 10.5 update changelog
This commit is contained in:
parent
413c33a5e9
commit
270f6d73f6
@ -4,6 +4,10 @@ changed:
|
|||||||
* updated cctools to 855 with ld64-236.3 (Xcode 5.1)
|
* updated cctools to 855 with ld64-236.3 (Xcode 5.1)
|
||||||
* gcc 4.9.0 -> gcc 4.9.1
|
* gcc 4.9.0 -> gcc 4.9.1
|
||||||
|
|
||||||
|
added:
|
||||||
|
* support for new '-arch x86_64h' (requires clang 3.5+)
|
||||||
|
* support for multiple '-arch' flags with gcc
|
||||||
|
|
||||||
/******************************* v0.7 *******************************/
|
/******************************* v0.7 *******************************/
|
||||||
|
|
||||||
added:
|
added:
|
||||||
|
3
README.md
Normal file → Executable file
3
README.md
Normal file → Executable file
@ -145,12 +145,13 @@ However, there are several ways to override the default value:
|
|||||||
\>= 10.9 also defaults to `libc++` instead of `libstdc++`, this behavior
|
\>= 10.9 also defaults to `libc++` instead of `libstdc++`, this behavior
|
||||||
can be overriden by explicitly passing `-stdlib=libstdc++` to clang.
|
can be overriden by explicitly passing `-stdlib=libstdc++` to clang.
|
||||||
|
|
||||||
|
x86_64h defaults to `Mac OS X 10.9` and requires clang 3.5+.
|
||||||
|
|
||||||
### LICENSE: ####
|
### LICENSE: ####
|
||||||
* scripts/wrapper: GPLv2
|
* scripts/wrapper: GPLv2
|
||||||
* cctools/ld64: APSL 2.0
|
* cctools/ld64: APSL 2.0
|
||||||
* xar: New BSD
|
* xar: New BSD
|
||||||
* bc: GPLv3
|
* bc: GPLv3
|
||||||
|
|
||||||
|
|
||||||
### CREDITS: ####
|
### CREDITS: ####
|
||||||
* [cjacker for the cctools linux port](https://code.google.com/p/ios-toolchain-based-on-clang-for-linux/source/browse/#svn%2Ftrunk%2Fcctools-porting%2Fpatches)
|
* [cjacker for the cctools linux port](https://code.google.com/p/ios-toolchain-based-on-clang-for-linux/source/browse/#svn%2Ftrunk%2Fcctools-porting%2Fpatches)
|
||||||
|
4
build.sh
4
build.sh
@ -200,6 +200,10 @@ popd &>/dev/null
|
|||||||
pushd $TARGET_DIR/bin &>/dev/null
|
pushd $TARGET_DIR/bin &>/dev/null
|
||||||
CCTOOLS=`find . -name "x86_64-apple-darwin*"`
|
CCTOOLS=`find . -name "x86_64-apple-darwin*"`
|
||||||
CCTOOLS=($CCTOOLS)
|
CCTOOLS=($CCTOOLS)
|
||||||
|
for CCTOOL in ${CCTOOLS[@]}; do
|
||||||
|
CCTOOL_X86_64H=`echo "$CCTOOL" | sed 's/x86_64/x86_64h/g'`
|
||||||
|
ln -sf $CCTOOL $CCTOOL_X86_64H
|
||||||
|
done
|
||||||
for CCTOOL in ${CCTOOLS[@]}; do
|
for CCTOOL in ${CCTOOLS[@]}; do
|
||||||
CCTOOL_I386=`echo "$CCTOOL" | sed 's/x86_64/i386/g'`
|
CCTOOL_I386=`echo "$CCTOOL" | sed 's/x86_64/i386/g'`
|
||||||
ln -sf $CCTOOL $CCTOOL_I386
|
ln -sf $CCTOOL $CCTOOL_I386
|
||||||
|
@ -20,7 +20,7 @@ PSCRIPT="`basename $0`"
|
|||||||
|
|
||||||
if [[ $PSCRIPT != *wrapper/build.sh ]]; then
|
if [[ $PSCRIPT != *wrapper/build.sh ]]; then
|
||||||
# how many concurrent jobs should be used for compiling?
|
# how many concurrent jobs should be used for compiling?
|
||||||
JOBS=`tools/get_cpu_count.sh`
|
JOBS=${JOBS:=`tools/get_cpu_count.sh`}
|
||||||
|
|
||||||
if [ $PSCRIPT != "build.sh" ]; then
|
if [ $PSCRIPT != "build.sh" ]; then
|
||||||
`tools/osxcross_conf.sh`
|
`tools/osxcross_conf.sh`
|
||||||
|
262
wrapper/main.cpp
262
wrapper/main.cpp
@ -151,6 +151,27 @@ bool detectTarget(int argc, char **argv, Target &target) {
|
|||||||
|
|
||||||
PABREAK;
|
PABREAK;
|
||||||
}
|
}
|
||||||
|
case 'f': {
|
||||||
|
// -f
|
||||||
|
|
||||||
|
if (!strcmp(arg, "-flto") || !strncmp(arg, "-flto=", 5)) {
|
||||||
|
target.args.push_back(arg);
|
||||||
|
|
||||||
|
if (target.isClang())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
delayedfuncs.push_back([](Target &t) {
|
||||||
|
if (t.targetarch.size() > 1) {
|
||||||
|
std::cerr << "gcc does not support '-flto' with multiple "
|
||||||
|
<< "-arch flags" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
PABREAK;
|
||||||
|
}
|
||||||
case 'm': {
|
case 'm': {
|
||||||
// -m
|
// -m
|
||||||
|
|
||||||
@ -352,6 +373,8 @@ bool detectTarget(int argc, char **argv, Target &target) {
|
|||||||
|
|
||||||
if (!strncmp(cmd, "o32", 3))
|
if (!strncmp(cmd, "o32", 3))
|
||||||
target.arch = Arch::i386;
|
target.arch = Arch::i386;
|
||||||
|
else if (!strncmp(cmd, "o64h", 4))
|
||||||
|
target.arch = Arch::x86_64h;
|
||||||
else if (!strncmp(cmd, "o64", 3))
|
else if (!strncmp(cmd, "o64", 3))
|
||||||
target.arch = Arch::x86_64;
|
target.arch = Arch::x86_64;
|
||||||
else
|
else
|
||||||
@ -368,6 +391,242 @@ bool detectTarget(int argc, char **argv, Target &target) {
|
|||||||
return target.setup();
|
return target.setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// generateMultiArchObjectFile():
|
||||||
|
// support multiple -arch flags with gcc
|
||||||
|
// and clang + -oc-use-gcc-libs
|
||||||
|
//
|
||||||
|
|
||||||
|
void generateMultiArchObjectFile(int &rc, int argc, char **argv, Target &target,
|
||||||
|
int debug) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
std::string stdintmpfile;
|
||||||
|
string_vector objs;
|
||||||
|
std::stringstream obj;
|
||||||
|
bool compile = false;
|
||||||
|
size_t num = 0;
|
||||||
|
|
||||||
|
if (!strcmp(argv[argc - 1], "-")) {
|
||||||
|
//
|
||||||
|
// fork() + reading from stdin isn't a good idea
|
||||||
|
//
|
||||||
|
|
||||||
|
std::stringstream file;
|
||||||
|
std::string stdinsrc;
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
while (std::getline(std::cin, line)) {
|
||||||
|
stdinsrc += line;
|
||||||
|
stdinsrc += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
file << "/tmp/" << getNanoSeconds() << "_stdin";
|
||||||
|
|
||||||
|
if (target.isC())
|
||||||
|
file << ".c";
|
||||||
|
else if (target.isCXX())
|
||||||
|
file << ".cpp";
|
||||||
|
else if (target.isObjC())
|
||||||
|
file << ".m";
|
||||||
|
|
||||||
|
stdintmpfile = file.str();
|
||||||
|
writeFileContent(stdintmpfile, stdinsrc);
|
||||||
|
target.args[target.args.size() - 1] = stdintmpfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cleanup = [&]() {
|
||||||
|
if (!stdintmpfile.empty())
|
||||||
|
remove(stdintmpfile.c_str());
|
||||||
|
for (auto &obj : objs)
|
||||||
|
remove(obj.c_str());
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!target.outputname) {
|
||||||
|
bool f = false;
|
||||||
|
|
||||||
|
for (auto &arg : target.args) {
|
||||||
|
if (arg == "-c") {
|
||||||
|
f = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f && target.haveSourceFile()) {
|
||||||
|
static std::string outputname;
|
||||||
|
const char *ext = getFileExtension(target.sourcefile);
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
|
if (*ext)
|
||||||
|
outputname = std::string(target.sourcefile, ext - target.sourcefile);
|
||||||
|
else
|
||||||
|
outputname = target.sourcefile;
|
||||||
|
|
||||||
|
outputname += ".o";
|
||||||
|
|
||||||
|
if ((pos = outputname.find_last_of('/')) == std::string::npos)
|
||||||
|
pos = 0;
|
||||||
|
else
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
target.outputname = outputname.c_str() + pos;
|
||||||
|
} else {
|
||||||
|
if (f) {
|
||||||
|
std::cerr << "source filename detection failed" << std::endl;
|
||||||
|
std::cerr << "using a.out" << std::endl;
|
||||||
|
}
|
||||||
|
target.outputname = "a.out";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *outputname = strrchr(target.outputname, '/');
|
||||||
|
|
||||||
|
if (!outputname)
|
||||||
|
outputname = target.outputname;
|
||||||
|
else
|
||||||
|
++outputname;
|
||||||
|
|
||||||
|
for (auto &arch : target.targetarch) {
|
||||||
|
const char *archname = getArchName(arch);
|
||||||
|
pid_t pid;
|
||||||
|
++num;
|
||||||
|
|
||||||
|
obj.str(std::string());
|
||||||
|
obj << "/tmp/" << getNanoSeconds() << "_" << outputname << "_" << archname;
|
||||||
|
|
||||||
|
objs.push_back(obj.str());
|
||||||
|
pid = fork();
|
||||||
|
|
||||||
|
if (pid > 0) {
|
||||||
|
int status = 1;
|
||||||
|
|
||||||
|
if (wait(&status) == -1) {
|
||||||
|
std::cerr << "wait() failed" << std::endl;
|
||||||
|
cleanup();
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIFEXITED(status)) {
|
||||||
|
status = WEXITSTATUS(status);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
rc = status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (pid == 0) {
|
||||||
|
|
||||||
|
if (target.isGCC()) {
|
||||||
|
// GCC
|
||||||
|
bool is32bit = false;
|
||||||
|
|
||||||
|
switch (arch) {
|
||||||
|
case Arch::i386:
|
||||||
|
case Arch::i486:
|
||||||
|
case Arch::i586:
|
||||||
|
case Arch::i686:
|
||||||
|
is32bit = true;
|
||||||
|
case Arch::x86_64:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false && "unsupported arch");
|
||||||
|
}
|
||||||
|
|
||||||
|
target.fargs.push_back(is32bit ? "-m32" : "-m64");
|
||||||
|
} else if (target.isClang()) {
|
||||||
|
// Clang
|
||||||
|
target.fargs.push_back("-arch");
|
||||||
|
target.fargs.push_back(getArchName(arch));
|
||||||
|
} else {
|
||||||
|
assert(false && "unsupported compiler");
|
||||||
|
}
|
||||||
|
|
||||||
|
target.fargs.push_back("-o");
|
||||||
|
target.fargs.push_back(obj.str());
|
||||||
|
|
||||||
|
if (target.usegcclibs) {
|
||||||
|
target.setupGCCLibs(arch);
|
||||||
|
|
||||||
|
if (target.langGiven()) {
|
||||||
|
// -x must be added *after* the static libstdc++ *.a
|
||||||
|
// otherwise clang thinks they are source files
|
||||||
|
target.fargs.push_back("-x");
|
||||||
|
target.fargs.push_back(target.lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
std::cerr << "[d] "
|
||||||
|
<< "[" << num << "/" << target.targetarch.size()
|
||||||
|
<< "] [compiling] " << archname << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
compile = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
std::cerr << "fork() failed" << std::endl;
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compile && !target.nocodegen && rc == -1) {
|
||||||
|
std::string cmd;
|
||||||
|
std::string lipo;
|
||||||
|
std::string path;
|
||||||
|
|
||||||
|
lipo = "x86_64-apple-";
|
||||||
|
lipo += getDefaultTarget();
|
||||||
|
lipo += "-lipo";
|
||||||
|
|
||||||
|
if (getPathOfCommand(lipo.c_str(), path).empty()) {
|
||||||
|
lipo = "lipo";
|
||||||
|
|
||||||
|
if (getPathOfCommand(lipo.c_str(), path).empty()) {
|
||||||
|
std::cerr << "cannot find lipo binary" << std::endl;
|
||||||
|
rc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc == -1) {
|
||||||
|
cmd.swap(path);
|
||||||
|
cmd += "/";
|
||||||
|
cmd += lipo;
|
||||||
|
cmd += " -create ";
|
||||||
|
|
||||||
|
for (auto &obj : objs) {
|
||||||
|
cmd += obj;
|
||||||
|
cmd += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd += "-output ";
|
||||||
|
cmd += target.outputname;
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
std::cerr << "[d] [lipo] <-- " << cmd << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = system(cmd.c_str());
|
||||||
|
rc = WEXITSTATUS(rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compile)
|
||||||
|
cleanup();
|
||||||
|
#else
|
||||||
|
(void)rc;
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
(void)target;
|
||||||
|
(void)debug;
|
||||||
|
std::cerr << __func__ << " not supported" << std::endl;
|
||||||
|
rc = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -416,6 +675,9 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
concatEnvVariable("COMPILER_PATH", target.execpath);
|
concatEnvVariable("COMPILER_PATH", target.execpath);
|
||||||
|
|
||||||
|
if (target.targetarch.size() > 1 && (target.usegcclibs || target.isGCC()))
|
||||||
|
generateMultiArchObjectFile(rc, argc, argv, target, debug);
|
||||||
|
|
||||||
auto printCommand = [&]() {
|
auto printCommand = [&]() {
|
||||||
std::string in;
|
std::string in;
|
||||||
std::string out;
|
std::string out;
|
||||||
|
@ -343,6 +343,9 @@ void Target::setupGCCLibs(Arch arch) {
|
|||||||
fargs.push_back(tmp.str());
|
fargs.push_back(tmp.str());
|
||||||
|
|
||||||
fargs.push_back("-lc");
|
fargs.push_back("-lc");
|
||||||
|
|
||||||
|
if (OSNum <= OSVersion(10, 5))
|
||||||
|
fargs.push_back("-Wl,-no_compact_unwind");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Target::setup() {
|
bool Target::setup() {
|
||||||
@ -382,7 +385,14 @@ bool Target::setup() {
|
|||||||
otriple += target;
|
otriple += target;
|
||||||
|
|
||||||
if (!OSNum.Num()) {
|
if (!OSNum.Num()) {
|
||||||
if (stdlib == StdLib::libcxx) {
|
if (haveArch(Arch::x86_64h)) {
|
||||||
|
OSNum = OSVersion(10, 9); // Default to 10.9 for x86_64h
|
||||||
|
if (SDKOSNum < OSNum) {
|
||||||
|
std::cerr << getArchName(arch) << "requires the SDK from "
|
||||||
|
<< OSNum.Str() << " (or later)";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (stdlib == StdLib::libcxx) {
|
||||||
OSNum = OSVersion(10, 7); // Default to 10.7 for libc++
|
OSNum = OSVersion(10, 7); // Default to 10.7 for libc++
|
||||||
} else {
|
} else {
|
||||||
OSNum = getDefaultMinTarget();
|
OSNum = getDefaultMinTarget();
|
||||||
@ -632,11 +642,19 @@ bool Target::setup() {
|
|||||||
case Arch::i686:
|
case Arch::i686:
|
||||||
is32bit = true;
|
is32bit = true;
|
||||||
case Arch::x86_64:
|
case Arch::x86_64:
|
||||||
|
case Arch::x86_64h:
|
||||||
if (isGCC()) {
|
if (isGCC()) {
|
||||||
if (targetarch.size() > 1)
|
if (targetarch.size() > 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
fargs.push_back(is32bit ? "-m32" : "-m64");
|
fargs.push_back(is32bit ? "-m32" : "-m64");
|
||||||
|
|
||||||
|
if (arch == Arch::x86_64h) {
|
||||||
|
std::cerr << getArchName(arch) << " requires clang" << std::endl;
|
||||||
|
return false;
|
||||||
|
// fargs.push_back("-march=core-avx2");
|
||||||
|
// fargs.push_back("-Wl,-arch,x86_64h");
|
||||||
|
}
|
||||||
} else if (isClang()) {
|
} else if (isClang()) {
|
||||||
if (usegcclibs && targetarch.size() > 1)
|
if (usegcclibs && targetarch.size() > 1)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user