GN: Add support for 32- and 64-bit cross-compiles.

This makes it possible on Linux to refer to 64-bit targets from a 32-bit build, and 32-bit targets from a 64-bit build.

This also adds flags for Mac cross-compiles but I haven't written the toolchain definitions yet.

BUG=322106
R=scottmg@chromium.org

Review URL: https://codereview.chromium.org/81153003

git-svn-id: http://src.chromium.org/svn/trunk/src/build@236871 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
This commit is contained in:
brettw@chromium.org 2013-11-22 23:30:28 +00:00
Родитель fac71cc95c
Коммит 761c4c6466
3 изменённых файлов: 168 добавлений и 80 удалений

Просмотреть файл

@ -383,20 +383,32 @@ set_defaults("source_set") {
# default toolchain. # default toolchain.
if (is_win) { if (is_win) {
if (cpu_arch == "x64") { if (build_cpu_arch == "x64") {
host_toolchain = "//build/toolchain/win:64" host_toolchain = "//build/toolchain/win:64"
} else if (cpu_arch == "x86") { } else if (build_cpu_arch == "x86") {
host_toolchain = "//build/toolchain/win:32" host_toolchain = "//build/toolchain/win:32"
} }
set_default_toolchain(host_toolchain)
if (cpu_arch == "x64") {
set_default_toolchain("//build/toolchain/win:64")
} else if (cpu_arch == "x86") {
set_default_toolchain("//build/toolchain/win:32")
}
} else if (is_linux) { } else if (is_linux) {
host_toolchain = "//build/toolchain/linux:host" if (build_cpu_arch == "arm") {
if (cpu_arch == "arm" && build_cpu_arch != "arm") { host_toolchain = "//build/toolchain/linux:arm"
# Special toolchain for ARM cross-compiling. } else if (build_cpu_arch == "x86") {
set_default_toolchain("//build/toolchain/linux:arm-cross-compile") host_toolchain = "//build/toolchain/linux:32"
} else { } else if (build_cpu_arch == "x64") {
# Use whatever GCC is on the current platform. host_toolchain = "//build/toolchain/linux:64"
set_default_toolchain(host_toolchain) }
if (build_cpu_arch == "arm") {
set_default_toolchain("//build/toolchain/linux:arm")
} else if (build_cpu_arch == "x86") {
set_default_toolchain("//build/toolchain/linux:32")
} else if (build_cpu_arch == "x64") {
set_default_toolchain("//build/toolchain/linux:64")
} }
} else if (is_mac) { } else if (is_mac) {
host_toolchain = "//build/toolchain/mac:clang" host_toolchain = "//build/toolchain/mac:clang"

Просмотреть файл

@ -39,14 +39,12 @@ config("compiler") {
cflags += [ "-fstack-protector", "--param=ssp-buffer-size=4" ] cflags += [ "-fstack-protector", "--param=ssp-buffer-size=4" ]
} }
# Mac-specific compiler flags setup.
# ----------------------------------
if (is_mac) { if (is_mac) {
# Mac-specific compiler flags setup.
# ----------------------------------
# These flags are shared between the C compiler and linker. # These flags are shared between the C compiler and linker.
common_mac_flags = [ common_mac_flags = [
# TODO(brettw) obviously this arch flag needs to be parameterized.
"-arch i386",
# Set which SDK to use. # Set which SDK to use.
# TODO(brettw) this needs to be configurable somehow. # TODO(brettw) this needs to be configurable somehow.
"-isysroot", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk", "-isysroot", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk",
@ -54,6 +52,13 @@ config("compiler") {
"-mmacosx-version-min=10.6", "-mmacosx-version-min=10.6",
] ]
# CPU architecture.
if (cpu_arch == "x64") {
common_mac_flags += "-arch x86_64"
} else if (cpu_arch == "x32") {
common_mac_flags += "-arch i386"
}
cflags += common_mac_flags + [ cflags += common_mac_flags + [
# Without this, the constructors and destructors of a C++ object inside # Without this, the constructors and destructors of a C++ object inside
# an Objective C struct won't be called, which is very bad. # an Objective C struct won't be called, which is very bad.
@ -70,6 +75,19 @@ config("compiler") {
"-Wl,-rpath,@loader_path/.", "-Wl,-rpath,@loader_path/.",
"-Wl,-rpath,@loader_path/../../..", "-Wl,-rpath,@loader_path/../../..",
] ]
} else {
# Non-Mac Posix compiler flags setup.
# -----------------------------------
# CPU architecture. We may or may not be doing a cross compile now, so for
# simplicity we always explicitly set the architecture.
if (cpu_arch == "x64") {
cflags += "-m64"
ldflags += "-m64"
} else if (cpu_arch == "x32") {
cflags += "-m32"
ldflags += "-m32"
}
} }
# Linux-specific compiler flags setup. # Linux-specific compiler flags setup.

Просмотреть файл

@ -7,110 +7,64 @@ cxx = "g++"
ar = "ar" ar = "ar"
ld = cxx ld = cxx
# Everything up to the toolchain args is an exact copy of the GCC version # The toolchains below all issue the same commands with some different flags.
# below. Keep in sync! Only the compiler variable definitions have changed. # TODO(brettw) it would be nice to have a different way to express this without
toolchain("host") { # so much duplication.
# Make these apply to all tools below. cc_command = "$cc -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_c -c \$in -o \$out"
lib_prefix = "-l" cxx_command = "$cxx -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_cc -c \$in -o \$out"
lib_dir_prefix="-L" alink_command = "rm -f \$out && $ar rcs \$out \$in"
solink_command = "if [ ! -e \$lib -o ! -e \${lib}.TOC ]; then $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname -Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive \$libs && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.TOC; else $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname -Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive \$libs && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.tmp && if ! cmp -s \${lib}.tmp \${lib}.TOC; then mv \${lib}.tmp \${lib}.TOC ; fi; fi"
link_command = "$ld \$ldflags -o \$out -Wl,--start-group \$in \$solibs -Wl,--end-group \$libs"
stamp_command = "\${postbuilds}touch \$out"
copy_command = "ln -f \$in \$out 2>/dev/null || (rm -rf \$out && cp -af \$in \$out)"
tool("cc") { # ARM --------------------------------------------------------------------------
# cflags_pch_c
command = "$cc -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_c -c \$in -o \$out"
description = "CC \$out"
depfile = "\$out.d"
deps = "gcc"
}
tool("cxx") {
# cflags_pch_cc
command = "$cxx -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_cc -c \$in -o \$out"
description = "CXX \$out"
depfile = "\$out.d"
deps = "gcc"
}
tool("alink") {
command = "rm -f \$out && $ar rcs \$out \$in"
description = "AR \$out"
}
tool("solink") {
command = "if [ ! -e \$lib -o ! -e \${lib}.TOC ]; then $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname -Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive \$libs && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.TOC; else $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname -Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive \$libs && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.tmp && if ! cmp -s \${lib}.tmp \${lib}.TOC; then mv \${lib}.tmp \${lib}.TOC ; fi; fi"
description = "SOLINK \$lib"
#pool = "link_pool"
restat = "1"
}
tool("link") {
command = "$ld \$ldflags -o \$out -Wl,--start-group \$in \$solibs -Wl,--end-group \$libs"
description = "LINK \$out"
#pool = "link_pool"
}
tool("stamp") {
command = "\${postbuilds}touch \$out"
description = "STAMP \$out"
}
tool("copy") {
command = "ln -f \$in \$out 2>/dev/null || (rm -rf \$out && cp -af \$in \$out)"
description = "COPY \$in \$out"
}
# When invoking this toolchain not as the default one, these args will be
# passed to the build. They are ignored when this is the default toolchain.
toolchain_args() {
# Pass the current CPU architecture to the build as the toolchain to use.
# If the default toolchain is set to ARM and the local system is x86, this
# will make this secondary toolchain refer to the host GCC again.
cpu_arch = build_cpu_arch
}
}
# ARM Cross-Compile ------------------------------------------------------------
cc = "arm-linux-gnueabi-gcc" cc = "arm-linux-gnueabi-gcc"
cxx = "arm-linux-gnueabi-g++" cxx = "arm-linux-gnueabi-g++"
ar = "arm-linux-gnueabi-ar" ar = "arm-linux-gnueabi-ar"
ld = cxx ld = cxx
# Everything up the the toolchain args is an exact copy of the GCC version toolchain("arm") {
# below. Keep in sync! Only the compiler variable definitions have changed.
toolchain("arm-cross-compile") {
# Make these apply to all tools below. # Make these apply to all tools below.
lib_prefix = "-l" lib_prefix = "-l"
lib_dir_prefix="-L" lib_dir_prefix="-L"
tool("cc") { tool("cc") {
# cflags_pch_c # cflags_pch_c
command = "$cc -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_c -c \$in -o \$out" command = cc_command
description = "CC \$out" description = "CC \$out"
depfile = "\$out.d" depfile = "\$out.d"
deps = "gcc" deps = "gcc"
} }
tool("cxx") { tool("cxx") {
# cflags_pch_cc # cflags_pch_cc
command = "$cxx -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_cc -c \$in -o \$out" command = cxx_command
description = "CXX \$out" description = "CXX \$out"
depfile = "\$out.d" depfile = "\$out.d"
deps = "gcc" deps = "gcc"
} }
tool("alink") { tool("alink") {
command = "rm -f \$out && $ar rcs \$out \$in" command = alink_command
description = "AR \$out" description = "AR \$out"
} }
tool("solink") { tool("solink") {
command = "if [ ! -e \$lib -o ! -e \${lib}.TOC ]; then $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname -Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive \$libs && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.TOC; else $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname -Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive \$libs && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.tmp && if ! cmp -s \${lib}.tmp \${lib}.TOC; then mv \${lib}.tmp \${lib}.TOC ; fi; fi" command = solink_command
description = "SOLINK \$lib" description = "SOLINK \$lib"
#pool = "link_pool" #pool = "link_pool"
restat = "1" restat = "1"
} }
tool("link") { tool("link") {
command = "$ld \$ldflags -o \$out -Wl,--start-group \$in \$solibs -Wl,--end-group \$libs" command = link_command
description = "LINK \$out" description = "LINK \$out"
#pool = "link_pool" #pool = "link_pool"
} }
tool("stamp") { tool("stamp") {
command = "\${postbuilds}touch \$out" command = stamp_command
description = "STAMP \$out" description = "STAMP \$out"
} }
tool("copy") { tool("copy") {
command = "ln -f \$in \$out 2>/dev/null || (rm -rf \$out && cp -af \$in \$out)" command = copy_command
description = "COPY \$in \$out" description = "COPY \$in \$out"
} }
@ -120,3 +74,107 @@ toolchain("arm-cross-compile") {
cpu_arch = "arm" cpu_arch = "arm"
} }
} }
# 32-bit -----------------------------------------------------------------------
toolchain("32") {
# Make these apply to all tools below.
lib_prefix = "-l"
lib_dir_prefix="-L"
tool("cc") {
# cflags_pch_c
command = cc_command
description = "CC \$out"
depfile = "\$out.d"
deps = "gcc"
}
tool("cxx") {
# cflags_pch_cc
command = cxx_command
description = "CXX \$out"
depfile = "\$out.d"
deps = "gcc"
}
tool("alink") {
command = alink_command
description = "AR \$out"
}
tool("solink") {
command = solink_command
description = "SOLINK \$lib"
#pool = "link_pool"
restat = "1"
}
tool("link") {
command = link_command
description = "LINK \$out"
#pool = "link_pool"
}
tool("stamp") {
command = stamp_command
description = "STAMP \$out"
}
tool("copy") {
command = copy_command
description = "COPY \$in \$out"
}
# When invoking this toolchain not as the default one, these args will be
# passed to the build. They are ignored when this is the default toolchain.
toolchain_args() {
cpu_arch = "x32"
}
}
# 64-bit -----------------------------------------------------------------------
toolchain("64") {
# Make these apply to all tools below.
lib_prefix = "-l"
lib_dir_prefix="-L"
tool("cc") {
# cflags_pch_c
command = cc_command
description = "CC \$out"
depfile = "\$out.d"
deps = "gcc"
}
tool("cxx") {
# cflags_pch_cc
command = cxx_command
description = "CXX \$out"
depfile = "\$out.d"
deps = "gcc"
}
tool("alink") {
command = alink_command
description = "AR \$out"
}
tool("solink") {
command = solink_command
description = "SOLINK \$lib"
#pool = "link_pool"
restat = "1"
}
tool("link") {
command = link_command
description = "LINK \$out"
#pool = "link_pool"
}
tool("stamp") {
command = stamp_command
description = "STAMP \$out"
}
tool("copy") {
command = copy_command
description = "COPY \$in \$out"
}
# When invoking this toolchain not as the default one, these args will be
# passed to the build. They are ignored when this is the default toolchain.
toolchain_args() {
cpu_arch = "x64"
}
}