Im trying to build an executable which depends on a shared library in C for android. I want to run the executable on android shell.
I first built the executable using android ndk (I'm using android-ndk-r16b), then using adb push I put the files generated by ndk on my android device then using adb shell i try to run the executable.
Im building on Ubuntu 14.04.
I installed the android arm toolchain using apt-get:
sudo apt-get install gcc-arm-linux-androideabi
Here are my files:
Shared library: libcal.so
cal.c:
#include "cal.h"
int add(int a , int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
cal.h:
int add(int a , int b);
int sub(int a, int b);
Makefile:
CXX=arm-linux-androideabi-gcc
CXXFLAGS=-fPIC -Wall -I. -c
LDFLAGS=-shared
SOURCES=./cal.c
OBJECTS=$(SOURCES:.c=.o)
TARGET_LIB=libcal.so
all: $(SOURCES) $(TARGET_LIB)
$(TARGET_LIB): $(OBJECTS)
$(CXX) -o $# $(OBJECTS) $(LDFLAGS)
.c.o:
$(CXX) $(CXXFLAGS) $< -o $#
.PHONY: clean
clean:
#rm -f $(TARGET_LIB) $(OBJECTS)
So this how I generate the shared library. Then in a folder called jni I have the following files:
test.c:
#include <stdio.h>
#include "cal.h"
int main()
{
int sum = 0, diff = 0;
sum = add(3,2);
diff = sub(2,2);
printf("sum = %d\ndiff = %d\n",sum, diff);
return 0;
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cal
LOCAL_SRC_FILES := $(LOCAL_PATH)/../../library/libcal.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../library/
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.c
LOCAL_SHARED_LIBRARIES := cal
include $(BUILD_EXECUTABLE)
Application.mk
APP_ABI := armeabi-v7a
APP_PLATFORM := android-19
Then on running $ndk-build this is my output
rohith#rohith-Lenovo-G50-80:~/example2/hello/jni$ ndk-build
[armeabi-v7a] Prebuilt : libcal.so <= jni/../../library/
[armeabi-v7a] Install : libcal.so => libs/armeabi-v7a/libcal.so
[armeabi-v7a] Compile thumb : test <= test.c
[armeabi-v7a] Executable : test
[armeabi-v7a] Install : test => libs/armeabi-v7a/test
rohith#rohith-Lenovo-G50-80:~/example2/hello/jni$ cd ../libs/armeabi-v7a/
rohith#rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$ ls
libcal.so test
rohith#rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$
Thus my android compatible files are in the libs folder
NOTE: If i don't use the Application.mk the build fails with the following output
rohith#rohith-Lenovo-G50-80:~/example/hello/jni$ ndk-build
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-14.
[arm64-v8a] Prebuilt : libcal.so <= jni/../../library/
[arm64-v8a] Install : libcal.so => libs/arm64-v8a/libcal.so
[arm64-v8a] Compile : test <= test.c
[arm64-v8a] Executable : test
/home/rohith/example/hello/obj/local/arm64-v8a/libcal.so: error adding symbols: File in wrong format
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [/home/rohith/example/hello/obj/local/arm64-v8a/test] Error 1
Anyways now after I put the shared library and executable on the android device and run the executable i get the following error:
rohith#rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$ ls
libcal.so test
rohith#rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$ cd ..
rohith#rohith-Lenovo-G50-80:~/example2/hello/libs$ adb push armeabi-v7a /data/local/rohith
push: armeabi-v7a/libcal.so -> /data/local/rohith/libcal.so
push: armeabi-v7a/test -> /data/local/rohith/test
2 files pushed. 0 files skipped.
134 KB/s (11088 bytes in 0.080s)
rohitht#rohith-Lenovo-G50-80:~/example2/hello/libs$ adb shell
root#tcc897x:/ # cd /data/local/rohith
root#tcc897x:/data/local/rohith # ls
libcal.so
test
root#tcc897x:/data/local/rohith # export LD_LIBRARY_PATH=.
root#tcc897x:/data/local/rohith # ./test
CANNOT LINK EXECUTABLE: could not load library "/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so" needed by "./test"; caused by library "/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so" not found
1|root#tcc897x:/data/local/rohith #
Why is it linking to paths with respect to my laptop?
I would appreciate it immensely if someone can tell what I'm doing wrong or give me advice on how they have gone about doing something similar.
My actual task requires me link much more complicated shared libraries and run an executable on android shell. Don't know how I am going to do that if I can get a simple .so working.
The library was not built correctly. This kind of problem with SONAME path is not new. It has surfaced after one particular fix in Android at API 23.
If for whatever reason you cannot rebuild this library with latest NDK, you may try the patchelf utility to add SONAME to existing binary.
I tried one of the methods specified by Alex Cohen.
On running $readelf -d test to executable generated by NDK the output is as follows:
(...)
0x00000004 (HASH) 0x41c
0x00000001 (NEEDED) Shared library: [/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
(...)
The shared library's path got appended to its name. Thus inorder to change that to just libcal.so I used patchelf.
Here are the commands I used:
$patchelf --remove-needed /home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so test
$patchelf --add-needed libcal.so test
Note: This may not be the perfect fix. As on running readelf -d test after changing the library names I got another field (Not too bothered about it at the moment as the executable works)
rohith#rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$ readelf -d test
Dynamic section at offset 0x4000 contains 32 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libcal.so]
0x0000001d (RUNPATH) Library runpath: [/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so:./libcal.so]
0x00000003 (PLTGOT) 0x2fcc
0x00000002 (PLTRELSZ) 80 (bytes)
0x00000017 (JMPREL) 0x50c
0x00000014 (PLTREL) REL
0x00000011 (REL) 0x4ac
0x00000012 (RELSZ) 96 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 10
0x00000015 (DEBUG) 0x0
0x00000006 (SYMTAB) 0x224
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x4130
0x0000000a (STRSZ) 347 (bytes)
0x00000004 (HASH) 0x41c
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]
That extra field type RUNPATH got added
Related
I want to build a Linux kernel module foo.ko from an existing file foo.c and a static library support.a. The library support.a is compiled from Rust so there is no support.c.
I've used the following Makefile
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
obj-m += foo.o
foo-obs += support.a
all:
$(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules V=1
It seems that support.a is not linked; there are warnings that the functions called from foo.c (and implemented in support.a) are undefined.
Update 0: the Makefile works on Ubuntu LTS (I've tested on 18.04 and 14.04) but not on Fedora (both 29/30). The output in case of Fedora is:
...
make -C /lib/modules/5.1.11-200.fc29.x86_64/build SUBDIRS=/public/Github/rustyvisor modules
make[1] : on entre dans le répertoire « /usr/src/kernels/5.1.11-200.fc29.x86_64 »
Makefile:205: ================= WARNING ================
Makefile:206: 'SUBDIRS' will be removed after Linux 5.3
Makefile:207: Please use 'M=' or 'KBUILD_EXTMOD' instead
Makefile:208: ==========================================
LD [M] /public/Github/rustyvisor/rustyvisor.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: /public/Github/rustyvisor/rustyvisor.o(.init.text+0xbb): Section mismatch in reference from the function init_module() to the function .exit.text:rustyvisor_exit()
The function __init init_module() references
a function __exit rustyvisor_exit().
This is often seen when error handling in the init function
uses functionality in the exit path.
The fix is often to remove the __exit annotation of
rustyvisor_exit() so it may be used outside an exit section.
WARNING: "rustyvisor_core_unload" [/public/Github/rustyvisor/rustyvisor.ko] undefined!
WARNING: "rustyvisor_load" [/public/Github/rustyvisor/rustyvisor.ko] undefined!
WARNING: "rustyvisor_core_load" [/public/Github/rustyvisor/rustyvisor.ko] undefined!
WARNING: "rustyvisor_unload" [/public/Github/rustyvisor/rustyvisor.ko] undefined!
LD [M] /public/Github/rustyvisor/rustyvisor.ko
make[1] : on quitte le répertoire « /usr/src/kernels/5.1.11-200.fc29.x86_64 »
Update 1: There is very similar question but this question is to ask why the Makefile doesn't work on Fedora but I discovered that it works on Ubuntu.
Finally, I found a workaround for the problem (but I still don't understand why). On Fedora, the library name support.a should be changed to support.o, then the linker works!!!
I'm trying to build my own library. It worked on x86 linux so I wanna build for MIPS Linux (Little endian.)
I'm using sourcery codebench in Mento Graphics and buildroot and CMake.
I configured build_all.sh like below.
#!/bin/bash -ev
export TARGETROOT="/usr/mipsel-buildroot-linux-gnu/sysroot"
mkdir -p mips_build
cd mips_build
cmake -DCMAKE_SYSTEM_NAME="Linux" \
-DCMAKE_C_COMPILER="${CROSS_COMPILE}gcc" \
-DCMAKE_CXX_COMPILER="${CROSS_COMPILE}g++" \
-DCMAKE_AR="${CROSS_COMPILE}ar" \
-DCMAKE_C_FLAGS="-EL -c -g -O2 -fPIC --sysroot=$TARGETROOT " \
-DCMAKE_CXX_FLAGS="-EL -c -g -O2 -fPIC --sysroot=$TARGETROOT " \
../
make
cd ..
Where $CROSS_COMPILE=/home/vagrant/bd1/mips-2014.05/bin/mips-linux-gnu-
And CMakeFiles.txt is like below.
make_minimum_required (VERSION 2.6)
set(EMSG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../src/eagle_msg/include )
set(EMSG_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../lib )
set (PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set (PROJECT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set (PROJECT_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(LIBRARIES
libemsg.a
libzmq.a
libprotobuf.a
libprotobuf-c.a
libpthread.a
libstdc++.a
)
#For controller : Client
SET(EXECUTABLE test_controller)
project (${EXECUTABLE})
include_directories(
${PROJECT_INCLUDE_DIR}
${EMSG_INCLUDE_DIR}
$ENV{TARGETROOT}/usr/include
)
link_directories(
${PROJECT_LIB_DIR}
${EMSG_LIB_DIR}
$ENV{TARGETROOT}/usr/lib
)
set(SRCS
test_controller.cpp
)
add_executable( ${EXECUTABLE} ${SRCS})
target_link_libraries( ${EXECUTABLE} ${LIBRARIES} )
Then it makes the error like below.
[ 40%] Built target emsg
Linking CXX executable ../../../bin/test_controller
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make[2]: *** [../bin/test_controller] Error 1
make[1]: *** [test/emsg_test/CMakeFiles/test_controller.dir/all] Error 2
So I checked the format of libstdc++.so. Then it's ELF 32-bit LSB shared object, MIPS, MIPS32. That's the right version. Then what can I do to solve?
/usr/mipsel-buildroot-linux-gnu/sysroot# file /usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.*
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.a: current ar archive
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so: symbolic link to `libstdc++.so.6.0.19'
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so.6: symbolic link to `libstdc++.so.6.0.19'
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so.6.0.19: ELF 32-bit LSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, with unknown capability 0xf41 = 0x756e6700, not stripped
New information
It seems to be the problem of buildroot. I checked the sysroot value of mips-linux-gnu-gcc.
This is the result before installing buildroot.
$ mips-linux-gnu-gcc --print-sysroot
/home/vagrant/bd1/mips-2014.05/bin/../mips-linux-gnu/libc
This is the result after installing buildroot.
$ mips-linux-gnu-gcc --print-sysroot
/usr/usr/mipsel-buildroot-linux-gnu/sysroot/soft-float/el
I also found the post about similar problem. But it's old issue.
Please use the CMake toolchain file provided by Buildroot. It is generated in $(HOST_DIR)/usr/share/buildroot/toolchainfile.cmake. Use it this way:
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/host/usr/share/buildroot/toolchainfile.cmake
And then you can remove all your other -DCMAKE_ variable, since the toolchain file indicates to CMake which compiler to use, which flags, etc.
I found the reason. The main reason is sysroot path. Buildroot organizes all toolchain into $BUILDROOT/output/host/. So you should change the PATH environment like below.
HOST_BINARY="$BUILDROOT/output/host/usr/bin"
PATH="${PATH}:${HOST_BINARY}"
Where $BUILDROOT is the folder where buildroot is extracted.
You should use toolchain below $BUILDROOT/output/host/usr/bin.
I have a Xilinx FPGA running a soft processor (PowerPC). I recently cross compiled Boost libraries for PowerPC and wanted to test it. So I used one of the sample programs and tried to cross compile it for my target. Below is the code
#include <boost/thread/thread.hpp>
void helloworld()
{
printf( "Hello World!");
}
int main()
{
boost::thread thrd(&helloworld);
thrd.join();
}
Below is my make file
CPP=ppc_4xx-g++
CFLAGS=-c -g -Wall
LDFLAGS_PowerPC=-L/shared/deps/powerpc/lib -L/opt/ELDK/4.2/ppc_4xx/lib/
LIBS_PowerPC=-lboost_thread -lboost_system -lpthread -lrt
INCLUDES=-I. -I./4.2.2/ -I./include -I/opt/ELDK/4.2/ppc_4xx/usr/include/
CPPFLAGS_PowerPC=-I/shared/deps/common/include
CPPFLAGS_COMMON=-I/shared/deps/powerpc/include
CPPFLAGS=$(CPPFLAGS_COMMON) $(CPPFLAGS_PowerPC)
all: helloworld
helloworld: helloworld.o
$(CPP) $(LDFLAGS_PowerPC) $(LIBS_PowerPC) helloworld.o -o helloworld
helloworld.o: helloworld.cpp
$(CPP) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) helloworld.cpp
clean:
rm -rf *.o helloWorld
I was able to generate the binaries but when I run the program on my target I get the below error
-/bin/sh: ./helloworld: not found
I checked online and found that the above problem comes when we have dynamic linking. My Boost libraries are present in the location /shared/deps/powerpc/lib and I have set the variable LD_LIBRARY_PATH accordingly using the below command.
export LD_LIBRARY_PATH=/shared/deps/powerpc/lib/:/opt/ELDK/4.2/ppc_4xx/lib/
But even then I get the same problem.
Below is the output of uname -ars
Linux (none) 3.0.0-14.1-build3+ #23 PREEMPT Thu Jan 3 18:44:27 CST 2013 ppc GNU/Linux
I don't have ldd installed on my target so I can't check the dynamic dependencies. But I am sure that, libraries are included. How can I proceed ?
Even though my embedded Linux system had a dynamic linker, it was not working. The problem was resolved when I used a dynamic linker provided with my tool chain and replaced it the correct directory. Now dynamic linking is fine.
Background
OSX is OS
R8 NDK
I am trying to compile the following class using the Android GCC compiler...
#include <stdint.h>
int main (void){
return 0;
}
I do the with the following command...
un#un:~/Development/Code/OpenGL$ ~/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/arm-linux-androideabi-gcc hello.c -o hello
I get...
In file included from hello.c:1:0:
/Users/un/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/include/stdint.h:3:26: fatal error: stdint.h: No such file or directory
compilation terminated.
So due to a lack of gcc knowledge (but some Google ability) I find this and try it...
un#un:~/Development/Code/OpenGL$ ~/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/arm-linux-androideabi-gcc hello.c -o hello -ffreestanding
and I get...
/Users/un/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtbegin_dynamic.o: No such file or directory
/Users/un/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtend_android.o: No such file or directory
/Users/un/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lc
/Users/un/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot find -ldl
collect2: ld returned 1 exit status
Can someone help me with what I am doing wrong? Am I missing a link or something? Android.mk is not an option.
UPDATE this isn't working either...
arm-linux-androideabi-gcc hello.c --sysroot=~/Development/Android/android-ndk-r8c/platforms/android-9/arch-arm
/Users/jackiegleason/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtbegin_dynamic.o: No such file or directory
/Users/jackiegleason/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtend_android.o: No such file or directory
/Users/jackiegleason/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lc
/Users/jackiegleason/Development/Android/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot find -ldl
collect2: ld returned 1 exit status
You must tell GCC where to find the Android system files and headers. Either use:
ndk-build and an Android.mk with BUILD_EXECUTABLE
or, the --sysroot GCC option
[1]
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo.c
include $(BUILD_EXECUTABLE)
[2]
# Change `android-9` with the level you target
/path/to/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt\
/darwin-x86/bin/arm-linux-androideabi-gcc\
--sysroot /path/to/android-ndk-r8c/platforms/android-9/arch-arm/\
foo.c -o foo
# Or generate a ready-to-use standalone toolchain (better)
/path/to/android-ndk-r8c/build/tools/make-standalone-toolchain.sh \
--platform=android-9 \
--install-dir=/tmp/my-android-toolchain
export SYSROOT=/tmp/my-android-toolchain/sysroot
/path/to/arm-linux-androideabi-gcc --sysroot $SYSROOT foo.c -o foo
So, since I don't want to use Android.mk file, I went ahead and created a standalone toolchain. this is done using the following...
/Users/un/Downloads/android-ndk-r8d/build/tools/make-standalone-toolchain.sh --platform=android-9 --install-dir=/tmp/my-toolchain
/tmp/my-toolchain/bin/arm-linux-androideabi-gcc hello.c
I would like to know what the "alternative" is in terms of the gcc linking I could do.
This answer adds a bit more details to #deltheil's answer. I had similar issues as I was trying to compile I2C-tools for debugging I2C bus on Android. Somehow after struggling for more than a day with make files and trying different options including --sysroot & --dynamic-linker options etc., I finally tried to compile it within the Android AOSP tree. I used the Google Nexus-S AOSP to build a binary that I intended to run on Samsung S3 phone. I created a folder called i2c-tools for the sources inside the AOSP/external folder and copied Android.mk, Cleanspec.mk & MODULE_LICENCE from another executable folder (ping) and modified it for i2c-tools as follows:
ifneq ($(TARGET_SIMULATOR), true)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := i2cdetect.c i2cbusses.c
LOCAL_C_INCLUDES := $(KERNEL_HEADERS)
LOCAL_MODULE := i2cdetect
LOCAL_MODULE_TAGS := tests
LOCAL_SHARED_LIBRARIES := libc
include $(BUILD_EXECUTABLE)
endif
Then I just ran:
source build/envsetup.sh
make i2cdetect
from the AOSP base folder and voila, I had a working executable in out/target/product/generic/system/bin/ folder. Note that I had to copy all needed source and header files from the original (i2c-tools)/tools & include folders and had to modify some of the #include to remove the extra path for header files that were now in the same place as the c-source.
In my case, I needed an .o file and did not need to define main().
I had to specify the -c switch:
~/ax/arm-linux-androideabi-g++ --sysroot=~/an/platforms/android-8/arch-arm/ -c dummy.c
where ~/ax and ~/an are links:
ax -> ~/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86/bin/
an -> ~/android-ndk-r9d/
did dummy.o.
i solved the problem ,
the default compress file manager in ubuntu wasn't extracting symbolic links ,
so i tried : tar jxf filename.tar.bz2
to untar the ndk.tar.bz2 and now it works fine
I successfully compiled swftools using their instructions (http://wiki.swftools.org/index.php/FAQ) on my Fedora 14 machine. I want to use one of the tools (pdf2swf) on another Linux machine. When I move it and run it on the other machine it asks for some shared libraries. Is it possible to compile swftools (in particular pdf2swf) so that when I run it on another Linux machine it does not ask for any shared libraries? It is OK if the executable itself is bigger in size, as far as it can run independently.
I am new to Linux, so if something requires advanced knowledge please point me to the appropriate online resource.
Regards
it's trivial: link with -static. of course, this implies that you'll need static libraries installed. the linker (often called through cc) simply defaults to using shared libraries when both are available.
[hahn#box ~]$ cat hello.c
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
[hahn#box ~]$ cc hello.c -o hello
[hahn#box ~]$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, not stripped
[hahn#box ~]$ ldd hello
linux-gate.so.1 => (0x00205000)
libc.so.6 => /lib/libc.so.6 (0x00697000)
/lib/ld-linux.so.2 (0x005b4000)
[hahn#box ~]$ cc hello.c -o hello -static
[hahn#box ~]$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, not stripped
[hahn#box ~]$ ldd hello
not a dynamic executable
[hahn#box ~]$ ./hello
Hello, world!
to make this work, I needed to install glibc-static, which is not installed by default (at least on this box, which is Fedora14). some packages let you select static linking at the ./configure level, or else you may need to modify the Makefile.
Well, what you want are statically linked libraries, as opposed to dynamically/shared libraries.
You need to compile your application and link it statically. If you use gcc you can apply the static switch to your call of the compiler:
gcc -static <and the whole gcc shebang>
Most of the times you can edit the makefile (look for a CC define or CC_ARGS something like that) and just include the static switch as above.