Skip to content

Instantly share code, notes, and snippets.

@bmount
Created October 11, 2013 03:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save bmount/6929380 to your computer and use it in GitHub Desktop.
Save bmount/6929380 to your computer and use it in GitHub Desktop.
Cross compile python 2.7.3 for arm
# For 2.7.3 (greater than not available for 2.7, not required in 3.3+)
# http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tar.xz
# based on these PPC instructions: http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html
# (thanks Paul Gibson)
# patch (also checked in here): http://randomsplat.com/wp-content/uploads/2012/10/Python-2.7.3-xcompile.patch
# in python source dir:
./configure
make python Parser/pgen
mv python hostpython
mv Parser/pgen Parser/hostpgen
make distclean
patch -p1 < ../Python-2.7.3-xcompile.patch
CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ AR=arm-linux-gnueabihf-ar RANLIB=arm-linux-gnueabihf-ranlib ./configure --host=arm-linux --build=x86_64-linux-gnu --prefix=/python
make HOSTPYTHON=./hostpython HOSTPGEN=./Parser/hostpgen BLDSHARED="arm-linux-gnueabihf-gcc -shared" CROSS_COMPILE=arm-linux-gnueabihf- CROSS_COMPILE_TARGET=yes HOSTARCH=arm-linux BUILDARCH=x86_64-linux-gnu
make install HOSTPYTHON=./hostpython BLDSHARED="arm-linux-gnueabihf-gcc -shared" CROSS_COMPILE=arm-linux-gnueabihf- CROSS_COMPILE_TARGET=yes prefix=$SOMEWHEREREASONABLE/Python-2.7.3/_install
# copy _install/ to device
diff -ur Python-2.7.3.orig/configure Python-2.7.3-Source/configure
--- Python-2.7.3.orig/configure 2012-04-09 19:07:36.000000000 -0400
+++ Python-2.7.3-Source/configure 2012-10-23 14:10:45.305220393 -0400
@@ -13697,7 +13697,7 @@
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then :
- ac_cv_have_long_long_format=no
+ ac_cv_have_long_long_format="cross -- assuming yes"
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -13749,7 +13749,7 @@
$as_echo "$ac_cv_have_long_long_format" >&6; }
fi
-if test "$ac_cv_have_long_long_format" = yes
+if test "$ac_cv_have_long_long_format" != no
then
$as_echo "#define PY_FORMAT_LONG_LONG \"ll\"" >>confdefs.h
diff -ur Python-2.7.3.orig/Makefile.pre.in Python-2.7.3-Source/Makefile.pre.in
--- Python-2.7.3.orig/Makefile.pre.in 2012-04-09 19:07:33.000000000 -0400
+++ Python-2.7.3-Source/Makefile.pre.in 2012-10-23 14:10:45.305220393 -0400
@@ -182,6 +182,7 @@
PYTHON= python$(EXE)
BUILDPYTHON= python$(BUILDEXE)
+HOSTPYTHON= ./$(BUILDPYTHON)
# The task to run while instrument when building the profile-opt target
PROFILE_TASK= $(srcdir)/Tools/pybench/pybench.py -n 2 --with-gc --with-syscheck
@@ -215,6 +216,8 @@
# Parser
PGEN= Parser/pgen$(EXE)
+HOSTPGEN= $(PGEN)
+
POBJS= \
Parser/acceler.o \
Parser/grammar1.o \
@@ -408,8 +411,8 @@
# Build the shared modules
sharedmods: $(BUILDPYTHON)
@case $$MAKEFLAGS in \
- *s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \
- *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py build;; \
+ *s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' PYTHONXCPREFIX='$(DESTDIR)$(prefix)' $(HOSTPYTHON) -E $(srcdir)/setup.py -q build;; \
+ *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' PYTHONXCPREFIX='$(DESTDIR)$(prefix)' $(HOSTPYTHON) -E $(srcdir)/setup.py build;; \
esac
# Build static library
@@ -543,7 +546,7 @@
$(GRAMMAR_H) $(GRAMMAR_C): Parser/pgen.stamp
Parser/pgen.stamp: $(PGEN) $(GRAMMAR_INPUT)
-@$(INSTALL) -d Include
- $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
+ -$(HOSTPGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
-touch Parser/pgen.stamp
$(PGEN): $(PGENOBJS)
@@ -938,26 +941,26 @@
$(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \
$(DESTDIR)$(LIBDEST)/distutils/tests ; \
fi
- PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
+ -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+ ./$(HOSTPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST) -f \
-x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
$(DESTDIR)$(LIBDEST)
- PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
+ -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+ ./$(HOSTPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST) -f \
-x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
$(DESTDIR)$(LIBDEST)
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
+ ./$(HOSTPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
+ ./$(HOSTPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -t -c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"
+ ./$(HOSTPYTHON) -Wi -t -c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"
# Create the PLATDIR source directory, if one wasn't distributed..
$(srcdir)/Lib/$(PLATDIR):
@@ -1062,7 +1065,9 @@
# Install the dynamically loadable modules
# This goes into $(exec_prefix)
sharedinstall: sharedmods
- $(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \
+ CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
+ $(RUNSHARED) $(HOSTPYTHON) -E $(srcdir)/setup.py install \
+ --skip-build \
--prefix=$(prefix) \
--install-scripts=$(BINDIR) \
--install-platlib=$(DESTSHARED) \
diff -ur Python-2.7.3.orig/setup.py Python-2.7.3-Source/setup.py
--- Python-2.7.3.orig/setup.py 2012-04-09 19:07:36.000000000 -0400
+++ Python-2.7.3-Source/setup.py 2012-10-23 14:10:56.085220237 -0400
@@ -145,6 +145,7 @@
def __init__(self, dist):
build_ext.__init__(self, dist)
self.failed = []
+ self.cross_compile = os.environ.get('CROSS_COMPILE_TARGET') == 'yes'
def build_extensions(self):
@@ -278,6 +279,14 @@
(ext.name, sys.exc_info()[1]))
self.failed.append(ext.name)
return
+
+ # Import check will not work when cross-compiling.
+ if os.environ.has_key('PYTHONXCPREFIX'):
+ self.announce(
+ 'WARNING: skipping import check for cross-compiled: "%s"' %
+ ext.name)
+ return
+
# Workaround for Mac OS X: The Carbon-based modules cannot be
# reliably imported into a command-line Python
if 'Carbon' in ext.extra_link_args:
@@ -369,9 +378,10 @@
def detect_modules(self):
# Ensure that /usr/local is always used
- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
- add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
- self.add_multiarch_paths()
+ if not self.cross_compile:
+ add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
+ add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
+ self.add_multiarch_paths()
# Add paths specified in the environment variables LDFLAGS and
# CPPFLAGS for header and library files.
@@ -408,7 +418,8 @@
add_dir_to_list(dir_list, directory)
if os.path.normpath(sys.prefix) != '/usr' \
- and not sysconfig.get_config_var('PYTHONFRAMEWORK'):
+ and not sysconfig.get_config_var('PYTHONFRAMEWORK') \
+ and not self.cross_compile:
# OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework
# (PYTHONFRAMEWORK is set) to avoid # linking problems when
# building a framework with different architectures than
@@ -426,11 +437,23 @@
# lib_dirs and inc_dirs are used to search for files;
# if a file is found in one of those directories, it can
# be assumed that no additional -I,-L directives are needed.
- lib_dirs = self.compiler.library_dirs + [
- '/lib64', '/usr/lib64',
- '/lib', '/usr/lib',
- ]
- inc_dirs = self.compiler.include_dirs + ['/usr/include']
+ lib_dirs = self.compiler.library_dirs
+ inc_dirs = self.compiler.include_dirs
+ if not self.cross_compile:
+ lib_dirs += [
+ '/lib64', '/usr/lib64',
+ '/lib', '/usr/lib',
+ ]
+ inc_dirs += ['/usr/include']
+ else:
+ # The common install prefix of 3rd party libraries used during
+ # cross compilation
+ mydir = os.environ.get('PYTHON_XCOMPILE_DEPENDENCIES_PREFIX')
+ if mydir:
+ inc_dirs += [mydir + '/include' ]
+ inc_dirs += [mydir + '/lib/libffi-3.0.10/include']
+ lib_dirs += [mydir + '/lib' ]
+
exts = []
missing = []
@@ -1004,13 +1027,24 @@
# We hunt for #define SQLITE_VERSION "n.n.n"
# We need to find >= sqlite version 3.0.8
sqlite_incdir = sqlite_libdir = None
- sqlite_inc_paths = [ '/usr/include',
- '/usr/include/sqlite',
- '/usr/include/sqlite3',
- '/usr/local/include',
- '/usr/local/include/sqlite',
- '/usr/local/include/sqlite3',
- ]
+
+ if not self.cross_compile:
+ sqlite_inc_paths = [ '/usr/include',
+ '/usr/include/sqlite',
+ '/usr/include/sqlite3',
+ '/usr/local/include',
+ '/usr/local/include/sqlite',
+ '/usr/local/include/sqlite3',
+ ]
+ else:
+ # The common install prefix of 3rd party headers used during
+ # cross compilation
+ mydir = os.environ.get('PYTHON_XCOMPILE_DEPENDENCIES_PREFIX')
+ if mydir:
+ sqlite_inc_paths = [mydir + '/include' ]
+ else:
+ sqlite_inc_paths = []
+
MIN_SQLITE_VERSION_NUMBER = (3, 0, 8)
MIN_SQLITE_VERSION = ".".join([str(x)
for x in MIN_SQLITE_VERSION_NUMBER])
@@ -1050,12 +1084,22 @@
print "sqlite: %s had no SQLITE_VERSION"%(f,)
if sqlite_incdir:
- sqlite_dirs_to_check = [
- os.path.join(sqlite_incdir, '..', 'lib64'),
- os.path.join(sqlite_incdir, '..', 'lib'),
- os.path.join(sqlite_incdir, '..', '..', 'lib64'),
- os.path.join(sqlite_incdir, '..', '..', 'lib'),
- ]
+ if not self.cross_compile:
+ sqlite_dirs_to_check = [
+ os.path.join(sqlite_incdir, '..', 'lib64'),
+ os.path.join(sqlite_incdir, '..', 'lib'),
+ os.path.join(sqlite_incdir, '..', '..', 'lib64'),
+ os.path.join(sqlite_incdir, '..', '..', 'lib'),
+ ]
+ else:
+ # The common install prefix of 3rd party headers used during
+ # cross compilation
+ mydir = os.environ.get('PYTHON_XCOMPILE_DEPENDENCIES_PREFIX')
+ if mydir:
+ sqlite_dirs_to_check = [mydir + '/lib' ]
+ else:
+ sqlite_dirs_to_check = []
+
sqlite_libfile = self.compiler.find_library_file(
sqlite_dirs_to_check + lib_dirs, 'sqlite3')
if sqlite_libfile:
@@ -1864,8 +1908,15 @@
# Pass empty CFLAGS because we'll just append the resulting
# CFLAGS to Python's; -g or -O2 is to be avoided.
- cmd = "cd %s && env CFLAGS='' '%s/configure' %s" \
- % (ffi_builddir, ffi_srcdir, " ".join(config_args))
+ if self.cross_compile:
+ cmd = "cd %s && env CFLAGS='' %s/configure --host=%s --build=%s %s" \
+ % (ffi_builddir, ffi_srcdir,
+ os.environ.get('HOSTARCH'),
+ os.environ.get('BUILDARCH'),
+ " ".join(config_args))
+ else:
+ cmd = "cd %s && env CFLAGS='' '%s/configure' %s" \
+ % (ffi_builddir, ffi_srcdir, " ".join(config_args))
res = os.system(cmd)
if res or not os.path.exists(ffi_configfile):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment