With the attached patches cherry-picked from upstream 0.4.0, I was able to build Julia for armhf in Jessie and Sid schroots. The resultant binaries seem to run fine on a Debian porterbox and on an NVIDIA Jetson TK1, although so far I have only tried some simple Julia examples.
Included here is an updated version of make-patchelf-redundant.patch from bug #799099.
series
Description: Binary data
Description: Decide whether to build patchelf based on USE_SYSTEM_PATCHELF That way in distributions where the same tree structure is used for build and install, where patchelf is not used, we don't need to install it. Origin: upstream, https://github.com/JuliaLang/julia/commit/ccdc4b69a9a7ca06122dbdaf077d811680ca5e68 Author: Milan Bouchet-Valat <[email protected]> Last-Update: 2015-03-21 --- a/Make.inc +++ b/Make.inc @@ -37,6 +37,7 @@ USE_SYSTEM_RMATH=0 USE_SYSTEM_LIBUV=0 USE_SYSTEM_UTF8PROC=0 +USE_SYSTEM_PATCHELF=0 # Link to the LLVM shared library USE_LLVM_SHLIB = 0 --- a/deps/Makefile +++ b/deps/Makefile @@ -43,7 +43,7 @@ endif ifeq ($(OS), Linux) -ifeq ($(shell which patchelf 2>/dev/null),) +ifeq ($(USE_SYSTEM_PATCHELF), 0) STAGE1_DEPS += patchelf PATCHELF=$(build_bindir)/patchelf else
Description: Make patchelf redundant Build in the multiarch lib directories as well so that $(private_libdir_rel) = $(build_private_libdir_rel) and patchelf does not get run. Author: Graham Inggs <[email protected]> Forwarded: https://github.com/JuliaLang/julia/pull/13163 Last-Update: 2015-09-16 --- a/Make.inc +++ b/Make.inc @@ -120,8 +120,10 @@ # This used for debian packaging, to conform to library layout guidelines ifeq ($(MULTIARCH_INSTALL), 1) MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) -private_libdir = $(prefix)/lib/$(MULTIARCH)/julia -libdir = $(prefix)/lib/$(MULTIARCH)/ +libdir = $(prefix)/lib/$(MULTIARCH) +private_libdir = $(libdir)/julia +build_libdir = $(build_prefix)/lib/$(MULTIARCH) +build_private_libdir = $(build_libdir)/julia endif
Description: ARM: use 8-byte alignment (fixes #8314) Author: Isaiah Norton <[email protected]> 2014-10-28 04:32:33 Committer: Isaiah Norton <[email protected]> 2014-10-28 05:02:58 SHA: b3ff2cd0c9c04f86c5de58383f2624c92a52307a --- a/src/julia.h +++ b/src/julia.h @@ -23,6 +23,20 @@ # include <malloc.h> //for _resetstkoflw # define MAX_ALIGN 8 #endif +#include <setjmp.h> +#ifndef _OS_WINDOWS_ +# define jl_jmp_buf sigjmp_buf +# define MAX_ALIGN sizeof(void*) +# if defined(__arm__) +# define MAX_ALIGN 8 +# else +# define MAX_ALIGN sizeof(void*) +# endif +#else +# define jl_jmp_buf jmp_buf +# include <malloc.h> //for _resetstkoflw +# define MAX_ALIGN 8 +#endif #ifdef _P64 #define NWORDS(sz) (((sz)+7)>>3)
Description: improve support for building on PPC Origin: upstream, https://github.com/JuliaLang/julia/commit/ee5d1994556deaa28d1c9c3e0e2ced4a93a087ea Author: Jameson Nash <[email protected]> Last-update: 2015-03-29 --- a/src/sys.c +++ b/src/sys.c @@ -3,6 +3,7 @@ I/O and operating system utility functions */ #include "julia.h" +#include "julia_internal.h" #include "uv.h" #include <sys/stat.h> #include <stdlib.h> @@ -411,6 +412,7 @@ // CPUID +#ifdef HAVE_CPUID DLLEXPORT void jl_cpuid(int32_t CPUInfo[4], int32_t InfoType) { #if defined _MSC_VER @@ -433,6 +435,7 @@ ); #endif } +#endif // -- set/clear the FZ/DAZ flags on x86 & x86-64 -- #ifdef __SSE__ --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -131,6 +131,10 @@ // Returns time in nanosec DLLEXPORT uint64_t jl_hrtime(void); +#if defined(_CPU_X86_) || defined(_CPU_X86_64_) +#define HAVE_CPUID +#endif + #ifdef __cplusplus } #endif --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -252,9 +252,11 @@ return it->second.index; } +#ifdef HAVE_CPUID extern "C" { extern void jl_cpuid(int32_t CPUInfo[4], int32_t InfoType); } +#endif static void jl_gen_llvm_gv_array() { @@ -284,6 +286,7 @@ feature_string, "jl_sysimg_cpu_target"); +#ifdef HAVE_CPUID // For native also store the cpuid if (strcmp(jl_compileropts.cpu_target,"native") == 0) { uint32_t info[4]; @@ -296,6 +299,7 @@ ConstantInt::get(T_int64,((uint64_t)info[2])|(((uint64_t)info[3])<<32)), "jl_sysimg_cpu_cpuid"); } +#endif } static int32_t jl_assign_functionID(Function *functionObject) --- a/src/dump.c +++ b/src/dump.c @@ -100,8 +100,11 @@ static jl_value_t *jl_deserialize_value_internal(ios_t *s); jl_value_t ***sysimg_gvars = NULL; -extern int globalUnique; +#ifdef HAVE_CPUID extern void jl_cpuid(int32_t CPUInfo[4], int32_t InfoType); +#endif + +extern int globalUnique; uv_lib_t *jl_sysimg_handle = NULL; uint64_t jl_sysimage_base = 0; #ifdef _OS_WINDOWS_ @@ -124,6 +127,7 @@ if (strcmp(cpu_target,jl_compileropts.cpu_target) != 0) jl_error("Julia and the system image were compiled for different architectures.\n" "Please delete or regenerate sys.{so,dll,dylib}.\n"); +#ifdef HAVE_CPUID uint32_t info[4]; jl_cpuid((int32_t*)info, 1); if (strcmp(cpu_target, "native") == 0) { @@ -137,6 +141,8 @@ jl_error("The current host does not support SSSE3, but the system image was compiled for Core2.\n" "Please delete or regenerate sys.{so,dll,dylib}.\n"); } +#endif + #ifdef _OS_WINDOWS_ jl_sysimage_base = (intptr_t)jl_sysimg_handle->handle; #else --- a/Make.inc +++ b/Make.inc @@ -437,25 +437,59 @@ ifeq ($(ARCH),i386) BINARY=32 +ISX86=1 else ifeq ($(ARCH),i387) BINARY=32 +ISX86=1 else ifeq ($(ARCH),i486) BINARY=32 +ISX86=1 else ifeq ($(ARCH),i586) BINARY=32 +ISX86=1 else ifeq ($(ARCH),i686) BINARY=32 +ISX86=1 else ifeq ($(ARCH),x86_64) BINARY=64 +ISX86=1 +else ifneq (,$(findstring arm,$(ARCH))) +ISX86=0 +else ifneq (,$(findstring powerpc,$(ARCH))) +ISX86=0 +else ifneq (,$(findstring ppc,$(ARCH))) +ISX86=0 else $(error "unknown word-size for arch: $(ARCH)") endif + +# If we are running on ARM, set certain options automatically +ifneq (,$(findstring arm,$(ARCH))) +JCFLAGS += -fsigned-char + +#LLVM_ASSERTIONS=1 +#LLVM_FLAGS+="--with-float=hard --with-abi=aapcs-vfp" +#LLVM_VER=3.6.1 + +override USE_BLAS64=0 +override OPENBLAS_DYNAMIC_ARCH=0 +override OPENBLAS_TARGET_ARCH=ARMV7 + +endif + +# Set some ARCH-specific flags +ifneq ($(USEICC),1) +ifeq ($(ISX86),1) CC += -m$(BINARY) CXX += -m$(BINARY) FC += -m$(BINARY) +CC_ARG += -m$(BINARY) +CXX_ARG += -m$(BINARY) +endif +endif ifeq ($(USEGCC),1) -ifneq ($(ARCH), ppc64) +ifeq ($(ISX86),1) SHIPFLAGS += -momit-leaf-frame-pointer endif endif --- a/deps/Makefile +++ b/deps/Makefile @@ -1114,6 +1114,9 @@ done endif touch -c $@ +ifneq ($(PATCHELF),patchelf) +$(ARPACK_OBJ_TARGET): $(PATCHELF) +endif clean-arpack: -$(MAKE) -C arpack-ng-$(ARPACK_VER) clean --- a/src/support/platform.h +++ b/src/support/platform.h @@ -77,6 +77,10 @@ #define _CPU_X86_ #elif defined(__arm__) || defined(_M_ARM) #define _CPU_ARM_ +#elif defined(__PPC64__) +#define _CPU_PPC64_ +#elif defined(_ARCH_PPC) +#define _CPU_PPC_ #endif #if defined(_CPU_X86_64_) @@ -90,12 +94,10 @@ # else # define _P32 # endif -#elif defined(_COMPILER_GCC_) -# if __x86_64__ || __ppc64__ +#elif __SIZEOF_POINTER__ == 8 # define _P64 -# else +#elif __SIZEOF_POINTER__ == 4 # define _P32 -# endif #else # error pointer size not known for your platform / compiler #endif
Description: ARM: force on +vfp2 (ref #11817, ref #10602) this seems likely to be a better default for the majority of users. plus the failure mode is a SIGILL, rather than random data getting returned from floating point computations Author: Jameson Nash <[email protected]> 2015-07-08 05:59:31 Committer: Jameson Nash <[email protected]> 2015-07-08 08:05:45 SHA: 378ab7ce3d627cdb1b44ac61220079113df57192 Also https://github.com/JuliaLang/julia/commit/896cadf4555efcc42478780bf30fcc1376d879fa --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4574,6 +4574,7 @@ jl_mcjmm = new SectionMemoryManager(); #endif const char *mattr[] = { +#if defined(_CPU_X86_64_) || defined(_CPU_X86_) #ifndef USE_MCJIT // Temporarily disable Haswell BMI2 features due to LLVM bug. "-bmi2", "-avx2", @@ -4581,6 +4582,10 @@ #ifdef V128_BUG "-avx", #endif +#endif +#ifdef _CPU_ARM_ + "+vfp2", // the processors that don't have VFP are old and (hopefully) rare. this affects the $ +#endif #if defined(USE_MCJIT) && !defined(V128_BUG) // Prevent zero-sized array error ""
Description: copy module before running llvm codegen output passes (fix #11878) llvm may modify the Module during codegen output (as was observed to happen on ARM), so it is better to run the code emission passes on a copy rather than the actual shadow module Origin: Upstream, https://github.com/JuliaLang/julia/commit/24d990ce3525fefd0318959500bced4ef611591c Origin: Upstream, https://github.com/JuliaLang/julia/commit/050eedb5ff0a072cb05e91ac6e827e8322ba2c2b Author: Keno Fischer <[email protected]> Author: Jameson Nash <[email protected]> Last-Update: 2015-07-08 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -375,7 +375,7 @@ }; // --- helpers for reloading IR image -static void jl_gen_llvm_gv_array(); +static void jl_gen_llvm_gv_array(llvm::Module *mod); extern "C" void jl_dump_bitcode(char *fname) @@ -386,11 +386,14 @@ #else raw_fd_ostream OS(fname, err); #endif - jl_gen_llvm_gv_array(); #ifdef USE_MCJIT - WriteBitcodeToFile(shadow_module, OS); -#else - WriteBitcodeToFile(jl_Module, OS); + Module *bitcode = CloneModule(shadow_module); + jl_gen_llvm_gv_array(bitcode); + WriteBitcodeToFile(bitcode, OS); +#else + Module *bitcode = CloneModule(jl_Module); + jl_gen_llvm_gv_array(bitcode); + WriteBitcodeToFile(bitcode, OS); #endif } @@ -404,7 +407,6 @@ raw_fd_ostream OS(fname, err); #endif formatted_raw_ostream FOS(OS); - jl_gen_llvm_gv_array(); // We don't want to use MCJIT's target machine because // it uses the large code model and we may potentially @@ -454,9 +456,13 @@ } #ifdef USE_MCJIT - PM.run(*shadow_module); -#else - PM.run(*jl_Module); + Module *objfile = CloneModule(shadow_module); + jl_gen_llvm_gv_array(objfile); + PM.run(*objfile); +#else + Module *objfile = CloneModule(jl_Module); + jl_gen_llvm_gv_array(objfile); + PM.run(*objfile); #endif } --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -258,20 +258,20 @@ } #endif -static void jl_gen_llvm_gv_array() +static void jl_gen_llvm_gv_array(llvm::Module *mod) { // emit the variable table into the code image (can only call this once) // used just before dumping bitcode ArrayType *atype = ArrayType::get(T_psize,jl_sysimg_gvars.size()); new GlobalVariable( - *jl_Module, + *mod, atype, true, GlobalVariable::ExternalLinkage, ConstantArray::get(atype, ArrayRef<Constant*>(jl_sysimg_gvars)), "jl_sysimg_gvars"); new GlobalVariable( - *jl_Module, + *mod, T_size, true, GlobalVariable::ExternalLinkage, @@ -279,7 +279,7 @@ "jl_globalUnique"); Constant *feature_string = ConstantDataArray::getString(jl_LLVMContext, jl_compileropts.cpu_target); - new GlobalVariable(*jl_Module, + new GlobalVariable(*mod, feature_string->getType(), true, GlobalVariable::ExternalLinkage, @@ -292,7 +292,7 @@ uint32_t info[4]; jl_cpuid((int32_t*)info, 1); - new GlobalVariable(*jl_Module, + new GlobalVariable(*mod, T_int64, true, GlobalVariable::ExternalLinkage,
Description: fix #12082 codegen was missing a MapValue call when copying the jl_sysimg_gvars array into the output module, resulting in this array pointing to the wrong module Origin: upstream, https://github.com/JuliaLang/julia/commit/eb614d909fdfd93e4294a78d6e1fe89bebefdba4 Author: Jameson Nash <[email protected]> Last-Update: 2015-07-13 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -258,7 +258,7 @@ } #endif -static void jl_gen_llvm_gv_array(llvm::Module *mod) +static void jl_gen_llvm_gv_array(llvm::Module *mod, ValueToValueMapTy &VMap) { // emit the variable table into the code image (can only call this once) // used just before dumping bitcode @@ -268,7 +268,7 @@ atype, true, GlobalVariable::ExternalLinkage, - ConstantArray::get(atype, ArrayRef<Constant*>(jl_sysimg_gvars)), + MapValue(ConstantArray::get(atype, ArrayRef<Constant*>(jl_sysimg_gvars)), VMap), "jl_sysimg_gvars"); new GlobalVariable( *mod, --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -375,7 +375,7 @@ }; // --- helpers for reloading IR image -static void jl_gen_llvm_gv_array(llvm::Module *mod); +static void jl_gen_llvm_gv_array(llvm::Module *mod, ValueToValueMapTy &VMap); extern "C" void jl_dump_bitcode(char *fname) @@ -386,15 +386,14 @@ #else raw_fd_ostream OS(fname, err); #endif + ValueToValueMapTy VMap; #ifdef USE_MCJIT - Module *bitcode = CloneModule(shadow_module); - jl_gen_llvm_gv_array(bitcode); - WriteBitcodeToFile(bitcode, OS); + Module *bitcode = CloneModule(shadow_module, VMap); #else - Module *bitcode = CloneModule(jl_Module); - jl_gen_llvm_gv_array(bitcode); - WriteBitcodeToFile(bitcode, OS); + Module *bitcode = CloneModule(jl_Module, VMap); #endif + jl_gen_llvm_gv_array(bitcode, VMap); + WriteBitcodeToFile(bitcode, OS); } extern "C" @@ -455,15 +454,14 @@ jl_error("Could not generate obj file for this target"); } + ValueToValueMapTy VMap; #ifdef USE_MCJIT - Module *objfile = CloneModule(shadow_module); - jl_gen_llvm_gv_array(objfile); - PM.run(*objfile); + Module *objfile = CloneModule(shadow_module, VMap); #else - Module *objfile = CloneModule(jl_Module); - jl_gen_llvm_gv_array(objfile); - PM.run(*objfile); + Module *objfile = CloneModule(jl_Module, VMap); #endif + jl_gen_llvm_gv_array(objfile, VMap); + PM.run(*objfile); } // aggregate of array metadata
Description: Define all other architectures as "not x86" This allows the build to proceed for AArch64 (mentioned in #10791) and others. Author: Graham Inggs <[email protected]> Forwarded: https://github.com/JuliaLang/julia/pull/13558 Last-Update: 2015-10-12 --- a/Make.inc +++ b/Make.inc @@ -453,14 +453,9 @@ else ifeq ($(ARCH),x86_64) BINARY=64 ISX86=1 -else ifneq (,$(findstring arm,$(ARCH))) -ISX86=0 -else ifneq (,$(findstring powerpc,$(ARCH))) -ISX86=0 -else ifneq (,$(findstring ppc,$(ARCH))) -ISX86=0 else -$(error "unknown word-size for arch: $(ARCH)") +# For all other architectures (ARM, PPC, AArch64, etc.) +ISX86=0 endif # If we are running on ARM, set certain options automatically

