I am new in NDK and I am following this guide to build OpenSSL for Android, I am using Windows 7 and Cygwin for this.
I'm having errors when trying to build the OpenSSL library.
# From the 'root' directory
$ . ./setenv-android.sh
$ cd openssl-1.0.1g/
$ perl -pi -e 's/install: all install_docs install_sw/install: install_docs install_sw/g' Makefile.org
$ ./config shared no-ssl2 no-ssl3 no-comp no-hw no-engine --openssldir=/usr/local/ssl/$ANDROID_API
$ make depend
$ make all
When I try the make depend command I have 2 errors:
cryptlib.c:171:3: error: #error "Inconsistency between crypto.h and cryptlib.c"
# error "Inconsistency between crypto.h and cryptlib.c"
the cryplib.c line 171 says:
#if CRYPTO_NUM_LOCKS != 41
# error "Inconsistency between crypto.h and cryptlib.c"
#endif
I don't know how to fix that error.
the other one is uid.c:77:10: error: #include expects "FILENAME" or <FILENAME>
#include OPENSSL_UNISTD
if I change the line 77 in uid.c to #include <unistd.h> I get an error in the Makefile, so I don't know if it's the way to fix it, the error was in depend Makefile.
depend:
#[ -z "$(THIS)" -o -f buildinf.h ] || touch buildinf.h # fake buildinf.h if it does not exist
#[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDE) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
#[ -z "$(THIS)" -o -s buildinf.h ] || rm buildinf.h
#[ -z "$(THIS)" ] || (set -e; target=depend; $(RECURSIVE_MAKE) )
#if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$#; fi
Another question is if I can use this guide to build the OpenSSL library to the 64bit arch. (x86_64, arm64 and mips64) I haven't found information about OpenSSL for Android in those architectures, all post about it are old and those arch didn't exist for Android
EDIT
I found a way to solve partially my problem (not the best one but it works), the problem was due some errors in some paths, because I was trying to use Cywin on Windows and some files(I don't which ones) were trying to reach some paths that doesn't exist because I was on Windows and not in Linux, so I just install Ubuntu on a virtual machine and try this guide again, and I could compile libraries and I have libcrypto.a libcrypto.so libssl.a libssl.so for Android ARM, x86, mips, ARM64 and x86_64 Architectures.
But the libraries doesn't work for x86_64 and ARM64, when I try to compile a .c using the android.mk for x86_64 or arm64 eabi it doesn't compile due some compatibility errors, but if a try to compile de same .c file withe the "x86_64" or "arm-64" for a x86 or arm eabi it does compile, so they are still a 32bit libraries, this is not the answer because I need the libraries for all the architecture (at least for armv5, armv7, armv8-64, x86, x86_64), this is just a small step.
I will be updating to help someone with the same problem and if someone want to help me.
When I try the make depend command I have 2 errors:
cryptlib.c:171:3: error: #error "Inconsistency between crypto.h and cryptlib.c"
# error "Inconsistency between crypto.h and cryptlib.c"
There's a problem with the symlinks. Unpack the tarball again with tar zxvf. Then, verify the header files are not 0 length.
Also see Inconsistency between crypto.h and cryptlib.c on the OpenSSL mailing list. And How to copy symbolic link file from Linux to Windows and then back to Linux but still keeping it as a symbolic link on Stack Overflow.
Using this guide and modifying the file setenv-android.sh you can easy compile openssl for arm, x86 and mips.
You just have to modify _ANDROID_NDK _ANDROID_ARCH _ANDROID_EABI _ANDROID_API parameters
note: for mips you'll have to add some lines in the file around
around line 120:
arch-mips)
ANDROID_TOOLS="mipsel-linux-android-gcc mipsel-linux-android-ranlib mipsel-linux-android-ld"
;;
around line 200:
if [ "$_ANDROID_ARCH" == "arch-mips" ]; then
export MACHINE=mipsel
export RELEASE=2.6.37
export SYSTEM=android
export ARCH=mips
export CROSS_COMPILE="mipsel-linux-android-"
fi
if you follow the guide you'll have libcrypto.a, libssl.a, libcrypto.so and libssl.so.
if you want the libraries for 64 bits architecture you can do a pull from a device using adb, all android device have libcrypto.so and libssl.so in /system/lib64 for 64bits version (only in a 64bits device), and /system/lib the 32bits version, you can use an emulator for that, if you can want the 64bits version of the static libraries (libcrypto.a and libssl.a) in this link you can find the way to do it.
Related
i have MOTIF installed X11
a easy program is saved as hello.c
there is the following message
where can i get the X11/intrinsic.h , file ???
need help to compile
my system : MX-16 Linux Debian Jessie / i386
Code:
hans#mx1:~/Documents
$ cc push.c -o push -lXm -lXt -lX11
In file included from push.c:2:0:
/usr/include/Xm/Xm.h:59:27: fatal error: X11/Intrinsic.h: No such file or directory
#include <X11/Intrinsic.h>
^
compilation terminated.
hans#mx1:~/Documents
I installed the libxt-dev package on my Debian box:
apt-get install libxt-dev
Then the proper header will be installed:
# find /usr -name "Intrinsic.h" -print
/usr/include/X11/Intrinsic.h
Been using xv for several decades now -- I always find myself trying to rebuild it.
The copy on my system came from libxt-dev
$ locate Intrinsic
/usr/include/X11/Intrinsic.h
/usr/include/X11/IntrinsicI.h
/usr/include/X11/IntrinsicP.h
$ dpkg-query -S /usr/include/X11/Intrinsic.h
libxt-dev:amd64: /usr/include/X11/Intrinsic.h
You may want to install and use apt-file - you can ask it for a filename and it will tell you which packages (that you don't even have to have installed - just from the repos in your sources.lists) contain a file with that name
I am trying to cross-compile a project for embedded ARM Cortex builds, but I am unable to get the linker working. I want to use armlink, but no files are passed to armlink and hence no .elf file is produced.
My CMakeLists.txt is pretty simple and given below. The failure is shown after that which shows that armlink was invoked by the makefile without any arguments.
Any pointers will help - I searched and read many posts, but they all seem to have more involved requirements.
cmake_minimum_required(VERSION 2.8)
project(test_arm)
enable_language(C ASM)
# Cross-compilation for ARM
SET(CMAKE_C_COMPILER armcc)
SET(CMAKE_LINKER armlink)
SET(CMAKE_C_LINK_EXECUTABLE armlink)
SET(CMAKE_C_FLAGS "--cpu=Cortex-M3")
SET(LINK_FLAGS "--map --ro-base=0x0 --rw-base=0x0008000 --first='boot.o(RESET)' --datacompressor=off")
SET(CMAKE_EXE_LINKER_FLAGS "--map --ro-base=0x0 --rw-base=0x0008000 --first='boot.o(RESET)' --datacompressor=off")
include_directories(../include)
add_executable(blinky blinky.c)
set_target_properties(blinky PROPERTIES LINKER_LANGUAGE C)
The failure is as follows, but I guess it would be obvious to someone given that I have some stupid issue in my CMakeLists:
$ make VERBOSE=1
[100%] Building C object CMakeFiles/blinky.dir/blinky.c.o
/usr/bin/cmake -E cmake_link_script CMakeFiles/blinky.dir/link.txt --verbose=1
armlink
Linking C executable blinky
Product: DS-5 Professional 5.21.0 [5210017]
Component: ARM Compiler 5.05 update 1 (build 106)
Tool: armlink [4d0efa]
For support see http://www.arm.com/support/
Software supplied by: ARM Limited
Usage: armlink option-list input-file-list
where
....
I was expecting the CMake generated Makefile to invoke armlink with something like:
armlink --map --ro-base=0x0 --rw-base=0x0008000 \
--first='boot.o(RESET)' --datacompressor=off \
CMakeFiles/blinky.dir/blinky.c.o -o blinky.elf
Starting with CMake v3.5 you don't need a toolchain anymore for Keil ARM C/C++ compilation tools:
Support was added for the ARM Compiler (arm.com) with compiler id ARMCC.
Just set your C/CXX compiler variables accordingly
cmake -DCMAKE_C_COMPILER:PATH="C:\Program Files (x86)\DS-5\bin\armcc.exe"
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files (x86)\DS-5\bin\armcc.exe"
...
References
ARMCC toolchain support
Add support for the ARM Compiler (arm.com)
CMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found
From my experience, you cannot set CMAKE_EXE_LINKER_FLAGS in a CMakeLists.txt file. It has to be passed via a CMAKE_TOOLCHAIN_FILE when CMake is invoked the very first time in a build directory.
I don't find any documentation regarding this problem, but there is the cross-compilation with CMake page which you should use it if you do cross-compilation.
For a start, just put your set-calls in a toolchain file and run
cmake -DCMAKE_TOOLCHAIN_FILE=<yourfile.toolchain>
in a clean build directory.
A toolchain file may be a good idea. Here is what I've came up the last time I tried CMake 2.8.10 with the DS-5 toolchain (it could still be optimized, but it should give you a starting point):
INCLUDE(CMakeForceCompiler)
# This one is important
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_PROCESSOR arm)
# Specify the cross compiler
SET(CMAKE_C_COMPILER "C:/Program Files (x86)/DS-5/bin/armcc.exe")
SET(CMAKE_CXX_COMPILER "C:/Program Files (x86)/DS-5/bin/armcc.exe")
SET(CMAKE_AR "C:/Program Files (x86)/DS-5/bin/armar.exe" CACHE FILEPATH "Archiver")
#CMAKE_FORCE_C_COMPILER("C:/Program Files (x86)/DS-5/sw/gcc/bin/arm-linux-gnueabihf-gcc.exe" GNU)
#CMAKE_FORCE_CXX_COMPILER("C:/Program Files (x86)/DS-5/sw/gcc/bin/arm-linux-gnueabihf-g++.exe" GNU)
UNSET(CMAKE_C_FLAGS CACHE)
SET(CMAKE_C_FLAGS "--cpu=Cortex-A9 --thumb -Ospace" CACHE STRING "" FORCE)
UNSET(CMAKE_CXX_FLAGS CACHE)
SET(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "" FORCE)
UNSET(CMAKE_EXE_LINKER_FLAGS CACHE)
SET(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "" FORCE)
UNSET(CMAKE_AR_FLAGS CACHE)
SET(CMAKE_AR_FLAGS "-p -armcc,-Ospace" CACHE STRING "" FORCE)
# set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> ${CMAKE_AR_FLAGS} -o <TARGET> <OBJECTS>" CACHE STRING "C Archive Create")
# set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> ${CMAKE_AR_FLAGS} -o <TARGET> <OBJECTS>" CACHE STRING "CXX Archive Create")
include_directories("C:/Program Files (x86)/DS-5/include")
#include_directories("C:/Program Files (x86)/DS-5/sw/gcc/arm-linux-gnueabihf/libc/usr/include/arm-linux-gnueabi")
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH "C:/Program Files (x86)/DS-5")
# Search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# For libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Regarding your question
Some failure analysis
What you have tried should work (see also e.g. How do I add a linker or compile flag in a CMake file?). But it seems something goes wrong during the configuration step.
I don't know your command line call for CMake's configuration/generation steps, so some general tips to find the root cause:
You could try calling
cmake.exe --trace ...
to see what went wrong with your CMAKE_EXE_LINKER_FLAGS variable. This will generate a lot of output, so here are some basics on what CMake does:
The project() command will trigger the compiler evaluation
This will write CMAKE_EXE_LINKER_FLAGS into your CMakeCache.txt
You are overwriting it with a local variable (see variable scope docu here)
If you look into share\cmake-2.8\Modules\CMakeCommonLanguageInclude.cmake:
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS_INIT} $ENV{LDFLAGS}"
CACHE STRING "Flags used by the linker.")
You could use CMAKE_EXE_LINKER_FLAGS_INIT, but you have to set it before the project() command or in the toolchain file.
Because you set the link language to C take a look into share\cmake-2.8\Modules\CMakeCInformation.cmake:
if(NOT CMAKE_C_LINK_EXECUTABLE)
set(CMAKE_C_LINK_EXECUTABLE
"<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
So you can use CMAKE_C_LINK_EXECUTABLE to overwrite the complete linker call or you could use CMAKE_C_LINK_FLAGS to set additional flags.
The "official" way
The official way to set the target's linker and compiler flags would be (before CMake 2.8.12):
set_property(TARGET blinky APPEND_STRING PROPERTY COMPILE_FLAGS "--cpu=Cortex-M3")
set_property(TARGET blinky APPEND_STRING PROPERTIES LINK_FLAGS "--map --ro-base=0x0 --rw-base=0x0008000 --first='boot.o(RESET)' --datacompressor=off")
Starting with CMake 2.8.12 it would be something like:
add_compile_options("--cpu=Cortex-M3")
I'm running Linux Mint 14 with qemu, qemu-user, and the gnueabi toolchain installed. I compiled test.c with arm-linux-gnueabi-gcc test.c -o test.
When I try and run qemu-arm /usr/arm-linux-gnueabi/lib/ld-linux.so.3 test
I get an error saying: test: error while loading shared libraries: test: cannot open shared object file: No such file or directory. Running qemu-arm test, as I've previously tried, gives /lib/ld-linux.so.3: No such file or directory
However, the file does exist and is reachable.
$ stat /usr/arm-linux-gnueabi/lib/ld-linux.so.3
File: `/usr/arm-linux-gnueabi/lib/ld-linux.so.3' -> `ld-2.15.so'
Size: 10 Blocks: 0 IO Block: 4096 symbolic link
Device: 801h/2049d Inode: 4083308 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2013-04-22 16:19:48.090613901 -0700
Modify: 2012-09-21 08:31:29.000000000 -0700
Change: 2013-04-22 15:58:41.042542851 -0700
Birth: -
Does anyone know how I can make qemu run an arm program without having to emulate an entire arm Linux kernel?
test.c is
#include <stdio.h>
int main() {
printf("this had better work\n");
}
and file test is
test: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31, BuildID[sha1]=0xf2e49db65394b77c77ee5b65b83c0cc9220cbfc0, not stripped
you can run the example by providing a path to the arm-linux-gnueabi shared libs using the -L flag.
qemu-arm -L /usr/arm-linux-gnueabi/
also make sure the LD_LIBRARY_PATH is not set.
unset LD_LIBRARY_PATH
$ export QEMU_LD_PREFIX=/usr/arm-linux-gnueabi
This works for me.
It's basically the same thing as:
$ qemu-arm -L /usr/arm-linux-gnueabi/
You can add it to the ~/.bashrc file so you don't have to type it everytime you open the terminal.
I also met this problem when running a C program with assembly code. My solution is to build the executable with the option "-static", for instance
arm-linux-gnueabi-gcc -static -g main.c square.s
Then
qemu-arm a.out
will not report the error saying "can not find the /lib/ld-linux.so.3".
The only drawback is that the executable could be with a large size. But it's helpful when you just want to test your code.
Of course, you can go with the method from Balau(see artless noise's answer). But if you don't want to feel frustrated by something like "UART serial ports" in this step, which is only to run a simple "test" function, go for a try of my fix.
I solved the problem by copying the following libraries into /lib but I believe there should be a way better solution rather than this nasty solution I invented!
sudo cp /usr/arm-linux-gnueabi/lib/ld-linux.so.3 /lib
sudo cp /usr/arm-linux-gnueabi/lib/libgcc_s.so.1 /lib
sudo cp /usr/arm-linux-gnueabi/lib/libc.so.6 /lib
Please let me know if there are other better solutions as I am interested to know.
If you want to run ARM without Linux, then you need a different compiler (at least). arm-linux-gnueabi-gcc is a compiler for Linux. The compiler and libc are intimately linked. You will need a newlib compiler with a portability layer for qemu.porting newlib
See: Balau and Google newlib+qemu. A newlib port is hosted at Github and seems to the same as the Balau blog.
Typically a non-Linux gcc is called arm-none-eabi-gcc. The prefix arm-none-eabi- is recognized by some configure scripts.
A variant, which worked for me, was to pass the loader library directly and to specify the required library paths using the loader parameter --library-path. For example:
$ TOOLCHAIN_ROOT=/usr/local/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/arm-linux-gnueabihf
$ qemu-arm $TOOLCHAIN_ROOT/libc/lib/ld-linux-armhf.so.3 --library-path $TOOLCHAIN_ROOT/libc/lib/arm-linux-gnueabihf:/$TOOLCHAIN_ROOT/lib ./my_executable
Or equivalently export LD_LIBRARY_PATH instead of using --library-path.
I am having trouble cross-compiling a library for my arm board using autconf.
I am using this line:
./configure --target=arm-linux --host=arm-linux --prefix=/bla/bla/bla/linux_arm_tool CFLAGS='-m32'
make
make install
When I do file to check it I get:
libjpeg.so.8.4.0: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
That doesn't seem right at all, but I tried using it anyway... and I get:
/usr/lib/gcc/arm-linux-gnueabi/4.5.3/../../../../arm-linux-gnueabi/bin/ld: skipping incompatible /bla/bla/bla/bla/../linux_arm_tool/lib/libjpeg.so when searching for -ljpeg
I'm at a loss, I've been googling for an hour now...
So I knew I've cross compiled before using really basic method calls and I figured out why I've gotten away with this before after examining the output:
checking for arm-linux-gnueabi-gcc... no
checking for gcc... gcc
...
...
checking for arm-linux-gnueabi-gcc... gcc
In my /usr/bin there was no arm-linux-gnueabi-gcc, I had to:
ln -s /usr/bin/arm-linux-gnueabi-gcc-4.5 /usr/bin/arm-linux-gnueabi-gcc
I successfully cross-compiled using:
./configure --host=arm-linux-gnueabi -prefix=${CSTOOL_DIR}/linux_arm_tool
as for linking ... I still have to check some things, but I am going to assume I might need to throw some -rpath-link flags in more advanced compiles.
I think the problem could be restated more generally as: "How do I use Autoconf to cross compile for ARM?"
According to ./configure -h:
System types:
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
The official GNU documentation is helpful for answering this question:
http://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Hosts-and-Cross_002dCompilation.html
Note when they defining the usage of --host and and --build:
Therefore, whenever you specify --host, be sure to specify --build too.
And here is an example that I just used to configure iperf for my embedded ARM platform:
First of all the "./configure" script is actually called "Autoconf" which really helps for google-ing.
The idea here is to:
Have your cross compilers in your current $PATH
Set the CC and CXX environment variables to point to the cross compilers
Give the right --host and --build
buildpath <--- my little script to setup my $PATH
export CC=arm_v5t_le-gcc
export CXX=arm_v5t_le-g++
./configure --host=armv5tl-montavista-linux-gnueabi --build=x86_64-linux-gnu
You need to override the environment variables CC, LD, and other pertinent ones. Setting those switches doesn't tell configure where your cross tool chain is (it could be anywhere)
Check out some guides for various projects, for instance:
http://wiki.wxwidgets.org/Cross-Compiling_Under_Linux
Also, here is a script I made to setup cross compile for node.js - same idea:
https://gist.github.com/edhemphill/5094239
The libjpeg is not going to work b/c it's a x86 binary, you need it to say:
ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, not stripped
or similar.
This is the reason you are getting a skipping incompatible
# Install arm-linux-gnueabi packages
apt-get install libc6-armel-cross libc6-dev-armel-cross \
binutils-arm-linux-gnueabi arm-linux-gnueabi-gcc libncurses5-dev
./configure --target=arm-linux-gnueabi --host=arm-linux-gnueabi
...
checking for arm-linux-gnueabi-gcc... arm-linux-gnueabi-gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... yes
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether arm-linux-gnueabi-gcc accepts -g... yes
checking for arm-linux-gnueabi-gcc option to accept ISO C89... none needed
checking whether arm-linux-gnueabi-gcc understands -c and -o together... yes
checking whether make supports the include directive... yes (GNU style)
checking dependency style of arm-linux-gnueabi-gcc... gcc3
...
make
arm-linux-gnueabi-gcc -DPACKAGE_NAME=\"Tutorial\ Program\" -DPACKAGE_TARNAME=\"tutorial-program\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"Tutorial\ Program\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"tutorial-program\" -DVERSION=\"1.0\" -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
I am trying to build a arm toolchain from scratch.
I am referring to this site.
http://www.nixit.co.uk/cortex-m3-mac-1
Followed all the instructions carefully. Everything went well till newlib compilation. I am getting strange error.
/bin/bash: arm-none-eabi-cc: command not found
So I checked the Makefile
there is a line in makefile. There is a directive related to arm-none-eabi-cc
# -----------------------------------------------
# Programs producing files for the TARGET machine
# -----------------------------------------------
AR_FOR_TARGET=arm-none-eabi-ar
AS_FOR_TARGET=arm-none-eabi-as
CC_FOR_TARGET=$(STAGE_CC_WRAPPER) arm-none-eabi-cc
# If GCC_FOR_TARGET is not overriden on the command line, then this
# variable is passed down to the gcc Makefile, where it is used to
# build libgcc2.a. We define it here so that it can itself be
# overridden on the command line.
GCC_FOR_TARGET=$(STAGE_CC_WRAPPER) arm-none-eabi-gcc
I checked the /usr/arm/bin directory. So i do find arm-none-eabi tools, but not arm-none-eabi-cc
arm-none-eabi-ld arm-none-eabi-readelf
arm-none-eabi-ar arm-none-eabi-gcc-4.4.3 arm-none-eabi-nm arm-none-eabi-size
arm-none-eabi-as **arm-none-eabi-gcc**
Please help
Try replacing arm-none-eabi-cc in the Makefile with arm-none-eabi-gcc, or symlinking arm-none-eabi-cc to arm-none-eabi-gcc.