arkaik
Posts: 23
Joined: Mon Mar 20, 2017 3:42 pm

Cross-compiling libi2c-dev issue

Thu May 18, 2017 4:00 pm

Hi everyone,

I'm currently trying to cross-compile a small program to communicate through i2c with an accelerometer.

When I compile on my raspberry pi, there is no problem but when I'm trying to compile on my computer, the linker doesn't find the library.

Code: Select all

gcc -o exec i2c.o i2cTest.o
i2c.o: in function « readByte »:
i2c.c:(.text+0xdd): undefined reference to « i2c_smbus_read_byte_data »
i2c.o: in function « writeByte »:
i2c.c:(.text+0x152): undefined reference to « i2c_smbus_write_byte_data »
collect2: error: ld returned 1 exit status
I tried to link the library in the command line but the library is still not found

Code: Select all

gcc -o exec i2c.o i2cTest.o -li2c-dev
/usr/bin/ld: can't find -li2c-dev
collect2: error: ld returned 1 exit status
Usually I'm using more specific libraries so I know where I put them but I installed both i2c-tools and libi2c-dev with apt-get so I don't really know where they are installed and how to give it to the linker.

I found the library with locate but strangely I can't find any in /usr/lib

Code: Select all

$ locate libi2c-dev
/usr/share/doc/libi2c-dev
/usr/share/doc/libi2c-dev/changelog.Debian.gz
/usr/share/doc/libi2c-dev/changelog.gz
/usr/share/doc/libi2c-dev/copyright
/usr/share/doc/libi2c-dev/dev-interface.gz
/var/cache/apt/archives/libi2c-dev_3.1.1-1_all.deb
/var/lib/dpkg/info/libi2c-dev.list
/var/lib/dpkg/info/libi2c-dev.md5sums
/var/lib/dpkg/info/libi2c-dev.postrm
/var/lib/dpkg/info/libi2c-dev.preinst
I also give you my code in case of someone is interested in.

i2c.h

Code: Select all

#ifndef I2C_H_
#define I2C_H_

#define LSM9DS1_I2C_BUS "/dev/i2c-1"

int initBus(void);
void setSlave(int i2cBus, uint8_t slaveAddress);
uint8_t readByte(int i2cBus, uint8_t slaveAddress, uint8_t regAddress);
void writeByte(int i2cBus, uint8_t slaveAddress, uint8_t regAddress, uint8_t byte);

#endif
i2c.c

Code: Select all

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include "i2c.h"

int initBus(void)
{
    int i2cBus = open(LSM9DS1_I2C_BUS, O_RDWR);
    if (i2cBus < 0)
    {
        fprintf(stderr, "Error oppening i2c bus : %s\n", LSM9DS1_I2C_BUS);
        exit(EXIT_FAILURE);
    }
    return i2cBus;
}

void setSlave(int i2cBus, uint8_t slaveAddress)
{
    //Set the slave address to communicate with
    if(ioctl(i2cBus, I2C_SLAVE, slaveAddress) < 0)
    {
        fprintf(stderr, "Slave unreachable : %x\n", slaveAddress);
        exit(EXIT_FAILURE);
    }
}

uint8_t readByte(int i2cBus, uint8_t slaveAddress, uint8_t regAddress)
{
    setSlave(i2cBus, slaveAddress);
    int value = i2c_smbus_read_byte_data(i2cBus, regAddress);
    if(value < 0)
    {
        fprintf(stderr, "Error reading register %x\n", regAddress);
        exit(EXIT_FAILURE);
    }
    return value;
}

void writeByte(int i2cBus, uint8_t slaveAddress, uint8_t regAddress, uint8_t byte)
{
    setSlave(i2cBus, slaveAddress);
    int value = i2c_smbus_write_byte_data(i2cBus, regAddress, byte);
    if(value < 0)
    {
        fprintf(stderr, "Error writing register %x\n", regAddress);
        exit(EXIT_FAILURE);
    }
}
i2cTest.c

Code: Select all

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include "i2c.h"

#define MAG_SLAVE_ADDR 0x1C
#define ACC_SLAVE_ADDR 0x6A

#define WHO_AM_I  0xF

int main(int argc, char * argv[])
{
    int i2cBus;

    i2cBus = initBus();

    uint8_t whoami = readByte(i2cBus, MAG_SLAVE_ADDR, WHO_AM_I);
    printf("%x\n", whoami);
}
If someone already had a similar issue I'd be glad to have some advices ;)

Thanks

User avatar
topguy
Posts: 6629
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: Cross-compiling libi2c-dev issue

Thu May 18, 2017 7:29 pm

"libi2c-dev" is the name of the installable package that contain header files you need to do development, that is why it has "-dev" in the name.
libi2c is the name of the library, so -li2c should be enough.

