How to cross compile redis for ARM on Ubuntu? - redis

I have downloaded redis-5.0.6 on Ubuntu and tried to compile redis in x86_64 and the redis-server could work appropriately. Now I need to cross compile it and run it in ARM 32bits linux system
I have tried to install arm-linux-gnueabi-gcc and add CC=arm-linux-gnueabi-gcc in Makefile before compiling but it didn't work. There is no ./configure in redis path so I don't know how to regenerate Makefile

An aging question, but worth sharing some information for others...
This is still an open issue with Redis, see this and this.
A workaround would be to statically build it on a similar machine, say a raspberry pi.
Then copy the directory of binaries over to your target host similar to this.
make distclean && make CFLAGS="-static" EXEEXT="-static" LDFLAGS="-I/usr/local/include/" PREFIX=~/_build/
Any missing shared objects on the target, try to find and copy from debian.org

Related

How to compile objdump for the m32c architecture

I would like to use objdump to view binary m32c files. When I type in: objdump -i the architecture list returned is i386 based. Looking at the source code from binutils it appears that the m32c architecture is supported, just not compiled in by default.
I've also seen arm-none-eabi-objdump for the embedded ARM market. What I would like to create is a compiled version of objdump for the m32c architecture. Has anyone done something similar?
Building binutils for a specific target is pretty straightforward. If binutils is to be hosted on Windows, you will need to install MinGW/GCC and the Msys shell environment. Then from within a Linux bash shell or msys on Windows:
Create a directory to build the tools ()
Create a directory to which to install the tools ()
Extract the binutils package into , hereafter refers to the binutils verion you are building, and is indicated in the package name (binutils-.tar.bz2)
Working from , configure the package for the appropriate target and host:
../binutils-<version>/configure --target m32c-elf --prefix <installdir>
In Windows you can also add to the configure command line --enable-win32-registry=gnu_m32c to allow path lookup via the registry. The toolchain name gnu_m32c is arbitrary - you can call it what you like.
Run make to build the tools.
Run make install-strip to install the tools.
Note:
If you are installing on Windows and used the --enable-win32-registry option but subsequently choose to move the installation, or are installing your pre-build tools on a new host, you will need to modify the registry to match; this can be done in regedit editing the key HKEY_LOCAL_MACHINE\SOFTWARE\Free Software Foundation\gnu_m32c, adding/modifying the item:"BINUTILS"="<installdir>" if you have installed GCC as well there are related keys:
"GCC"="<gccinstalldir>"
"G++"="<gppinstalldir>"

CMake won't link when moved to 64-bit system

