vdhieu
Posts: 5
Joined: Fri Jul 31, 2020 9:55 am

Cross-compile for PI

Fri Jul 31, 2020 10:00 am

I created a file main.c on my Ubuntu
#include <stdio.h>
#include <wiringPi.h>

int main(void)
{
int i;
wiringPiSetup();
pinMode(7, OUTPUT);
while(1)
{
digitalWrite(7, HIGH);
delay(500);
digitalWrite(7, LOW);
delay(500);
}
return 1;
}

Now i want to cross-compile this file for PI. But issue that:
main.c:2:22: fatal error: wiringPi.h: No such file or directory

I think i need to copy wiringPi.h to somewhere.
Could anyone help me please.
Thank you!

GlowInTheDark
Posts: 1065
Joined: Sat Nov 09, 2019 12:14 pm

Re: Cross-compile for PI

Fri Jul 31, 2020 10:41 am

The short answer is going to be:

1) Copy wiringpi.h from the Pi to the directory containing your source file on Ubuntu.
2) Include -I. on your compile command line.

The longer answer, which is really a question, is: How did you set up your cross-compiler? Are you sure it works at all?
GitD's list of things that are not ready for prime time:
1) IPv6
2) 64 bit OSes
3) USB 3
4) Bluetooth

Loves Linux; loves to dance.

User avatar
jahboater
Posts: 6270
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: Cross-compile for PI

Fri Jul 31, 2020 10:58 am

Have you actually tried compiling this on the Pi?

Why do you want to cross compile ?

Although your Ubuntu machine may be more powerful, a Pi4 will compile a tiny program like that in a few milliseconds.
Pi4 8GB running PIOS64 Lite

fbe
Posts: 648
Joined: Thu Aug 17, 2017 9:08 pm

Re: Cross-compile for PI

Fri Jul 31, 2020 7:44 pm

jahboater wrote:
Fri Jul 31, 2020 10:58 am
Although your Ubuntu machine may be more powerful, a Pi4 will compile a tiny program like that in a few milliseconds.
Although a Pi4 will compile this program, you will have to find a wiringPi version, that is compatible with Pi4 to run it on a Pi4.
Please don't start new projects with wiringPi. http://wiringpi.com/wiringpi-deprecated/

User avatar
jahboater
Posts: 6270
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: Cross-compile for PI

Fri Jul 31, 2020 7:51 pm

fbe wrote:
Fri Jul 31, 2020 7:44 pm
jahboater wrote:
Fri Jul 31, 2020 10:58 am
Although your Ubuntu machine may be more powerful, a Pi4 will compile a tiny program like that in a few milliseconds.
Although a Pi4 will compile this program, you will have to find a wiringPi version, that is compatible with Pi4 to run it on a Pi4.
Please don't start new projects with wiringPi. http://wiringpi.com/wiringpi-deprecated/
Agreed.

I suggest pigpio
http://abyz.me.uk/rpi/pigpio/
Pi4 8GB running PIOS64 Lite

vdhieu
Posts: 5
Joined: Fri Jul 31, 2020 9:55 am

Re: Cross-compile for PI

Sun Aug 02, 2020 3:23 pm

Thank you all for your reply.
1. I installed toolchain for cross-compile on Ubuntu, compiled a simple file and run well on PI. -> toolchain is fine.
2. I installed wiringPI on Ubuntu, not error.
3. I compiled this file on PI and run well. (I installed wiringPI on PI)
4. I use cross-compile because i want to prastice this and may be i need this for the future.
5. I think the method for this issue: i need to copy wiringPi.h to somewhere, but dont know to where. I copied to source folder, but also can not build. I also copied to /usr/local/bin, /lib, ../toolchain/gcc.../bin, lib/ , everywhere i can but the same error.
So i think we can not use wiringPi for cross-compile, because when we install wiringPi , it need to know our platform.

elotronico
Posts: 3
Joined: Mon Apr 04, 2016 4:19 pm

Re: Cross-compile for PI

Sun Aug 02, 2020 11:55 pm

Hello
i'm in the same situation like you.

I have spended a week looking for some guide or manual to cross compile from my laptop (linux ubuntu) to Raspberry pi 3, maybe if we join our efforts we will goal.

I too use the g++-arm-linux-gnueabihf.
In a subfolder of the "project" i've got the entire library of wiringPi, but this doesn't work.