arkaik
Posts: 23
Joined: Mon Mar 20, 2017 3:42 pm

Re: Cross-compiling libi2c-dev issue

Fri May 19, 2017 8:17 am

Hi, thanks for your answer,

I also tried with -li2c but the library is not found by the linker either.

jahboater
Posts: 5944
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Cross-compiling libi2c-dev issue

Fri May 19, 2017 8:35 am

I'm currently trying to cross-compile a small program to communicate through i2c with an accelerometer.

When I compile on my raspberry pi, there is no problem but when I'm trying to compile on my computer, the linker doesn't find the library.
Then why not save yourself lots of trouble and just compile it on the Pi all the time?
Its a small program so the compile time should be insignificant.

arkaik
Posts: 23
Joined: Mon Mar 20, 2017 3:42 pm

Re: Cross-compiling libi2c-dev issue

Fri May 19, 2017 9:04 am

Because for now it's really small but it'll not stay long. That's why I'm trying to cross-compile it, for later use.
It will be a lot easier to have a Makefile for building and transfering code through ssh when I will begin to integer other things.

jahboater
Posts: 5944
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Cross-compiling libi2c-dev issue

Fri May 19, 2017 9:18 am

arkaik wrote:Because for now it's really small but it'll not stay long. That's why I'm trying to cross-compile it, for later use.
OK.
You can use the makefile to only compile the modules recently changed, each of which should be small even if the whole program is large - and make -j4 will use all four cores to build four modules at a time.

Compile time on the Pi is only an issue when you occasionally rebuild the entire project (and then only for really large programs).

The Pi (even a Pi Zero) is easily capable of compiling huge programs like the Linux kernel or GCC (around 17 million lines). Don't dismiss the Pi because its tiny and cheap!

arkaik
Posts: 23
Joined: Mon Mar 20, 2017 3:42 pm

Re: Cross-compiling libi2c-dev issue

Fri May 19, 2017 11:58 am

Yes I know I can compile on Rpi and it's not a problem, my point is I want to cross-compile, it's easier to code and compile on the same computer and it's a good exercise to understand how things works.

1 - Apparently I'm missing something so I would like to know what is it and how to fix it
2 - If every time I have an issue with something I'd change my mind to do it with another approach I'll never progress
3 - It could be useful for future projects to have a working toolchain

For all this reasons I want to have a working toolchain. Here compiling is okay, the problem is just that ld can't find the associated library and I don't know how to do it.

Thank for your answers btw ;)

User avatar
topguy
Posts: 6629
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: Cross-compiling libi2c-dev issue

Fri May 19, 2017 12:24 pm

arkaik wrote:Hi, thanks for your answer,
I also tried with -li2c but the library is not found by the linker either.
After a little more digging. I dont think there is a "libi2c" you need to link with. i2c is supported by the kernel and the header file just contain constants you need to talk to i2c devices but no functions you need to link with.
And you said that it worked on the Pi itself and I'm guessing it worked without any "-li2c"

The function "i2c_smbus_read_byte_data" is actually a Linux kernel function. So now I'm thinking that you might have the wrong gcc compiler.
I've seen that other crosscompilers for Raspbian is called for example "arm-unknown-linux-gnueabi-gcc" which I'm thinking means that this compiler already knows how to access Linux kernel functions.
But your "gcc" doesnt seem to know how to do that.

jahboater
Posts: 5944
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Cross-compiling libi2c-dev issue

Fri May 19, 2017 12:39 pm

arkaik wrote:it's easier to code and compile on the same computer
Yes of course - and the Pi has a wide choice of editors to code with!
arkaik wrote:and it's a good exercise to understand how things work.
Fair enough! Thats a good reason.
arkaik wrote:3 - It could be useful for future projects to have a working toolchain

For all this reasons I want to have a working toolchain.
Never forget that you already have a perfectly good working toolchain on the Pi and it will stay working in the future without any complicated effort on your part.

I'll say no more, have fun ...

arkaik
Posts: 23
Joined: Mon Mar 20, 2017 3:42 pm

Re: Cross-compiling libi2c-dev issue

Fri May 19, 2017 1:20 pm

@topguy You are right, I don't use -li2c to build on the raspi, I should precise it....

I tried all the compiler I had with the toolchain.

On both Rpi and computer I can build with classic gcc but not with the toolchain.

I'm thinking that the toolchain doesn't include the i2c-tools, so maybe I need to download it separately and link it when compiling with a -I$(I2C_HEADERS_DIRECTORY) don't you think?

@jahboater
arkaik wrote:
it's easier to code and compile on the same computer

