Lazarus

Programming => Operating Systems => Android => Topic started by: chronozphere on October 31, 2011, 12:32:00 am

Title: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on October 31, 2011, 12:32:00 am
Hey guys,

I've ran into an issue here during my android expiriments.

I want to cross compile a library dpr to ARM to be able to use it with JNI on android. Below you will see a tiny example that reproduces the problem I'm facing now:

Code: [Select]
library hellojni;

uses
  SysUtils,
  JNI;

function Java_com_example_hellojni_HelloJni_stringFromJNI(PEnv: PJNIEnv; this: JObject): JString;
begin
    Result := (PEnv^).NewStringUTF(PEnv, 'Hello from JNI !');
end;

exports Java_com_example_hellojni_HelloJni_stringFromJNI;

end.

When I use the following command (please yell if this command is wrong somehow):
Code: [Select]
fpc -Tlinux -Parm -XParm-linux- hello-jni.dpr

I get:
Code: [Select]
Free Pascal Compiler version 2.7.1 [2011/10/27] for arm
Copyright (c) 1993-2011 by Florian Klaempfl and others
Target OS: Linux for ARMEL
Compiling hello-jni.dpr
Assembling hellojni
Linking libhello-jni.so
/usr/local/bin/arm-linux-ld: warning: link.res contains output sections; did you forget -T?
/usr/local/bin/arm-linux-ld: cannot find /lib/ld-linux.so.3
hello-jni.dpr(9,60) Error: Error while linking
hello-jni.dpr(9,60) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/local/bin/ppcarm returned an error exitcode (normal if you did not specify a source file to be compiled)

So there is a /lib/ld-linux.so.3 file which is nowhere to be found.
Code: [Select]
ls -al /lib | grep ld
gives
Code: [Select]
-rwxr-xr-x  1 root root  113964 Jan 22  2011 ld-2.11.1.so
lrwxrwxrwx  1 root root      12 Feb  2  2011 ld-linux.so.2 -> ld-2.11.1.s

So I only have version 2. I'm running Ubuntu 10.04 here.

Some extra research led me to the following website:

http://wiki.maemo.org/Compile_FreePascal_on_device (http://wiki.maemo.org/Compile_FreePascal_on_device)

Which mentions the t_linux.pas, which is part of FPC, and refers to ld-linux.so.3. The source:
Code: [Select]
{$ifdef arm}
{$ifdef FPC_ARMEL}
     defdynlinker:='/lib/ld-linux.so.3';
{$else FPC_ARMEL}
     defdynlinker:='/lib/ld-linux.so.2';
{$endif FPC_ARMEL}
{$endif arm}

So in my case FPC_ARMEL is defined, so it selects v3. This makes sense, because this is how I've build my cross compiler:

http://wiki.lazarus.freepascal.org/Setup_Cross_Compile_For_ARM (http://wiki.lazarus.freepascal.org/Setup_Cross_Compile_For_ARM)

Code: [Select]
sudo make crossinstall CPU_TARGET=arm OS_TARGET=linux CROSSBINDIR=/home/user/lazarus/fpc/binutils/ OPT=-dFPC_ARMEL INSTALL_PREFIX=/usr

So what's up here? Should I just dive in the source and change the number and rebuild my ppcarm?

Please help me find the best solution here.

Thanks a bunch! :)



Can somebody please help me out here? I'm almost there. :(

Thanks!
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Laksen on October 31, 2011, 01:02:11 am
Doesn't the Android NDK have this file, or something like it?
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on October 31, 2011, 01:08:50 am
Well, when I go into the NDK directory and do find . -iname ld* I get:
Code: [Select]
nathan@nathan-PC android-ndk-r6b $ find . -iname ld*
./platforms/android-9/arch-x86/usr/include/asm/ldt.h
./toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/arm-linux-androideabi/lib/ldscripts
./toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/arm-linux-androideabi/bin/ld
./toolchains/x86-4.4.3/prebuilt/linux-x86/i686-android-linux/lib/ldscripts
./toolchains/x86-4.4.3/prebuilt/linux-x86/i686-android-linux/bin/ld