The problems i have are the same like you. I made a simple program "Hello world" and it compile it in laptop and run perfectly in rpi3, buy if try to use the library wiritngPi i've got errors.

This are the two webs more helps me:
https://hackaday.com/2016/02/03/code-cr ... pberry-pi/
https://medium.com/@zw3rk/making-a-rasp ... d75ba#bd07

This are my commands:

Code: Select all

arm-linux-gnueabihf-g++ -O3 -g3 -Wall -c -o "blink.o" blink.cpp -fPIC -L /home/eloy/Documents/FIRMWARE/wiringpi-2.46-1/usr/include/wiringPi
This doesn't give errors

Code: Select all

 arm-linux-gnueabihf-g++ -o "blink" blink.o
wpi.o: In function `main':
/home/eloy/Documents/FIRMWARE/blink.cpp:10: undefined reference to `wiringPiSetup'
/home/eloy/Documents/FIRMWARE/blink.cpp:13: undefined reference to `digitalWrite'
/home/eloy/Documents/FIRMWARE/blink.cpp:13: undefined reference to `delay'
/home/eloy/Documents/FIRMWARE/blink.cpp:14: undefined reference to `digitalWrite'
/home/eloy/Documents/FIRMWARE/blink.cpp:14: undefined reference to `delay'
collect2: error: ld returned 1 exit status
here are the errors!!

The website of hackaday mentioned before indicates:

Code: Select all

arm-linux-gnueabihf-g++ -O3 -g3 -Wall -c -o -fPIC "hello.o" "hello.cpp"
arm-linux-gnueabihf-g++ -o "hello" hello.o
The first line compiled the file hello.cpp and the second linked the compiler output to build the executable hello. Assuming all goes well, enter the following command and you should see output similar to what is shown in italics:

User avatar
Paeryn
Posts: 3074
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Cross-compile for PI

Mon Aug 03, 2020 2:04 am

elotronico wrote:
Sun Aug 02, 2020 11:55 pm
This are my commands:

Code: Select all

arm-linux-gnueabihf-g++ -O3 -g3 -Wall -c -o "blink.o" blink.cpp -fPIC -L /home/eloy/Documents/FIRMWARE/wiringpi-2.46-1/usr/include/wiringPi
This doesn't give errors
The last pair of command line arguments are seeming at odds, you use -L which adds the path following it to the linker search path but (a) you've told gcc to not call the linker and (b) the path you supplied looks to be to where the header files are located so I wouldn't expect the linker to find the library in there anyway. You need -I (that is an upper-case i as in include) when providing paths to search for header files, but since you said it compiled fine I assume the headers were in the default search path anyway.
elotronico wrote:
Sun Aug 02, 2020 11:55 pm

Code: Select all

 arm-linux-gnueabihf-g++ -o "blink" blink.o
wpi.o: In function `main':
/home/eloy/Documents/FIRMWARE/blink.cpp:10: undefined reference to `wiringPiSetup'
/home/eloy/Documents/FIRMWARE/blink.cpp:13: undefined reference to `digitalWrite'
/home/eloy/Documents/FIRMWARE/blink.cpp:13: undefined reference to `delay'
/home/eloy/Documents/FIRMWARE/blink.cpp:14: undefined reference to `digitalWrite'
/home/eloy/Documents/FIRMWARE/blink.cpp:14: undefined reference to `delay'
collect2: error: ld returned 1 exit status
here are the errors!!
In this command you are now telling gcc to call the linker to generate the executable but you haven't told it to link the wiringPi library which is why it can't find the functions. You need to add -lwiringPi to the line to tell it you want the wiringPi library linking in and an appropriate -L with path to said library if it isn't in the default search path.

Code: Select all

arm-linux-gnueabihf-g++ -o "blink" blink.o -lwiringPi
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

vdhieu
Posts: 5
Joined: Fri Jul 31, 2020 9:55 am

Re: Cross-compile for PI

Mon Aug 03, 2020 4:41 am

I tried too many thing but nothing got. Maybe you get luck.
Read this:You may also need to add
-I/usr/local/include -L/usr/local/lib -lwiringPi
to the compile line of your program depending on the environment you are using.

If you open wiringPi.h, you will see it includes boardtype_friendlyelec.h. I guess we need define our board somewhere to wiringPi normally install.

http://wiringpi.com/reference/

elotronico
Posts: 3
Joined: Mon Apr 04, 2016 4:19 pm

Re: Cross-compile for PI

