Class: AndroidProject

Inherits:
BaseProject show all
Defined in:
lib/makeconf/androidproject.rb

Instance Attribute Summary collapse

Attributes inherited from BaseProject

#author, #cc, #config_h, #description, #id, #installer, #license, #license_file, #makefile, #packager, #summary, #version

Instance Method Summary collapse

Methods inherited from BaseProject

#add, #add_binary, #build, #check_decl, #check_function, #check_header, #compiler, #configure, #define, #distfile, #distribute, #finalize, #header, #install, #library, #log, #manpage, #mount, #provides?, #script, #sysdeps, #target, #write_config_h

Constructor Details

#initialize(options) ⇒ AndroidProject

Returns a new instance of AndroidProject.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/makeconf/androidproject.rb', line 8

def initialize(options)
  super(options)

  # Public
  @target_platform = 'android-14'
  @target_arch = 'arm'
  @target_arch_abi = 'armeabi'
  @target_abi = 'armeabi-v7a'
  @ndk_path = nil
  @sdk_path = nil

  # Private
  @prebuilt_libs = []

  # KLUDGE: We need to know the NDK and SDK paths very early on.
  # Peek at the original ARGV to find them.
  Makeconf.original_argv.each do |arg|
    if arg =~ /^--with-ndk=(.*)/
       @ndk_path = $1
    end
    if arg =~ /^--with-sdk=(.*)/
       @sdk_path = $1
    end
  end

  self.ndk_toolchain_version = '4.6'
end

Instance Attribute Details

#target_abiObject

Returns the value of attribute target_abi.



3
4
5
# File 'lib/makeconf/androidproject.rb', line 3

def target_abi
  @target_abi
end

#target_archObject

Returns the value of attribute target_arch.



3
4
5
# File 'lib/makeconf/androidproject.rb', line 3

def target_arch
  @target_arch
end

#target_arch_abiObject

Returns the value of attribute target_arch_abi.



3
4
5
# File 'lib/makeconf/androidproject.rb', line 3

def target_arch_abi
  @target_arch_abi
end

#target_platformObject

Returns the value of attribute target_platform.



3
4
5
# File 'lib/makeconf/androidproject.rb', line 3

def target_platform
  @target_platform
end

Instance Method Details

#ndk_libdirObject

Return the path to the Android NDK /usr/lib



157
158
159
# File 'lib/makeconf/androidproject.rb', line 157

def ndk_libdir
   ndk_sysroot + '/usr/lib/'
end

#ndk_sysrootObject

Return the path to the Android NDK system root



152
153
154
# File 'lib/makeconf/androidproject.rb', line 152

def ndk_sysroot
   @ndk_path + '/platforms/' + @target_platform + '/arch-' + @target_arch
end

#ndk_toolchain_versionObject



54
55
56
# File 'lib/makeconf/androidproject.rb', line 54

def ndk_toolchain_version
  @ndk_toolchain_version
end

#ndk_toolchain_version=(version) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/makeconf/androidproject.rb', line 58

def ndk_toolchain_version=(version)
  @ndk_toolchain_version = version

  ndk_cc = toolchain_binary('gcc')

  #FIXME -overwrites previous Compiler object
  @cc = CCompiler.new(
          :search => ndk_cc
          ) 
  @cc.sysroot = ndk_sysroot
end

#parse_options(opts) ⇒ Object

Parse ARGV options Should only be called from Makeconf.parse_options() Note that ndk_path and sdk_path are previously parsed during initialize()



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/makeconf/androidproject.rb', line 39

def parse_options(opts)
  super(opts)

  opts.separator ""
  opts.separator "Android options:"

  opts.on('--with-ndk=DIRECTORY', "Path to the Android NDK") do |arg|
     @ndk_path = arg
  end
  opts.on('--with-sdk=DIRECTORY', "Path to the Android SDK") do |arg|
     @sdk_path = arg
  end

end

#preconfigureObject



70
71
72
73
74
75
76
77
78
# File 'lib/makeconf/androidproject.rb', line 70

def preconfigure

  printf 'checking for the Android NDK.. '
  throw 'Unable to locate the NDK. Please set the --with-ndk variable to the correct path' if @ndk_path.nil?
  puts @ndk_path
  printf 'checking for the Android SDK.. '
  throw 'Unable to locate the SDK. Please set the --with-sdk variable to the correct path' if @sdk_path.nil?
  puts @sdk_path
end

#to_makeObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/makeconf/androidproject.rb', line 80

def to_make

  write_android_mk
  write_application_mk

  # Generate the ndk-build command
  ndk_build = '$(NDK)/ndk-build V=1 NDK_DEBUG=1 NDK_PROJECT_PATH=.'
  unless @ndk_toolchain_version.nil?
    ndk_build += " NDK_TOOLCHAIN_VERSION=#{@ndk_toolchain_version}"
  end

  mf = super

  mf.define_variable('NDK_LIBDIR', ':=', ndk_libdir)
  mf.define_variable('NDK', '?=', @ndk_path)
  mf.define_variable('SDK', '?=', @sdk_path)
  mf.define_variable('GDB', '?=', toolchain_binary('gdb'))
  mf.define_variable('ADB', '?=', '$(SDK)/platform-tools/adb')
  mf.target('all').rules.push ndk_build
  
  # Copy objects from obj/ to the top level, to match the behavior
  # of non-Android platforms
  # FIXME: this is very crude and should use the actual :output filenames
  #        also, it will only copy libraries and not executables
  #
  mf.target('all').rules.push 'cp obj/local/*/*.a obj/local/*/*.so .'

  # Generate the 'make clean' target
  mf.target('clean').rules = [ ndk_build + ' clean' ]

  # Generate the 'make check' target
  mf.target('check').deps = []        # FIXME: should depend on 'all'
  @build.each do |obj|
    if obj.kind_of?(Test)
      mf.target('check').rules.push([
        '$(ADB) push libs/' + @target_abi + '/' + obj.output + ' /data/local/tmp',
        '$(ADB) shell chmod 751 /data/local/tmp/' + obj.output,
        '$(ADB) shell /data/local/tmp/' + obj.output,
        '$(ADB) shell rm /data/local/tmp/' + obj.output
        ])
    end
  end

  # Run a $(BINARY) under the Android debugger
  # see: http://www.kandroid.org/online-pdk/guide/debugging_gdb.html
  mf.add_target('debug', [], [
       '$(ADB) forward tcp:5039 tcp:5039',
       '$(ADB) push $(BINARY) /data/local/tmp',
       '$(ADB) shell chmod 751 /data/local/tmp/`basename $(BINARY)`',
       '$(ADB) shell gdbserver :5039 /data/local/tmp/`basename $(BINARY)` &',
       'sleep 2', # give gdbserver time to start

        # Pull things from the device that are needed for debugging
        '$(ADB) pull /system/bin/linker obj/local/armeabi/linker',
        '$(ADB) pull /system/lib/libc.so obj/local/armeabi/libc.so',
        '$(ADB) pull /system/lib/libm.so obj/local/armeabi/libm.so',
        '$(ADB) pull /system/lib/libstdc++.so obj/local/armeabi/libstdc++.so',

       'echo "set solib-search-path obj/local/armeabi" > .gdb-commands',
       'echo "target remote :5039" >> .gdb-commands',
       '$(GDB) -x .gdb-commands $(BINARY)',
       'rm .gdb-commands',
       ])

  # Connect to the device and run a shell
  # TODO: add to makeconf
  mf.add_target('shell', [], [ '$(ADB) shell' ])

  mf
end