alphaville / optimization-engine

Nonconvex embedded optimization: code generation for fast real-time optimization + ROS support
https://alphaville.github.io/optimization-engine/
Other
499 stars 53 forks source link

Cross compiling for Raspberry Pi #151

Closed gmsanchez closed 4 years ago

gmsanchez commented 4 years ago

I want to use OpEn from a ROS C++ node, because of that, I am trying to run OpEn on a Raspberry Pi with its C bindings as a first step.

I am running the current stable KDE Neon distribution, which is based on Ubuntu 18.04 I did the following:

rustup target add arm-unknown-linux-gnueabihf
apt install gcc-arm-linux-gnueabihf

The gcc-arm-linux-gnueabihf installs GCC version 7.4.0.

Then I modified the C/C++ Bindings example in the documentation in order to cross compiling for the Raspberry Pi, as mentioned on OpEn on Raspberry Pi. The code I used is attached. After running python3 rosenbrock_codegen.py I get the errors that can be seen in the attached log file.

Any help would be appreciated. Thanks in advance!

rosenbrock_codegen.py.txt rosenbrock_codegen_output.log

gmsanchez commented 4 years ago

As a workaround, removed line 49 from the attached code (the one that sets cross compiling with the line .with_target_system("arm-unknown-linux-gnueabihf")) and I did the following:

  1. Install rust and clang following the installation instructions on the Raspberry Pi.
  2. Copy the generated the_optimizer folder to the Raspberry Pi.
  3. Access to the the_optimizer folder on the Raspberry Pi.
  4. Compile the Optimization Engine libraries running
    cargo clean
    cargo build --release
  5. Compile and run the C bindings following the C/C++ Bindings tutorial
    gcc optimizer.c -lthe_optimizer -L./target/release -pthread -lm -ldl -o optimizer
    LD_LIBRARY_PATH=./target/release ./optimizer
alphaville commented 4 years ago

To cross-compile for a Raspberry Pi you need the target arm-unknown-linux-gnueabihf. There's a shorthand for that - you can compile using

build_config = og.config.BuildConfiguration() \
    .with_build_directory("your_path")\
    .with_target_system("rpi")

Then as you said you need to transfer the cross-compiled executable onto Raspberry. I have tried that on a Raspberry Pi Model B and it seems to work. You can find some documentation here but it would be worth having a standalone example.

As far as I know, you cannot compile Rust programs directly on Raspberry Pi, although I read somewhere that it is supported on Pi 3.

gmsanchez commented 4 years ago

Thanks for the quick reply!

To cross-compile for a Raspberry Pi you need the target arm-unknown-linux-gnueabihf

As I said in my report, I installed the target architecture for Rust by running the commands

rustup target add arm-unknown-linux-gnueabihf
apt install gcc-arm-linux-gnueabihf

on my notebook. Is that all I need? Or do I have to do something else?

Then, as the attached code shows, I set up the build_config as follows

build_config = og.config.BuildConfiguration()           \
    .with_rebuild(True)                                 \
    .with_build_mode("release")                         \
    .with_target_system("arm-unknown-linux-gnueabihf")                          \
    .with_build_c_bindings()            # <- The important setting

As the documentation says, rpi is a shorthand for arm-unknown-linux-gnueabihf so it would be equivalent to use one or another. Right?

After running the attached code, I get the errors attached in the log file and I don't have any cross-compiled executable. Would you mind trying to run the attached code?

As far as I know, you cannot compile Rust programs directly on Raspberry Pi, although I read somewhere that it is supported on Pi 3.

Ignorance bliss then! Lucky me :smile:

Thanks in advance!

alphaville commented 4 years ago

I tried your code and it works on my system, so I suspect it's a matter of configuring your target.

I see you're getting the message "error: linking with cc failed." I suppose this means that your program is trying to link using cc instead of the appropriate ARM-specific compiler/linker.

Can you have a look at https://github.com/japaric/rust-cross#tldr-ubuntu-example? You should make sure that you have updated your ~/.cargo/config configuration file.

Regarding your other question, yes, rpi and arm-unknown-linux-gnueabihf are the same thing.

alphaville commented 4 years ago

@gmsanchez you can try this out by using opengen version 0.3.2a1. You can install it using

pip install opengen==0.3.2a1
gmsanchez commented 4 years ago

After adding

[target.arm-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"

to my ~/.cargo/config file, the cross-compiling works.

Thanks a lot for the help!