Tue Aug 04, 2020 11:39 pm

Thanks all,
Paeryn you are righ!! the -c parameter cancels the -L (include library)

I've got the solution!!!
In my case, the errors are because i'm not a professional programmer and I do not know many basics of the c/c++ language, but google helps me.
I don't know what i have been doing. Now i know better the library and compilation process, that's the success.

PROCEDURE:
MEET THE LIBRARY:
http://wiringpi.com/wiringpi-deprecated/ where Mr. Gordon indicates that the source code becomes private, he only share de compiled library so you should use the library like an dynamic library.

LEARN DIFFERENCE BETWEEN STATIC LIBRARY AND DYNAMIC LIBRARY
(from google translator)
Types of libraries

There are various classifications of libraries, which we will simplify as two types: static and dynamic.

Static Libraries. They bind when compiling, they are "inside" the final executable. In Windows they have the .lib extension. In Linux they have the extension .a.

Dynamic Libraries. They bind when run, the operating system must find them when running the program. If an app installs well, the operating system shouldn't have a problem finding it.
In Windows they have the .dll extension (generally in c: \ windows \ system32 and without a version number, hence the so-called dll hell).
In Linux they have the extension .so (usually in / usr / lib or / usr / local / lib, read about the folder structure in Debian and derivatives); said operating system updates its listing with a sudo ldconfig).


LEARN ABOUT DYNAMIC LIBRARIES
https://www.cprogramming.com/tutorial/s ... x-gcc.html
Here are some interesting and vital things like: the parameter "-lwiringPi" refers to the file "libwiringPi.so"


CONCLUSION:
I begin with a folder /home/eloy/FIRMWARE that contains the blink.cpp and the library wiringPi
Inside the directory of the library we have the directory: /home/eloy/Documents/FIRMWARE/wiringpi-2.46-1/usr/lib. Here are the compiled library. The .so files are that we need. The parameter -L must be this directory
To cross-compile using the wiringPi library the code seems like this

Code: Select all

#include <stdio.h>
#include "/home/eloy/Documents/FIRMWARE/wiringpi-2.46-1/usr/include/wiringPi.h"

int main(void){

  wiringPiSetup() ;
  for (;;){
    digitalWrite (0, HIGH) ; delay (250) ;
    digitalWrite (0,  LOW) ; delay (250) ;
  }
  return 0 ;
}

Code to compile it on laptop:

Code: Select all

arm-linux-gnueabihf-g++ -Wall -L/home/eloy/Documents/FIRMWARE/wiringpi-2.46-1/usr/lib -o "blink" blink.cpp -lwiringPi
-L indicates where are the .so files (compiled library)
-lwiringPi refeers to libwiringPi.so from the directory indicated before. (to understand this read the link from cprogramming.com indicated before)

IMPORTANT NOTE:
If you upload this compiled firmware to the pi and run it, it works. But keep in mind that the library that are using the pi is not the same that your compiler!!

User avatar
Paeryn
Posts: 3074
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Cross-compile for PI

Wed Aug 05, 2020 12:47 am

elotronico wrote:
Tue Aug 04, 2020 11:39 pm
Thanks all,
Paeryn you are righ!! the -c parameter cancels the -L (include library)
It's not that -c cancels the -L, it doesn't, rather gcc doesn't use the paths added by -L itself, it just passes them to the linker (typically ld). When you pass -c to gcc you are telling it to only go so far as to generating object files (those with names typically ending in .o) and to not invoke the linker. Since the linker is not invoked, any library paths you pass when calling gcc with -c will just be thrown away (they don't get stored in the object files).
elotronico wrote:
Tue Aug 04, 2020 11:39 pm

Code: Select all

#include <stdio.h>
#include "/home/eloy/Documents/FIRMWARE/wiringpi-2.46-1/usr/include/wiringPi.h"
...
Using absolute path names in #include "" is considered bad practice, especially if said header file includes other header files which are relative. You should use relative path names and if the header files aren't in the default search directories then you add the base directory for the compiler to search in with the -I flag (this one is used when using -c as the compiler needs it). If you have already compiled the code to object files (using this) then you don't need to pass this when using gcc to just link the object files and libraries into an executable as the linker doesn't use it, only the compiler.
E.g.

Code: Select all

#include <stdio.h>
#include "wiringPi.h"
...
And compile with

Code: Select all

