summaryrefslogtreecommitdiffhomepage
path: root/tasks/toolchains
diff options
context:
space:
mode:
authorFelix Jones <[email protected]>2016-09-15 15:57:44 +0100
committerFelix Jones <[email protected]>2016-09-15 15:57:44 +0100
commit18662ff57653a8e795c43ff9d102ece0478505b3 (patch)
tree4cee58f9f4494c6df430507833b0598a2620fcf9 /tasks/toolchains
parent08a1dd2ac89333bd928a3300f712d1a7fb57e8ff (diff)
downloadmruby-18662ff57653a8e795c43ff9d102ece0478505b3.tar.gz
mruby-18662ff57653a8e795c43ff9d102ece0478505b3.zip
Re-written android.rake task for latest Android NDK clang. Currently loses support for GCC and mips, mips64. Addresses issue #3208
Diffstat (limited to 'tasks/toolchains')
-rw-r--r--tasks/toolchains/android.rake304
1 files changed, 158 insertions, 146 deletions
diff --git a/tasks/toolchains/android.rake b/tasks/toolchains/android.rake
index aadc5b3cc..4febe4882 100644
--- a/tasks/toolchains/android.rake
+++ b/tasks/toolchains/android.rake
@@ -1,16 +1,21 @@
class MRuby::Toolchain::Android
- DEFAULT_ARCH = 'armeabi'
- DEFAULT_PLATFORM = 'android-14'
- DEFAULT_TOOLCHAIN = :gcc
+
+ DEFAULT_ARCH = 'armeabi' # TODO : Revise if arch should have a default
+
+ DEFAULT_TOOLCHAIN = :clang
+
DEFAULT_NDK_HOMES = %w{
/usr/local/opt/android-ndk
+ /usr/local/opt/android-sdk/ndk-bundle
+ %LOCALAPPDATA%/Android/android-sdk/ndk-bundle
}
- TOOLCHAINS = [:gcc, :clang]
+
+ TOOLCHAINS = [:clang] # TODO : Add gcc support
+
ARCHITECTURES = %w{
armeabi armeabi-v7a arm64-v8a
- mips mips64
x86 x86_64
- }
+ } # TODO : Add mips mips64 support
class AndroidNDKHomeNotFound < StandardError
def message
@@ -21,196 +26,203 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter
end
end
+ class PlatformDirNotFound < StandardError
+ def message
+ <<-EOM
+Couldn't find Android NDK platform directories.
+Set ANDROID_PLATFORM environment variable or set :platform parameter
+ EOM
+ end
+ end
+
attr_reader :params
def initialize(params)
@params = params
end
- def home_path
- @home_path ||= Pathname(
- params[:ndk_home] ||
- ENV['ANDROID_NDK_HOME'] ||
- DEFAULT_NDK_HOMES.find{ |path| File.directory?(path) } ||
- raise(AndroidNDKHomeNotFound)
- )
+ def bin_gcc(command)
+ case toolchain
+ when :gcc then bin(command)
+ when :clang
+ command = command.to_s
+
+ command = case arch
+ when /armeabi/, /armeabi-v7a/ then 'arm-linux-androideabi-'
+ when /arm64-v8a/ then 'aarch64-linux-android-'
+ when /x86/ then 'i686-linux-android-'
+ when /x86_64/ then 'x86_64-linux-android-'
+ when /mips/ then 'mipsel-linux-android-'
+ when /mips64/ then 'mips64el-linux-android-'
+ end + command
+
+ prefix = case arch
+ when /armeabi/, /armeabi-v7a/ then 'arm-linux-androideabi-'
+ when /arm64-v8a/ then 'aarch64-linux-android-'
+ when /x86/ then 'x86-'
+ when /x86_64/ then 'x86_64-'
+ when /mips/ then 'mipsel-linux-android-'
+ when /mips64/ then 'mips64el-linux-android-'
+ end
+
+ test = case arch
+ when /armeabi/, /armeabi-v7a/ then 'arm-linux-androideabi-*'
+ when /arm64-v8a/ then 'aarch64-linux-android-*'
+ when /x86/ then 'x86-*'
+ when /x86_64/ then 'x86_64-*'
+ when /mips/ then 'mipsel-linux-android-*'
+ when /mips64/ then 'mips64el-linux-android-*'
+ end
+
+ gcc_toolchain_version = Dir[home_path.join('toolchains', test)].map{|t| t.match(/-(\d+\.\d+)$/); $1.to_f }.max
+ gcc_toolchain_path = home_path.join('toolchains', prefix + gcc_toolchain_version.to_s, 'prebuilt', host_platform)
+ gcc_toolchain_path.join('bin', command).to_s
+ end
end
- def arch
- params.fetch(:arch){ DEFAULT_ARCH }
+ def bin(command)
+ command = command.to_s
+ toolchain_path.join('bin', command).to_s
end
- def platform
- params.fetch(:platform){ DEFAULT_PLATFORM }
+ def home_path
+ @home_path ||= Pathname(
+ params[:ndk_home] ||
+ ENV['ANDROID_NDK_HOME'] ||
+ DEFAULT_NDK_HOMES.find { |path|
+ path.gsub! '%LOCALAPPDATA%', ENV['LOCALAPPDATA'] || '%LOCALAPPDATA%'
+ path.gsub! '\\', '/'
+ File.directory?(path)
+ } || raise(AndroidNDKHomeNotFound)
+ )
end
def toolchain
- params.fetch(:toolchain){ DEFAULT_TOOLCHAIN }
+ @toolchain ||= params.fetch(:toolchain){ DEFAULT_TOOLCHAIN }
end
- def toolchain_version
- params.fetch(:toolchain_version) do
- test = case toolchain
- when :gcc
- case arch
- when /armeabi/
- 'arm-linux-androideabi-*'
- when /arm64/
- 'aarch64-linux-android-*'
- when /mips64/
- 'mips64el-linux-android-*'
- when /mips/
- 'mipsel-linux-android-*'
- when /x86_64/
- 'x86_64-*'
- when /x86/
- 'x86-*'
- end
+ def toolchain_path
+ @toolchain_path ||= case toolchain
when :clang
- 'llvm-*'
+ home_path.join('toolchains', 'llvm' , 'prebuilt', host_platform)
end
+ end
- Dir[home_path.join('toolchains',test)].map{|t| t.match(/-(\d+\.\d+)$/); $1.to_f }.max
- end
+ def host_platform
+ @host_platform ||= case RUBY_PLATFORM
+ when /cygwin|mswin|mingw|bccwin|wince|emx/i
+ path = home_path.join('toolchains', 'llvm' , 'prebuilt', 'windows*')
+ Dir.glob(path.to_s){ |item|
+ next if File.file?(item)
+ path = Pathname(item)
+ break
+ }
+ path.basename
+ when /x86_64-darwin/i
+ 'darwin-x86_64'
+ when /darwin/i
+ 'darwin-x86'
+ when /x86_64-linux/i
+ 'linux-x86_64'
+ when /linux/i
+ 'linux-x86'
+ else
+ raise NotImplementedError, "Unknown host platform (#{RUBY_PLATFORM})"
+ end
end
- def toolchain_path
- prefix = case toolchain
- when :clang then 'llvm-'
- when :gcc
- case arch
- when /armeabi/ then 'arm-linux-androideabi-'
- when /arm64/ then 'aarch64-linux-android-'
- when /x86_64/ then 'x86_64-'
- when /x86/ then 'x86-'
- when /mips64/ then 'mips64el-linux-android-'
- when /mips/ then 'mipsel-linux-android-'
- end
- end
- home_path.join('toolchains', prefix + toolchain_version.to_s, 'prebuilt', host_platform)
+ def arch
+ @arch ||= (params[:arch] || ENV['ANDROID_ARCH'] || DEFAULT_ARCH).to_s
end
def sysroot
- path = case arch
- when /armeabi/ then 'arch-arm'
- when /arm64/ then 'arch-arm64'
- when /x86_64/ then 'arch-x86_64'
- when /x86/ then 'arch-x86'
- when /mips64/ then 'arch-mips64'
- when /mips/ then 'arch-mips'
- end
-
- home_path.join('platforms', platform, path).to_s
+ @sysroot ||= home_path.join('platforms', platform,
+ case arch
+ when /armeabi/, /armeabi-v7a/ then 'arch-arm'
+ when /arm64-v8a/ then 'arch-arm64'
+ when /x86/ then 'arch-x86'
+ when /x86_64/ then 'arch-x86_64'
+ when /mips/ then 'arch-mips'
+ when /mips64/ then 'arch-mips64'
+ end
+ ).to_s
end
- def bin(command)
- command = command.to_s
-
- if toolchain == :gcc
- command = case arch
- when /armeabi/ then 'arm-linux-androideabi-'
- when /arm64/ then 'aarch64-linux-android-'
- when /x86_64/ then 'x86_64-linux-android-'
- when /x86/ then 'i686-linux-android-'
- when /mips64/ then 'mips64el-linux-android-'
- when /mips/ then 'mipsel-linux-android-'
- end + command
+ def platform
+ if @platform === nil then
+ @platform = params[:platform] || ENV['ANDROID_PLATFORM'] || nil
+ if @platform === nil
+ Dir.glob(home_path.join('platforms/android-*').to_s){ |item|
+ next if File.file?(item)
+ if @platform === nil
+ @platform = Integer(item.rpartition('-')[2])
+ else
+ platform = Integer(item.rpartition('-')[2])
+ @platform = platform > @platform ? platform : @platform
+ end
+ }
+ if @platform === nil
+ raise(PlatformDirNotFound)
+ else
+ @platform = "android-#{@platform}"
+ end
+ end
end
-
- toolchain_path.join('bin',command).to_s
+ if Integer(@platform.rpartition('-')[2]) < 21
+ case arch
+ when /arm64-v8a/, /x86_64/, /mips64/
+ raise NotImplementedError, "Platform (#{@platform}) has no implementation for architecture (#{arch})"
+ end
+ end
+ @platform
end
def cc
case toolchain
- when :gcc then bin(:gcc)
- when :clang then bin(:clang)
+ when :clang then bin('clang')
end
end
- def cflags
- flags = []
-
+ def ar
case toolchain
- when :gcc
- flags += %W(-ffunction-sections -funwind-tables -no-canonical-prefixes)
- flags += %W(-D__android__ -mandroid --sysroot="#{sysroot}")
- case arch
- when /arm64/
- flags += %W(-fpic -fstack-protector-strong)
- when 'armeabi-v7a-hard'
- flags += %W(-fpic -fstack-protector-strong -march=armv7-a -mhard-float -D_NDK_MATH_NO_SOFTFP=1 -mfpu=vfpv3-d16)
- when 'armeabi-v7a'
- flags += %W(-fpic -fstack-protector-strong -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16)
- when /arm/
- flags += %W(-fpic -fstack-protector-strong -march=armv5te -mtune=xscale -msoft-float)
- when /mips/
- flags += %W(-fpic -fno-strict-aliasing -finline-functions -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers)
- when /x86/
- flags += %W(-fstack-protector-strong)
- end
- when :clang
+ when :clang then bin_gcc('ar')
end
-
- flags
- end
-
- def ld
- cc
end
- def ldflags
+ def cflags
flags = []
+
+ flags += %W(-D__android__ --sysroot="#{sysroot}")
case toolchain
- when :gcc
- flags += %W(-no-canonical-prefixes)
- flags += %W(-D__android__ -mandroid --sysroot="#{sysroot}")
+ when :clang
+ flags += %W(-gcc-toolchain #{toolchain_path.to_s})
case arch
- when 'armeabi-v7a-hard'
- flags += %W(-march=armv7-a -Wl,--fix-cortex-a8 -Wl,--no-warn-mismatch -lm_hard)
- when 'armeabi-v7a'
- flags += %W(-march=armv7-a -Wl,--fix-cortex-a8)
+ when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi)
+ when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi)
+ when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android)
+ when /x86/ then flags += %W(-target i686-none-linux-android)
+ when /x86_64/ then flags += %W(-target x86_64-none-linux-android)
+ when /mips/ then flags += %W(-target mipsel-none-linux-android)
+ when /mips64/ then flags += %W(-target mips64el-none-linux-android)
end
end
-
- flags
- end
- def ar
- case toolchain
- when :gcc then bin(:ar)
- when :clang then bin('llvm-ar')
- end
+ flags
end
- def host_platform
- case RUBY_PLATFORM
- when /cygwin|mswin|mingw|bccwin|wince|emx/i
- 'windows'
- when /x86_64-darwin/i
- 'darwin-x86_64'
- when /darwin/i
- 'darwin-x86'
- when /x86_64-linux/i
- 'linux-x86_64'
- when /linux/i
- 'linux-x86'
- else
- raise NotImplementedError, "Unknown host platform (#{RUBY_PLATFORM})"
- end
- end
end
MRuby::Toolchain.new(:android) do |conf, params|
- ndk = MRuby::Toolchain::Android.new(params)
+ android = MRuby::Toolchain::Android.new(params)
- toolchain ndk.toolchain
+ toolchain android.toolchain
[conf.cc, conf.cxx, conf.objc, conf.asm].each do |cc|
- cc.command = ndk.cc
- cc.flags = ndk.cflags
+ cc.command = android.cc
+ cc.flags = android.cflags
end
- conf.linker.command = ndk.ld
- conf.linker.flags = ndk.ldflags
- conf.archiver.command = ndk.ar
-end
+ conf.archiver.command = android.ar
+ conf.linker.command = android.cc
+ conf.linker.flags = []
+end