Cannot find /lib/ld-linux.so.3 while cross-compiling to ARM lazarus / 43-Android ---------------------------------------------------------------------- chronozphere · 2011-10-30 23:32 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 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 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! ---------------------------------------------------------------------- Laksen · 2011-10-31 00:02 Doesn't the Android NDK have this file, or something like it? ---------------------------------------------------------------------- chronozphere · 2011-10-31 00:08 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? ---------------------------------------------------------------------- Laksen · 2011-10-31 00:34 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 ---------------------------------------------------------------------- herux · 2011-10-31 04:54 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 ---------------------------------------------------------------------- felipemdc · 2011-10-31 08:04 Quote from: Laksen on October 31, 2011, 01:34:47 amIt 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. ---------------------------------------------------------------------- marcov · 2011-10-31 08:25 Use -FL to specify the name of the dynamic linker. ---------------------------------------------------------------------- chronozphere · 2011-10-31 08:40 Thanks for all your replies! QuoteSysUtils 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 ---------------------------------------------------------------------- felipemdc · 2011-10-31 09:47 Quote from: chronozphere on October 31, 2011, 09:40:53 amNope, 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. ---------------------------------------------------------------------- chronozphere · 2011-10-31 10:20 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? ---------------------------------------------------------------------- felipemdc · 2011-10-31 10:25 Quote from: chronozphere on October 31, 2011, 11:20:48 amAny 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 ---------------------------------------------------------------------- chronozphere · 2011-10-31 10:41 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? ---------------------------------------------------------------------- Laksen · 2011-10-31 11:06 Have you tried herux's tip? ---------------------------------------------------------------------- chronozphere · 2011-10-31 11:24 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? ---------------------------------------------------------------------- felipemdc · 2011-10-31 12:03 Quote from: chronozphere on October 31, 2011, 11:41:44 amI'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. ---------------------------------------------------------------------- Laksen · 2011-10-31 12:34 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 ---------------------------------------------------------------------- marcov · 2011-10-31 12:36 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#msg57 377 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. ---------------------------------------------------------------------- chronozphere · 2011-11-01 09:25 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.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. QuoteIt 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! ---------------------------------------------------------------------- Laksen · 2011-11-01 12:08 Quote from: chronozphere on November 01, 2011, 10:25:27 amWould 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 ---------------------------------------------------------------------- chronozphere · 2011-11-02 09:28 Quote from: Laksen on November 01, 2011, 01:08:08 pmQuote from: chronozphere on November 01, 2011, 10:25:27 amWould 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? ---------------------------------------------------------------------- Laksen · 2011-11-02 10:19 Quote from: chronozphere on November 02, 2011, 10:28:46 amQuote from: Laksen on November 01, 2011, 01:08:08 pmQuote from: chronozphere on November 01, 2011, 10:25:27 amWould 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) ---------------------------------------------------------------------- chronozphere · 2011-11-02 10:47 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: QuoteLets 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! ---------------------------------------------------------------------- Laksen · 2011-11-02 10:56 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 ---------------------------------------------------------------------- chronozphere · 2011-11-02 11:30 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. ---------------------------------------------------------------------- Andru · 2011-11-03 09:29 QuoteBut 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. ---------------------------------------------------------------------- chronozphere · 2011-11-05 16:56 Thanks alot. I will try this as as im back from my little holyday. ---------------------------------------------------------------------- chronozphere · 2011-11-22 22:26 Yes. it compiles smoothly  when using -FLlibdl.so  Thanks for that! ---------------------------------------------------------------------- Rustam Asmandiarov · 2012-02-17 05:57 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.(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 ---------------------------------------------------------------------- felipemdc · 2012-02-17 06:46 Please do not reuse old threads for new questions. Please create a new topic. ---------------------------------------------------------------------- Rustam Asmandiarov · 2012-02-17 06:47 ok ---------------------------------------------------------------------- marcov · 2012-02-17 09:21 Quote from: chronozphere on October 31, 2011, 12:24:25 pmYes, 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? ---------------------------------------------------------------------- Seenkao · 2020-04-17 14:30 Данная проблема проявляется и по сей день. Либо нехватает каких-то библиотек, либо компилятор ищет не те библиотеки. Прописывайте пути, обновляйте всё что возможно и просто меняйте целевой процессор ARM5, ARM6, ARM7 или ещё какой. В общем без танцев с бубном не обойтись... ---------------------------------------------------------------------- PascalDragon · 2020-04-17 14:49 English, please. ---------------------------------------------------------------------- Seenkao · 2020-04-17 15:34 я не силён в английском. google translator to help. ---------------------------------------------------------------------- Thaddy · 2020-04-17 16:00 Quote from: Seenkao on April 17, 2020, 05:34:11 pmя не силён в английском. google translator to help. Which in this case helps, but makes too many mistakes.... (My wife is from Lithuania and makes a lot less mistakes) ---------------------------------------------------------------------- Seenkao · 2020-04-17 18:19 installation of FPC through CodeTyphon (if necessary) installation Lazarus. target android-arm (not linux-arm) FPC > 3.0.4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   (not equal 3.0.4) path check!!! checking used libraries!!!! iterate over different options!!! and alas, without dancing with a tambourine you can’t get anywhere... understand?