Yes of course - and the Pi has a wide choice of editors to code with!
I don't have x server installed on my system, I'm using raspberry pi zero and my only access to it is through ssh ;)

User avatar
topguy
Posts: 6629
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: Cross-compiling libi2c-dev issue

Fri May 19, 2017 4:41 pm

arkaik wrote:@topguy You are right, I don't use -li2c to build on the raspi, I should precise it....

I tried all the compiler I had with the toolchain.

On both Rpi and computer I can build with classic gcc but not with the toolchain.
When you say "classic gcc" I'm assuming you mean "native gcc", the version that comes intstalled in Raspbian or your Linux computer.
You haven't told us where this Cross Toolchain comes from.
I'm thinking that the toolchain doesn't include the i2c-tools, so maybe I need to download it separately and link it when compiling with a -I$(I2C_HEADERS_DIRECTORY) don't you think?
I'm not sure anymore to be honest. I know that most crosscompiling guides I've read for RPi include a step to copy all include/lib directories from a Raspbian image and use them during compiling/linking with the "--sysroot" option. Is this (or something similar) part of your setup.

jahboater
Posts: 5944
Joined: Wed Feb 04, 2015 6:38 pm
Location: West Dorset

Re: Cross-compiling libi2c-dev issue

Sun May 21, 2017 8:25 am

arkaik wrote: I don't have x server installed on my system, I'm using raspberry pi zero and my only access to it is through ssh ;)
and thats a problem because? :D

How about getting a Pi3 with full Raspbian and cross compile on that? If you don't have physical monitor spare, just use the included VNC to display the desktop on your PC.

For the Zero:
Many people use and love such an environment for developing, no need for an X GUI really, though I am guessing its not what you are used to.
The common editors that run in an ssh terminal are nano (easy to use, fast, syntax highlighting), vi, vim (fast, powerful, syntax highlighting, hard to learn), emacs (powerful, large and heavyweight, syntax highlighting - an IDE really). Astonishingly emacs actually works fine on a Zero and looks nice though its not fast. vim and emacs must be installed with "sudo apt install". Nano and the old vi come pre-installed in Raspbian Lite.

Another idea, write the bulk of the code on your PC with a familiar editor, then copy the files to the Pi Zero with scp. On the Pi just make the odd small changes needed with one of the above editors. Copy them back when done.

arkaik
Posts: 23
Joined: Mon Mar 20, 2017 3:42 pm

Re: Cross-compiling libi2c-dev issue

Mon May 22, 2017 8:14 am

@topguy
When you say "classic gcc" I'm assuming you mean "native gcc"
Yes I meant native gcc, I'm not native english speaker, sorry for the mistakes I can do ;)

My cross toolchain comes from the official raspberry pi github repository.

I think the problem is what I was saying, I tried with another library (wiringPi) and after compiling this one on the raspi and linked it from the Makefile with -I -L and -l, the cross compilation was ok. Executing on Rpi too.

The point with i2c-tools, is that the library is installed on the system but there is nothing available for cross-compile it, I think the library as to be included with the executable as a static library as it's not a native linux library.
I may be wrong but I think it's something like that ^^

@jahboater
and thats a problem because? :D
This is not a problem at all ^^ What I meant is that I don't like to develop with command line, I know many people are used to that and it's not a problem for them.
How about getting a Pi3 with full Raspbian and cross compile on that? If you don't have physical monitor spare, just use the included VNC to display the desktop on your PC.
Trust me if I develop on pi zero it's for good reasons (mainly because of size issues), a Rpi 3 would not fit in my application, moreover I don't know if you already tried a vnc connection to a Rpi but this is the worse experience I ever had with it ^^ rarely seen something slower...
Many people use and love such an environment for developing, no need for an X GUI really, though I am guessing its not what you are used to.
I don't particularly love no GUI environment, but the OS is faster without GUI. And I'm well used to cross-compiling, I always used the Rpi like this because I don't really like to need a screen + keyboard + hdmi wire + mouse + .... So the Rpi is wired to my router and that's all.
About editors, I'm also used to develop with nano or vim but it's okay for small programs only. This application will be a big mess if I don't take some time to have a proper development environment.

Thanks to both of you.

ulkona
Posts: 1
Joined: Wed Apr 05, 2017 8:48 am

Re: Cross-compiling libi2c-dev issue

Fri Sep 15, 2017 1:28 pm

The libi2c-dev is really one header file that is different (!) in kernel and userland.

Code: Select all

cd [your sysroot]
sudo apt-get install libi2c-dev
mv usr/include/linux/i2c-dev.h to usr/include/linux/i2c-dev.h.kernel
cp /usr/include/linux/i2c-de.h to usr/include/linux/i2c-dev.h
And do full rebuild

Return to “C/C++”