I did "ld -v" for both of them and they are version 2.20.1. Should I do anything with these?
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Laksen on October 31, 2011, 01:34:47 am
Those are executable binaries of the binutils linker, ld. That's not what you are looking for

It needs to link to ld-linux.so.3 for the target platform, not your host platform. Try to remove sysutils from the uses clause and see if that changes anything. I don't remember ld-linux.so being a normal dependency unless you rely on dynamic linking
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: herux on October 31, 2011, 05:54:55 am
I hope this can help.
do this :

#apt-file search ld-linux.so.3

result on my ubuntu 11.10

libc6-armel-cross: /usr/arm-linux-gnueabi/lib/ld-linux.so.3
libc6-armhf-cross: /usr/arm-linux-gnueabihf/lib/ld-linux.so.3

then ..

#sudo apt-get install libc6-armel-cross
#sudo ln -sf /usr/arm-linux-gnueabi/lib/ld-linux.so.3 /lib/ld-linux.so.3
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: felipemdc on October 31, 2011, 09:04:54 am
It needs to link to ld-linux.so.3 for the target platform, not your host platform. Try to remove sysutils from the uses clause and see if that changes anything. I don't remember ld-linux.so being a normal dependency unless you rely on dynamic linking

SysUtils does not have any external dependencies, probably the JNI unit has.

As an example of why I am sure: LCL-Android currently has zero external dependencies and it uses a lot of RTL units. But it does not use JNI. Eventually I will have to add opengl as an external dependency, however.
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: marcov on October 31, 2011, 09:25:02 am
Use -FL to specify the name of the dynamic linker.
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on October 31, 2011, 09:40:53 am
Thanks for all your replies!

Quote
SysUtils does not have any external dependencies, probably the JNI unit has.
Nope, my jni.pas has no uses-clause.

I've tried:
Code: [Select]
fpc -Tlinux -Parm -XParm-linux- -FL/lib/ld-linux.so.2 libtest.dpr
Which gives me:
Code: [Select]
Free Pascal Compiler version 2.7.1 [2011/10/27] for arm
Copyright (c) 1993-2011 by Florian Klaempfl and others
Target OS: Linux for ARMEL
Compiling libtest.dpr
Assembling test
Linking liblibtest.so
/usr/local/bin/arm-linux-ld: warning: link.res contains output sections; did you forget -T?
/usr/local/bin/arm-linux-ld: skipping incompatible /lib/ld-linux.so.2 when searching for /lib/ld-linux.so.2
/usr/local/bin/arm-linux-ld: cannot find /lib/ld-linux.so.2
libtest.dpr(11) Error: Error while linking
libtest.dpr(11) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/local/bin/ppcarm returned an error exitcode (normal if you did not specify a source file to be compiled)

So the version installed on my system is obviously not usable (because it's x86 instead of ARM right?)

The question is: where to get this ld-linux.so.3? It doesn't seem to exist in the 10.04 repositories (apt-file search gives nothing).

My guess is that it's in the android-ndk because C must also use it. However, I haven't been able to find it.

Code: [Select]
nathan@nathan-PC arch-arm $ pwd
/home/nathan/android/android-ndk-r6b/platforms/android-4/arch-arm
nathan@nathan-PC arch-arm $ find . -iname *so
./usr/lib/libGLESv1_CM.so
./usr/lib/libthread_db.so
./usr/lib/liblog.so
./usr/lib/libm.so
./usr/lib/libdl.so
./usr/lib/libstdc++.so
./usr/lib/libz.so
./usr/lib/libc.so
nathan@nathan-PC arch-arm $

I'm also slightly confused. When I compiled the binutils for arm, it also generated a linker (/usr/local/bin/arm-linux-ld). What is the difference between that one and the ld-linux.so.3 file I'm looking for right now?

Many thanks :)
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: felipemdc on October 31, 2011, 10:47:14 am
Nope, my jni.pas has no uses-clause.