I had been using CMake without problems when I discovered my Ubuntu was installed as 32-bit even though my processor is actually 64-bit. Whoops.
I reinstalled Ubuntu and the various dev packages I was using. Now when I run make I get errors like this:
[ 1%] make[2]: *** No rule to make target `/usr/lib/i386-linux-gnu/libQtGui.so', needed by `/home...
/usr/lib/i386-linux-gnu/libQtGui.so` doesn't exist but /usr/lib/x86_64-linux-gnu/libQtGui.so does.
I have run ccmake to reconfigure and regenerate the makefile and run make clean but it's still looking for 64-bit libraries. If I expand the ccmake options I can see the 32-bit library path in various variables.
I have created a new build directory and run ccmake from scratch and this works but now I have to remember all the nondefault settings I put in and reproduce them in the new build environment.
I'd rather just "upgrade" the CMake setup to 64-bit, preserving my own flags. Is this possible?
Start with a new CMake cache:
rm CMakeCache.txt
If you don't like removing your Cmake cache, you can edit it and search-and-replace to modify the paths of libraries.

Building a cross-platform application (using Rust)

I started to learn Rust programming language and I use Linux. I'd like to build a cross-platform application using this language.
The question might not be related to Rust language in particular, but nonetheless, how do I do that? I'm interested in building a "Hello World" cross-platform application as well as for more complicated ones. I just need to get the idea.
So what do I do?
UPDATE:
What I want to do is the ability to run a program on 3 different platforms without changing the sources. Do I have to build a new binary file for each platform from the sources? Just like I could do in C
To run on multiple platforms you need to build an executable for each as #huon-dbauapp commented.
This is fairly straightforward with Rust. You use "--target=" with rustc to tell it what you want to build. The same flag works with Cargo.
For example, this builds for an ARM target:
cargo build --target=arm-unknown-linux-gnueabihf
See the Rust Flexible Target Specification for more about targets.
However, Rust doesn't ship with the std Crate compiled for ARM (as of June 2015). If this is the case for your target, you'll first need to compile the std Crates for the target yourself, which involves compiling the Rust compiler from source, and specifying the target for that build!
For information, most of this is copied from: https://github.com/japaric/ruststrap/blob/master/1-how-to-cross-compile.md
The following instructions are for gcc, so if you don't have this you'll need to install it. You'll also need the corresponding cross compiler tools, so for gcc:
sudo apt-get install gcc-arm-linux-gnueabihf
Compile Rust std Crate For ARM
The following example assumes you've already installed the current Rust Nightly, so we'll just get the sources and compile for ARM. If you are using a different version of the compiler, you'll need to get that to ensure your ARM libraries match the version of the compiler you're using to build your projects.
mkdir ~/toolchains
cd ~/toolchains
git clone https://github.com/rust-lang/rust.git
cd rust
git update
Build rustc for ARM
cd ~/toolchains/rust
./configure --target=arm-unknown-linux-gnueabihf,x86_64-unknown-linux-gnu
make -j4
sudo make install
Note "-j4" needs at least 8GB RAM, so if you hit a problem above try "make" instead.
Install ARM rustc libraries In native rustc build
sudo ln -s $HOME/src/rust/arm-unknown-linux-gnueabihf /usr/lib/rustlib/arm-unknown-linux-gnueabihf
Create hello.rs containing:
pub fn main() {
println!("Hello, world!");
}
Compile hello.rs, and tell rustc the name of the cross-compiler (which must be in your PATH):
rustc -C linker=arm-linux-gnueabihf-gcc-4.9 --target=arm-unknown-linux-gnueabihf hello.rs
Check that the produced binary is really an ARM binary:
$ file hello
hello: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), (..)
SUCCESS!!!:
Check: the binary should work on an ARM device
$ scp hello me#arm:~
$ ssh me#arm ./hello
Hello, world!
I've used this to build and link a Rust project with a separate C library as well. Instructions similar to the above on how to do this, dynamically or statically are in a separate post, but I've used my link quota up already!
The best way to figure this out is to download the source code for Servo and explore it on your own. Servo is absolutely a cross-platform codebase, so it will have to address all of these questions, whether they be answered in build/configuration files, or the Rust source itself.
It looks like the rust compiler might not be ready to build standalone binaries for windows yet (see the windows section here), so this probably can't be done yet.
For posix systems it should mostly Just Work unless you're trying to do GUI stuff.
Yes, you won't need to change the source, unless you are using specific libraries that are not cross-platform.
But as #dbaupp said native executables are different on each platform, *nix uses ELF, Windows PE, and OSX Mach-O. So you will need to compile it for each platform.
I don't know the state of cross-compiling in rust, but if they already implemented it, then you should be able to build all the binaries in the same platform, if not, you will have to build each binary on it's platform.

How to cross compile CMake for ARM with CMake

In short I'm trying to cross compile CMake with CMake, and I don't think I'm linking libraries correctly. What I want to do may not be possible, but I'd at least like to know why it isn't possible if that's the case.
System: The host is a Linux box with a Cavium ARM9 CPU. It's currently running version 2.6.24.4 of the Linux kernel and Debian 5.0 (Lenny). My workstation is a Core i5 running Ubuntu 12.04 LTS (Precise Pangolin).
My overall goal is to get ROS running on the Linux box. I have to compile from source rather than use apt since Debian 6.0 (Squeeze) binaries require thumb support that the Cavium does not give, and not many of the needed packages are available for Debian 5.0 (Lenny). I'd made progress installing the various libraries needed, but when I got to step 1.3.1 and tried to run CMake, I got the error
CMake 2.8 or higher is required. You are running version 2.6.0
Next I tried to download and build CMake 2.8.8 on the Linux box itself, but it was too much for the system. When that failed, I downloaded the toolchain suggested on the manufacturer's website and used the cross-compiling guide at [www.cmake.org/Wiki/CMake_Cross_Compiling] to build the CMake executables. Here is my toolchain file:
# This one is important
SET(CMAKE_SYSTEM_NAME Linux)
# Specify the cross compiler
SET(CMAKE_C_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-gcc)
SET(CMAKE_CXX_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-g++)
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/arm-unknown-linux-gnu)
# 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)
However, use of the binary on the Linux box gives the error
cmake: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by cmake)
Sure enough, the library is not there:
prompt# strings /usr/lib/libstdc++.so.6 | grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBC_2.3
GLIBC_2.0
GLIBC_2.3.2
GLIBC_2.1
GLIBC_2.1.3
GLIBC_2.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
I've never cross-compiled before, but I can see one of two scenarios happening: either the binary got created with a link to a higher version of glibcxx on the host machine or the manufacturer's toolchain is more modern than their image. I don't know how to check which is happening or if something else is happening that I don't know about.
My last effort involved trying to statically cross-compile CMake to hopefully get rid of the linking error with
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-technologic.cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS_RELEASE="-static" ..
I got build errors, and that binary didn't work either. I got:
FATAL: kernel too old
Segmentation fault
I'd try installing glibcxx 3.4.14 on the Linux box, but it doesn't look like it's available for this processor.
I've tried searching for CMake dependencies or system requirements and can't find anything. I've also searched on how to build CMake, but most searches turn up how to build other things with CMake rather than building CMake itself.
I do cross-compile a lot for ARM9 devices using CMake, and indeed this looks like you're not linking to the same libs you have on your target device. You shouldn't need to build CMake yourself to get this done, since it does have good support for cross-compiling since version 2.6. Just make sure you set the CMAKE_FIND_ROOT_PATH variable to a path where you have an exact copy of the root filesystem you have on your target device (with libraries and binaries pre-compiled for the target processor). That should solve your problems.
As a sidenote, I like to use crosstool-ng for building my cross-compilers. It is a really nice tool which helps you to build them from scratch, so I try to match the compiler version and glibc to the ones originally used to build the root filesystem (I usually start with a ready made root filesystem from ARMedslack, since I use Slackware for my development box and ARMedslack for my ARM targets).

armadillo C++ matrix library -- how to enable use of ATLAS or LAPACK?

When i compile example2.cpp with armadillo makefile and run it i am getting an error message
error: det(): use of ATLAS or LAPACK needs to be enabled
How do i fix that? I have similar errors when i try to use solve. Details of my setup are:
Ubuntu Lucid Lynx 10.04
Armadillo version: 2.4.2 (Loco Lounge Lizard)
ATLAS 3.9.51
BOOST 1.48.0
g++ (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
Atlas was installed before armadillo was, armadillo installation was configured with Cmake. I am far from an expert in cmake, but i thought that it was supposed to find ATLAS when i generated makefiles with it. Armadillo documentation seem to say that if i install with cmake i don't need to do any manual enabling of ATLAS. I tried to manually hack example2.cpp by inserting
#define ARMA_USE_ATLAS
before the headers, but it just generates a bunch of errors regarding missing stuff on Cblas. Maybe there is a step missing to allow cmake to find ATLAS. It feels i am missing something simple but key. Any help would be greatly appreciated.
Additional Detail:
Edit: for whatever reason i cannot add comment anymore, so i am posting a reply to #Appleman1234 answer below here.
I compiled armadillo and ATLAS from source. I thought that ATLAS has LAPACK and BLAS bundled in and optimized. When i compiled it, i passed a location to lapack tar like
./configure --shared --with-netlib-lapack-tarfile=/<path>/lapack-3.3.1.tgz
I also see in atlas lib directory the following files:
libatlas.a, libcblas.a, libf77blas.a, liblapack.a, libptcblas.a, libptf77blas.a libsatlas.so, libtatlas.so
which seem to indicate that blas, cblas, and lapack are installed on the system. However, CMakeCache.txt in armadillo seem to indicate that cmake didn't find BLAS, CBLAS, CLAPACK as follows
BLAS_LIBRARY:FILEPATH=BLAS_LIBRARY-NOTFOUND
There is no notion of ATLAS in CMakeCache.txt, so i assume that it wasn't found either. Maybe i am mistaken, but it seems that i somehow need to point cmake to ATLAS, i just don't know how. I could also be at error assuming that ATLAS has BLAS, LAPACK and CBLAS. I thought i compiled them as a part of ATLAS, but i could be wrong. Would appreciate your comments.
Solution to the problem:
What Dirk suggested almost worked. The problem as i mentioned in one of the replies to his post was cmake was balking. I misdiagnosed that as a problem with cmake not finding clapack. In fact, after looking more carefully at cmake output i realised it had problems with not finding good compiler or rather dragging its feet when it decided to use as compiler /usr/bin/c++. So i did CXX=g++ and then cmake again which worked fine. After that armadillo compiled fine.
Did you install armadillo from source ?
What did cmake output when running cmake . or ./configure ?
The latter just calls cmake ..
Did it output the values below ?
-- CLAPACK_FOUND = YES
-- CBLAS_FOUND = YES
If they are not YES, then according to CMakeLists.txt, ARMA_USE_ATLAS is set to false and ATLAS isn't used.
In order to use det or solve, install CLAPACK and CBLAS if you want to use ATLAS or just install LAPACK.
As armadillo exists in Debian / Ubuntu, you could simply install all the known build-dependencies to ensure you have all the -dev packages you need:
edd#max:~$ sudo apt-get build-dep armadillo
Reading package lists... Done
Building dependency tree
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
edd#max:~$
Appears that my system in complete in that regard.