[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Android support
- From: Marc Balmer <marc@...>
- Date: Mon, 26 Dec 2016 10:33:35 +0100
Am 26.12.16 um 10:29 schrieb Eric Wing:
> On 12/26/16, Marc Balmer <marc@msys.ch> wrote:
>>
>>
>> Am 26.12.16 um 01:34 schrieb Eric Wing:
>>> On 12/25/16, Marc Balmer <marc@msys.ch> wrote:
>>>>
>>>>
>>>> Am 25.12.16 um 20:02 schrieb Thomas Fletcher:
>>>>
>>>>> On Dec 25, 2016 7:02 AM, "Marc Balmer" <marc@msys.ch
>>>>> <mailto:marc@msys.ch>> wrote:
>>>>>>
>>>>>> I am late to the game, but I recently started working on an Android
>>>>>> app
>>>>>> that includes Lua. Fortunately I have quite a bit of experience with
>>>>>> the JNI and several (non Android) projects where Lua is called from
>>>>> Java...
>>>>>>
>>>>>> Now I wonder how other Android/Lua hackers handle 'require' for
>>>>>> modules
>>>>>> written in C/C++. Do you link your modules with Lua into a single
>>>>>> library or do you create several .so files? If the latter, how do you
>>>>>> trick Lua into loading the right shared object?
>>>>>
>>>>> With Storyboard we give the user the ability to list their binary
>>>>> modules and then preload them in the main android application by
>>>>> dlopening the files so that later when we retry within a secondary or
>>>>> tertiary module it succeeds.
>>>>
>>>> Thanks so far. So I am now able to detect the CPU architecture and ABI
>>>> using C preprocessor defines and in theory I can now adjust the
>>>> LUA_CPATH_DEFAULT definition in luaconf.h. But is the APK file actually
>>>> unpacked on the Android device's file system? I.e. can I just adjust
>>>> the CPATH and then use dlopen() to load the module? Or do I have unzip
>>>> the APK first?
>>>>
>>>> I was also considering writing a separate loader that calls
>>>> System.loadLibrary() via the JNI, but then that assumes as "lib" prefix
>>>> on the shared library, which we omit for Lua modules (we often have a C
>>>> library called e.g. libfoobar.so _and_ a Lua binding to it called
>>>> foobar.so).
>>>>
>>>>
>>>
>>> I try to preserve the usual Lua semantics for Android which means
>>> building dynamic libraries. So as you identified, I always use the lib
>>> prefex on Android. But this isn't just for System.loadLibrary(), but
>>> affects what Android does when it encounters your .apk. Android
>>> automatically extracts out the lib*.so files into a special directory
>>> so it is possible to use them. It ignores everything else. CPATH alone
>>> wouldn't help you since the files are not directly on the filesystem,
>>> but archived inside the APK.
>>
>> So it _only_ extracts lib*.so files, and not *.so, right? In that case
>> I will have to prefix my Lua modules with 'lib' which is no big deal.
>
> Yes, you need lib*.so.
> But pay extra attention to the LuaSocket part in that part of the
> talk. There are no subdirectories allowed for libraries so you have to
> do more work for Lua modules that follow the LuaSocket layout
> convention.
Actually we have exactly this "flat" scheme for our modules, no subdirs
luckily (and we don't use LuaSocket, we have our own 'net' module).
>> Do you know the path where it extracts lib*.so files to? If that is
>> known and constant, it could be possible to doctor CPATH so that require
>> loads those using dlopen(). Certainly something I want to give a try.
>
> It's in the preceding slide (33?). However, I forgot to say that you
> should never actually rely on that path. That is a private
> implementation detail and Google has refused to give us a public API
> for the path. Google is also pretty flippant about breaking
> existing/shipping binaries already on the store for those who use the
> NDK. For example, I've heard a surprising number of people were broken
> by the recent changes in the rules for SONAME.
So we should probably use a custom loader that uses the JNI to call
System.loadLibrary() to be safe. That should be quite easy to do.