What does that have to do with external dependencies? External dependencies means depending on external libraries, usually by declaring a procedure as external, but there is also {$linklib} and some other ways to add external dependencies. this is totally unrelated to the uses clause. And clearly your JNI unit has external dependencies.
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on October 31, 2011, 11:20:48 am
Sorry my bad. It obviously depends on a few functions exported by the JAVA Virtual machine.

However, I did some other tests and the ld-linux.so.3 requirement doesn't seem to be related to jni.pas. If I use the following example:

Code: [Select]
library test;

begin
  Writeln('a');   
end.

with the command:

Code: [Select]
fpc -Tlinux -Parm -XParm-linux- libtest.dpr

it still returns:

Code: [Select]
Free Pascal Compiler version 2.7.1 [2011/10/27] for arm
Copyright (c) 1993-2011 by Florian Klaempfl and others
Target OS: Linux for ARMEL
Compiling libtest.dpr
Assembling test
Linking liblibtest.so
/usr/local/bin/arm-linux-ld: warning: link.res contains output sections; did you forget -T?
/usr/local/bin/arm-linux-ld: cannot find /lib/ld-linux.so.3
libtest.dpr(6) Error: Error while linking
libtest.dpr(6) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/local/bin/ppcarm returned an error exitcode (normal if you did not specify a source file to be compiled)

If I replace "library" with "program" it does work. So the fact that I'm trying to compile a library causes this.

Any other ideas?
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: felipemdc on October 31, 2011, 11:25:26 am
Any other ideas?

Copy ld-linux.so.3 from our telephone (or tablet or emulator) and when compiling the project pass the path to it in the -FL part
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on October 31, 2011, 11:41:44 am
I connected my tablet and did:
Code: [Select]
nathan@nathan-PC ~ $ adb pull /lib/ld-linux.so.3 ~
remote object '/lib/ld-linux.so.3' does not exist
So it either doesn't exist or I just don't have access to it. The latter seems likely because I can't cd into /lib

I'll see if I can get it out of the emulator.

Update: I need to "root" either my device or the emulator to get to this file. I'll have a look at this later.

I'm still not sure whether this is right. I only want to get a JNI hello world sample working. If I get my hands on this ld-linux.so.3 file on my device, there is no guarantee that my demo will still work on other devices/versions of android, right?
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Laksen on October 31, 2011, 12:06:27 pm
Have you tried herux's tip?
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on October 31, 2011, 12:24:25 pm
Yes, sorry forgot to mention it.

On my system, "apt-file search ld-linux.so.3" doesn't return any results. I did do "apt-file update". They don't seem to have libc6-armel-cross for 10.04 (only for 10.10 and up).

It seems like that's the solution to my problem. But I hate having to do a system upgrade (with all kinds of possible nasty sideeffects) just to be able to cross compile. Maybe I can build that from source somehow?
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: felipemdc on October 31, 2011, 01:03:21 pm
I'm still not sure whether this is right. I only want to get a JNI hello world sample working. If I get my hands on this ld-linux.so.3 file on my device, there is no guarantee that my demo will still work on other devices/versions of android, right?

If ld-linux.so.3 was incompatible across multiple Android devices then JNI applications would not work, but this is not true, there are tons of JNI applications in the market and they work in all devices.
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Laksen on October 31, 2011, 01:34:03 pm
Try this:
Run fpc -Tlinux -Parm -XParm-linux- -FL/system/bin/linker -sh libtest.dpr
Then remove "/system/bin/linker" from the input section in link.res
Then run ppas.sh