arm-linux-gnueabihf-g++ -Wall -L/home/eloy/Documents/FIRMWARE/wiringpi-2.46-1/usr/lib -I/home/eloy/Documents/FIRMWARE/wiringpi-2.46-1/usr/include  -o "blink" blink.cpp -lwiringPi
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

vdhieu
Posts: 5
Joined: Fri Jul 31, 2020 9:55 am

Re: Cross-compile for PI

Wed Aug 05, 2020 8:04 am

I still cant compile.

logitech@logitech-VirtualBox:/opt/FriendlyARM/WiringNP/examples$ aarch64-linux-gnu-gcc -o main blink.o -L /opt/FriendlyARM/WiringNP/wiringPi/ -I /opt/FriendlyARM/WiringNP/wiringPi/ -lwiringPi
/opt/FriendlyARM/toolchain/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/6.3.1/../../../../aarch64-linux-gnu/bin/ld: cannot find -lwiringPi
collect2: error: ld returned 1 exit status

User avatar
DougieLawson
Posts: 40134
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Cross-compile for PI

Wed Aug 05, 2020 8:54 am

Get 2.52 of wiringPi (last ever version as it's now deprecated) from http://wiringpi.com/wiringpi-updated-to ... rry-pi-4b/ (it runs OK on any RPi model).
Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All fake doctors are on my foes list.

Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

elotronico
Posts: 3
Joined: Mon Apr 04, 2016 4:19 pm

Re: Cross-compile for PI

Wed Aug 05, 2020 12:17 pm

vdhieu

Code: Select all

VirtualBox:/opt/FriendlyARM/WiringNP/examples$ aarch64-linux-gnu-gcc -o main blink.cpp -L /opt/FriendlyARM/WiringNP/wiringPi/usr/lib/ -lwiringPi

Try this.
Read my last post and the links mentioned. In the -L parameter you should indicate the folder where are the .so files

hoserr9
Posts: 12
Joined: Mon Aug 24, 2020 5:05 pm

Re: Cross-compile for PI

Fri Sep 18, 2020 9:27 pm

What if you just want to build your cross compiling toolchain from source?

swampdog
Posts: 413
Joined: Fri Dec 04, 2015 11:22 am

Re: Cross-compile for PI

Sat Sep 19, 2020 2:44 pm

hoserr9 wrote:
Fri Sep 18, 2020 9:27 pm
What if you just want to build your cross compiling toolchain from source?
If you're prepared to do that then there's a counter intuitive way to cross compile using 'distcc' and your pi as the host - and you don't have to install any extra headers or libs other than on the host pi (as per normal native build). Essentially what you do is build a compiler for the host pi, build the same compiler as a cross for your x86 linux then use distcc such that it prioritises the most capable hardware (ie: the x86).

I was experimenting with this(*). In my case, I have a mixture of linux boxes and didn't want the faff of cross compiling gcc for each platform. I opted instead to use KVM/QEMU as it was installed in many places anyway. Create a VM in which to build the arm cross: pull the resultant binaries out of it into into a duplicate (aka lightwieight VM), fudge it a bit(**) then just duplicate the lightweight VM across your KVM hosts and all you have to do is change the hostname of each duplicated VM.

(*) Until my desktop PC started packing up. It's a waste to replace it now so I'm using it sparingly which is why I'm not here much.

(**) so that the VM looks to 'distcc' like a native compiler. It's just easier that way.

I did get as far as building QT with it on an rpi4 host with 26 cores (aka 'make -j26). The advantage of 'distcc' is if the KVM doesn't exist, it can be skipped which means one can spin up/down an arm-cross VM in a cloudy fashion.

There's various ways to use 'distcc' but the simplest oldest use case appears best. The host pi distcc gathers together all the headers and sends the entire preprocessed compilation unit off to an arm cross VM which returns the object file. The host pi does the linking. These two facts together mean the arm cross needs no extra headers/libs installed. I used a 4Gb rpi4 as the host. If you've extra rpi3/4 lying around they can be added to the DISTCC_HOSTS list as well.

In summary though, with the advent of rpi4 there's no need for cross compilation unless you're doing big builds from scratch a lot.


I built my arm cross using a centos7 VM. You'll need suitable binutils/linux/libc if memory serves (which it may not). From the timestamps looks like last I messed with it was over a year ago and the build failed so no point even posting the versions. I've set it off again and on the offchance it does succeed I'll post details next time my desktop PC is turned on.

Return to “C/C++”