It seems that the dynamic linker is called something else on Android, and that fpc puts the dynamic linker as an input to the linker script(line 439 in t_linux.pas). As far as I know it should only specify the dynamic linker as a parameter to ld, and not as an input
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: marcov on October 31, 2011, 01:36:09 pm
It does worry me a bit that it says it can't find explicitely /lib/ld-linux.so.3 and not "just" ld-linux.so.3

I think the -XR option was added because of similar problems, see

http://lazarus.freepascal.org/index.php/topic,8084.msg57377.html#msg57377

You need to build a tree structure like on the target device, and then pass the root using -XR. 

In general, search "sheeva" threads, they contain a few msgs of me and Jonas with a lot of cross-arm experience in them.
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on November 01, 2011, 10:25:27 am
Thank you for all the help. Much appreciated!

@Laksen: That works great! I have got my hello world sample working on android! So it goes like this. I assume you have the basic project framework allready set up, that loads a native lib and does a JNI call on it:

1. Create a dpr in the project/jni directory
2. Add jni.pas over there, include it and write a jni function
3. run: fpc -Tlinux -Parm -XParm-linux- -FL/system/bin/linker -olibyourproject.so -sh yourproject.dpr (replace "yourproject" by a different name)
4. Remove "/system/bin/linker" from the input section in link.res
5. Run chmod u+x ppas.sh (just to make sure it can execute).
6. Run ppas.sh
7. Move lib<yourproject>.so to project/libs/armeabi (make this dir if nonexistent)
6. cd to your project dir and execute "ant install" (make sure your device/emulator is connected and running).

Now you can start the app in your device. I will provide a working example later.

Quote
It seems that the dynamic linker is called something else on Android, and that fpc puts the dynamic linker as an input to the linker script(line 439 in t_linux.pas). As far as I know it should only specify the dynamic linker as a parameter to ld, and not as an input

Do you mean that ld-linux.so.3 is the default used by FPC, while android uses /system/bin/linker? I have found the latter on my device. :)
So the solution was to override this default by generating a linker script. I only don't really know what link.res is and why I needed to remove /system/lib/linker.

Would it be possible to make this build process a bit simpler? I tried removing -sh but then it complained that /system/bin/linker was not there. Is there a way to tell FPC that I'm cross-compiling so that it doesn't look for the dynamic linker on the host machine?

Thanks alot!
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Laksen on November 01, 2011, 01:08:08 pm
Would it be possible to make this build process a bit simpler?
Yes, if the method I suggested is correct. You should probably test it, to see if you can still load shared libraries on the platform
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on November 02, 2011, 10:28:46 am
Would it be possible to make this build process a bit simpler?
Yes, if the method I suggested is correct. You should probably test it, to see if you can still load shared libraries on the platform

I'm not sure what you mean. I actually used your method described in your last post and it let me dynamically link my pascal-written library to the java app running in the JVM. Do you mean loading native shared libs from native code?
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Laksen on November 02, 2011, 11:19:17 am
Would it be possible to make this build process a bit simpler?
Yes, if the method I suggested is correct. You should probably test it, to see if you can still load shared libraries on the platform

I'm not sure what you mean. I actually used your method described in your last post and it let me dynamically link my pascal-written library to the java app running in the JVM. Do you mean loading native shared libs from native code?
That's what I mean, yes.

The dynamic loaded JNI functions in your case aren't ever called, so it doesn't prove very much(except that it is able to link without throwing errors)
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on November 02, 2011, 11:47:08 am
Well, that's my fault. I didn't provide all the results I guess.

So I made this file (project/jni/hello-jni.dpr):
Code: [Select]
library hellojni;

uses
  SysUtils,
  JNI;

function Java_com_example_hellojni_HelloJni_stringFromJNI(PEnv: PJNIEnv; this: JObject): JString;
var
  I: Integer;
  S: String;
begin
    S := '';
    for I := 0 to 9 do
    begin
      S := S + IntToStr(I) + ' ';
    end;
    S := 'Lets count  '+S;
    Result := (PEnv^).NewStringUTF(PEnv, PChar(S) );
end;

exports Java_com_example_hellojni_HelloJni_stringFromJNI;

end.

I compile/link this file to get project/libs/armeabi/libhellojni.so.

The project also contains this JAVA file (project/src/com/example/hellojni/HelloJNI.java)
Code: [Select]
package com.example.hellojni;

import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;

public class HelloJni extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        TextView  tv = new TextView(this);
        tv.setText( stringFromJNI() );
        setContentView(tv);
    }

    public native String  stringFromJNI();

    static {
        System.loadLibrary("hellojni");
    }
}

If I use the steps described earlier, I will get the HelloJNI app on my tablet. When I execute it, it shows me:
Quote
Lets count 0 1 2 3 4 5 6 7 8 9

So that's definitely proof that it links and runs correctly.

But I find the build process quite cumbersome (having to edit link.res etc). Is there a way to do this in less steps?

Thanks!
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Laksen on November 02, 2011, 11:56:08 am
What I meant is that the pascal program doesn't call any dynamic linked procedures. When you call NewStringUTF it simply calls a pointer which is given from the Java program
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on November 02, 2011, 12:30:03 pm
Ok I get it. Do you have any suggestions to easily test this?
I could try to link against OpenGLESv2.so perhaps and just call eglGetDisplay(). I'll keep you posted.
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Andru on November 03, 2011, 10:29:33 am
Quote
But I find the build process quite cumbersome (having to edit link.res etc). Is there a way to do this in less steps?

Code: [Select]
-FLlibdl.so

Android have this one instead of ld-linux.so, so add this to your compiler options and set path to lib directory from Android NDK.
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on November 05, 2011, 05:56:15 pm
Thanks alot. I will try this as as im back from my little holyday.
 :D
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: chronozphere on November 22, 2011, 11:26:17 pm
Yes. it compiles smoothly  when using -FLlibdl.so  Thanks for that! :)
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Rustam Asmandiarov on February 17, 2012, 06:57:51 am
Hello! I compiled the application for the management and tested on the Samsung Galaxy s 2 i9100G application will not run. According tried on the emulator, just does not start, logcat brought this:
Здраствуйте! Я скомпилировал приложение по руководству и протестировал на Samsung Galaxy s 2 i9100G приложение не запустилось. По пробовал на  Эмуляторе, точно так же не запустилось, logcat вывел это:

I/lclapp  (  291): Trying to load liblclapp.so

D/dalvikvm(  291): Trying to load lib /data/data/com.pascal.lcltest/lib/liblclapp.so 0x40514330

E/lclapp  (  291): WARNING: Could not load liblclapp.so

W/System.err(  291): java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1962]:    32 could not load needed library 'ld-linux.so.3' for 'liblclapp.so' (load_library[1104]: Library 'ld-linux.so.3' not found)

W/System.err(  291):    at java.lang.Runtime.loadLibrary(Runtime.java:434)

W/System.err(  291):    at java.lang.System.loadLibrary(System.java:554)

W/System.err(  291):    at com.pascal.lcltest.LCLActivity.<clinit>(LCLActivity.java:621)

W/System.err(  291):    at java.lang.Class.newInstanceImpl(Native Method)

downloaded to the device ld-linux.so.3 not an option, since all mashines on which the library no need to install root
загружать на аппарат ld-linux.so.3 не выход, так как на всех апаратах на которых нету этой библиотеки потребуется установить root
What do I do?
lazarus: 0.9.31.33575
FPC:2.7.1
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: felipemdc on February 17, 2012, 07:46:28 am
Please do not reuse old threads for new questions. Please create a new topic.
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: Rustam Asmandiarov on February 17, 2012, 07:47:45 am
ok
Title: Re: Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM
Post by: marcov on February 17, 2012, 10:21:55 am
Yes, sorry forgot to mention it.

On my system, "apt-file search ld-linux.so.3" doesn't return any results.

Does apt-file actually find stuff installed by base?