Cross compiling a application using Shared libraries - c

I am having a existing application which compiles and executes in GCC.
I am cross compiling the same application, I am able to cross compile and generate the shared libraries. But when I try to use the shared libraries for linking to a application it is giving the following errors
arm-poky-linux-gnueabi-gcc MSO_Version.o MSO_Connect.o MSO_errors.o -o bin/MSO_Version_shared -Wall -g -Os -fPIC -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a7 --sysroot=/home/fsl-release-bsp/build_image/tmp/sysroots/imx6ulevk -I../include -I../wsq -I/home/fsl-release-bsp/build_image/tmp/sysroots/imx6ulevk/usr/include/ -L/opt/poky/1.8/sysroots/cortexa7hf-vfp-neon-poky-linux-gnueabi/usr/lib -L../lib -L/opt/poky/1.8/sysroots/i686-pokysdk-linux/lib -L/opt/poky/1.8/sysroots/i686-pokysdk-linux/usr/lib -L/home/fsl-release-bsp/build_image/tmp/sysroots/imx6ulevk/usr/lib -lMSO -lMSOComm -lusb
/opt/poky/1.8/sysroots/i686-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.9.2/ld: skipping incompatible /opt/poky/1.8/sysroots/i686-pokysdk-linux/lib/libgcc_s.so.1 when searching for libgcc_s.so.1
/opt/poky/1.8/sysroots/i686-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.9.2/ld: cannot find /lib/libc.so.6
/opt/poky/1.8/sysroots/i686-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.9.2/ld: cannot find /usr/lib/libc_nonshared.a
/opt/poky/1.8/sysroots/i686-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.9.2/ld: cannot find /lib/ld-linux-armhf.so.3
collect2: error: ld returned 1 exit status
make[1]: *** [MSO_Version_shared] Error 1
make[1]: Leaving directory `/home/linux/ESYS-IMP-LINUXAPP-SUF-24092012-V0.01/Internal Release/ESYS-IMP-LinuxApp-SUF-LIB-SRS-V0.01/samples'
make: *** [samples] Error 2
If I compile with static libraries executables are getting generated. Below is my makefile
export CROSS_COMPILE
CC = $(CROSS_COMPILE)gcc
ifeq ($(DEBUG),yes)
CFLAGS = -Wall -g -Os -fPIC -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a7 --sysroot=/home/fsl-release-bsp/build_image/tmp/sysroots/imx6ulevk
else
CFLAGS = -Wall -Os -fPIC -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a7 --sysroot=/home/fsl-release-bsp/build_image/tmp/sysroots/imx6ulevk
endif
LIB_USB = -lusb
LIB_SDL = -lSDL -lSDL_ttf
LIBPATH += -L/opt/poky/1.8/sysroots/cortexa7hf-vfp-neon-poky-linux-gnueabi/usr/lib
LIBPATH += -L../lib
LIBPATH += -L/opt/poky/1.8/sysroots/i686-pokysdk-linux/lib
LIBPATH += -L/opt/poky/1.8/sysroots/i686-pokysdk-linux/usr/lib
LIBPATH += -L/home/fsl-release-bsp/build_image/tmp/sysroots/imx6ulevk/usr/lib
LIB_STATIC_SAGEM = ../lib/libMSO.a ../lib/libMSOComm.a
LIB_SAGEM = -lMSO -lMSOComm
SRCINCLUDE += -I../include -I../wsq
SRCINCLUDE += -I/home/fsl-release-bsp/build_image/tmp/sysroots/imx6ulevk/usr/include/
EXEC_PATH = bin
EXEC_STATIC = MSO_Version #MSO_TestBio MSO_TestThread
EXEC_SHARED = MSO_Version_shared #MSO_TestBio_shared
MSO_Version_SRC = MSO_Version.c MSO_Connect.c MSO_errors.c
MSO_Version_OBJ = $(MSO_Version_SRC:.c=.o)
.PHONY: all
all: $(EXEC_STATIC) $(EXEC_SHARED)
%.o: %.c
$(CC) -c $(CFLAGS) $(SRCINCLUDE) $< -o $#
.PHONY: MSO_Version MSO_Version_shared
MSO_Version: $(MSO_Version_OBJ)
$(CC) $(MSO_Version_OBJ) -o $(EXEC_PATH)/MSO_Version $(CFLAGS) $(SRCINCLUDE) $(LIB_STATIC_SAGEM) $(LIB_USB)
MSO_Version_shared: $(MSO_Version_OBJ)
$(CC) $(MSO_Version_OBJ) -o $(EXEC_PATH)/MSO_Version_shared $(CFLAGS) $(SRCINCLUDE) $(LIBPATH) $(LIB_SAGEM) $(LIB_USB)
You can see I am generating two executables one with the static library and other with shared library.
I am using poky 1.8 and kernel is 2.6.38. Using NXP IMX6ULEVK board.
Can anyone tell me where I am going wrong

You specify architecture as armv7-a:
-march=armv7-a
but link towards i686 libraries:
-L/opt/poky/1.8/sysroots/i686-pokysdk-linux/lib -L/opt/poky/1.8/sysroots/i686-pokysdk-linux/usr/lib

Related

Trouble with arm-none-eabi-gcc during compilation on Mac OS (M1)

Context:
I'm using a Mac OS Monterey (12.5.1) with M1 pro processor
The last version of Xcode is installed
I'm trying to build an image to used it inside a raspberry pi and trying to interact with a Piface LED screen.
With the PI OS, I load my own kernel (.img) in the config.txt
I'm trying to compile c with (gcc) arm-none-eabi by Makefile :
MAINFILE = a2p1
OBJS = lib/piface.o
OBJS += lib/rpi-gpio.o lib/rpi-armtimer.o lib/rpi-interrupts.o lib/rpi-systimer.o
OBJS += lib/startup.o lib/syscalls.o
OBJS += $(MAINFILE).o
ELF = $(MAINFILE).elf
MAIN = $(MAINFILE).img
CROSS = arm-none-eabi-
CC = $(CROSS)gcc
AS = $(CROSS)as
SIZE = $(CROSS)size
OCOPY = $(CROSS)objcopy
CFLAGS = -march=armv8-a+crc -mtune=cortex-a53 -mfpu=vfp -mfloat-abi=soft -ffunction-sections -fdata-sections -fno-common -g -std=gnu99 -Wall -Wextra -Os -Ilib -DRPI3=1 -DIOBPLUS=1
LFLAGS = -static -nostartfiles -lc -lgcc -specs=nano.specs -Wl,--gc-sections -lm
LSCRIPT = lib/rpi3.ld
LDFLAGS += -u _printf_float
.PHONY: all clean run
all: $(MAIN)
%.o: %.c
$(CC) $(CFLAGS) -c -o $# $^
$(ELF): $(OBJS)
$(CC) -T $(LSCRIPT) $(CFLAGS) $(LFLAGS) $(LDFLAGS) -o $# $^
$(SIZE) $#
$(MAIN): $(ELF)
$(OCOPY) $< -O binary $#
clean:
rm -f $(MAIN) $(ELF) $(OBJS)
run: $(MAIN)
I've installed arm-none-eabi-gcc using 'port' this way :
sudo port install arm-none-eabi-gcc
Here is my errors:
can not find -lc_nano : No such file or directory
/opt/local/lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld
: can not find -lg_nano : No such file or directory
/opt/local/lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld
: can not find -lc_nano : No such file or directory
How the error occur :
When the compiler is trying to run this (I suppose this is the linking step):
arm-none-eabi-gcc -T lib/rpi3.ld -march=armv8-a+crc -mtune=cortex-a53
-mfpu=vfp -mfloat-abi=soft -ffunction-sections -fdata-sections -fno-common -g -std=gnu99 -Wall -Wextra -Os -Ilib -DRPI3=1 -DIOBPLUS=1 -static -nostartfiles -lc -lgcc -specs=nano.specs -Wl,--gc-sections -lm -u _printf_float -o a2p1.elf lib/piface.o lib/rpi-gpio.o lib/rpi-armtimer.o lib/rpi-interrupts.o lib/rpi-systimer.o
lib/startup.o lib/syscalls.o a2p1.o
I got the same issue with the port, remove it and use instead :
brew install --cask gcc-arm-embedded
( https://formulae.brew.sh/cask/gcc-arm-embedded )

arm-none-gcc-ld error : cannot find the object file even though it exists with the proper path

So this is a snippet from my makefile to build my target:
#include header files directory
vpath %.h = include
vpath %.o = obj
#create a list of *.c from the source directory
SRC = $(wildcard src/*.c)
OBJ = $(SRC:src/%.c=%.o)
main.elf: $(OBJ)
$(CC) $(LDFLAGX) $(addprefix obj/,$(OBJ)) -o $#
%.o : %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $^ -o obj/$#
my project directory is as follows:
srcdir
+---include
+---obj
\---src
Here's the output I'm getting:
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/RCC.c -o obj/RCC.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/SPI.c -o obj/SPI.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/main.c -o obj/main.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/startup.c -o obj/startup.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/timer.c -o obj/timer.o
arm-none-eabi-gcc -Iinclude -mcpu=cortex-m3 -mthumb -std=gnu11 -O0 -g -Wall -c src/usart.c -o obj/usart.o
arm-none-eabi-gcc -Xlinker -T -Xlinker lscript.ld -Xlinker -nostdlib -Xlinker -Map=main.map obj/RCC.o obj/SPI.o obj/main.o obj/startup.o obj/timer.o obj/usart.o -o main.elf
c:/program files (x86)/gnu arm embedded toolchain/9 2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/bin/ld.exe: cannot find startup.o
collect2.exe: error: ld returned 1 exit status
make.exe": *** [main.elf] Error 1
So the startup.o exists in obj/ folder and the path has also been specified in the recipe so What is going wrong here?
I have been struggling to create my own makefile due to tons of such errors and even after trying out numerous tutorials and examples which may solve a problem, another new one pops up every now and then, is there any more convenient way to build such projects that does not cause me so much trouble?

GNU make doesn't include headerfile

I have been searching for 6 hours and I can't seem to find the issue with this GNU make file, everytime I try to compile by main.o by the order
make main.o
it gives me this error:
arm-none-eabi-gcc -c main.c -mcpu=cortex-m4 -mthumb --
specs=nosys.specs -Wall -Werror -g -O0 -std=c99 -o main.o
main.c:23:22: fatal error: platform.h: No such file or directory
#include "platform.h"
^
compilation terminated.
Makefile:52: recipe for target 'main.o' failed
make: *** [main.o] Error 1
makefile:
include sources.mk
# Platform Overrides
PLATFORM = MSP432
# Architectures Specific Flags
LINKER_FILE = msp432p401r.lds
CPU = cortex-m4
ARCH = thumb
SPECS = nosys.specs
# Compiler Flags and Defines
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
TARGET = c1m1
LDFLAGS = -Wl,-Map=$(TARGET).map -T $(LINKER_FILE)
CFLAGS = -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS) -Wall -Werror -g -O0 -std=c99
CPPFLAGs =
.PHONY: all
all: $(TARGET).out
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET).out $(TARGET).map
%.o : %.c
$(CC) -c $< $(CFLAGS) -o $#
OBJS = $(SOURCES:.c=.o)
$(TARGET).out: $(OBJS)
$(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) -o $#
sources.mk:
# Add your Source files to this variable
SOURCES =./main.c \
./memory.c \
./startup_msp432p401r_gcc.c \
./system_msp432p401r.c \
./interrupts_msp432p401r_gcc.c
# Add your include paths to this variable
INCLUDES =-I./include/CMSIS \
-I./include/common \
-I./include/msp432
here's my code on github:
github repository
You have not used the INCLUDES macro in makefile's CFLAGS macro. Consequently the arm-none-eabi-gcc ... command line does not specify the include paths to the compiler (or strictly the pre-processor).
CFLAGS = -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS) $(INCLUDES) -Wall -Werror -g -O0 -std=c99
^^^^^^^^^^^

Add OpenCL CL/cl.h path to existing Make file

I am trying to successful execute a make file that comes from a new crytpo-coin called Sia Coin. It can be found here Sia Coin GPU Miner. It's relatively new and so some stuff requires more manual installation. I was getting the following error on Ubuntu 16.04 when using the make file. CL/cl.h was missing, and I was able to install and it is located at /usr/include/nvidia-361/CL/cl.h. However, when I ran the make file I still get errors so I think I need to include this path someone in the Make file, the problem is I am not familiar with make files at all. Below is the Make file I need to edit to include the path for compilation:
ifeq ($(shell uname -s),Darwin)
CC ?= clang
LDLIBS += -lcurl -framework OpenCL
else
CC ?= gcc
LDLIBS += -lOpenCL -lcurl
endif
CFLAGS += -c -std=c11 -Wall -pedantic -O2
TARGET = sia-gpu-miner
SOURCES = sia-gpu-miner.c network.c
OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
all: $(TARGET)
%.o: %.c
$(CC) $(CFLAGS) -o $# $<
$(TARGET): $(OBJECTS)
$(CC) -o $# $^ $(LDLIBS)
clean:
rm -f $(TARGET) $(OBJECTS)
.PHONY: all clean
Any help toward solving this problem is greatly appreciated.
Edit:
A new message I am getting now adding
CFLAGS += -c -std=c11 -Wall -pedantic -O2 -I /usr/include/nvidia-361
is now:
-lOpenCL -lcurl /usr/bin/ld: cannot find -lOpenCL collect2: error: ld returned 1 exit status
Two files did compile:
sia-gpu-miner.c
network.c
But I don't know enough to know why the -lOpenCL is not found. No ld directory exists in that directory location in the error if that helps.
Try changing
CFLAGS += -c -std=c11 -Wall -pedantic -O2
to
CFLAGS += -c -std=c11 -Wall -pedantic -O2 -I /usr/include/nvidia-361

make: force recompilation of same objects with different compiler

I want my makefile to build the same binary 2 times, first compiling with gcc and then with mingw. So, I've written this, but it does not work:
OBJ_DIR = obj
SRC_DIR = src
BIN_DIR = bin
INCLUDE = -I./$(SRC_DIR)
LIBS =
_SRCS = print_current_dir.c test_main.c
_OBJS = print_current_dir.o test_main.o
SRCS = $(addprefix $(SRC_DIR)/,$(_SRCS))
OBJS = $(addprefix $(OBJ_DIR)/,$(_OBJS))
all: $(BIN_DIR)/pps-linux $(BIN_DIR)/pps-win32
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) -c -o $# $< $(CFLAGS)
$(BIN_DIR)/pps-linux: CC = cc
$(BIN_DIR)/pps-linux: CFLAGS = -g -Wall $(INCLUDE) $(LIBS)
$(BIN_DIR)/pps-linux: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $#
$(BIN_DIR)/pps-win32: CC = i586-mingw32msvc-cc
$(BIN_DIR)/pps-win32: CFLAGS = -g -Wall $(INCLUDE) $(LIBS)
$(BIN_DIR)/pps-win32: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $#
Once it compiles the objects file in $(OBJS) with gcc for the target pps-linux, it tries to build pps-win32 with the very same objects file, obviously failing, and despite the fact that I redefined CC and CFLAGS for the target pps-win32.
Here is the output:
$ make
cc -c -o obj/print_current_dir.o src/print_current_dir.c -g -Wall -I./src
cc -c -o obj/test_main.o src/test_main.c -g -Wall -I./src
cc -g -Wall -I./src obj/print_current_dir.o obj/test_main.o -o bin/pps-linux
i586-mingw32msvc-cc -g -Wall -I./src obj/print_current_dir.o obj/test_main.o -o bin/pps-win32
obj/print_current_dir.o: In function `print_dir':
/home/matteo/Desktop/pps/src/print_dir.c:23: undefined reference to `get_current_dir_name'
/home/matteo/Desktop/pps/src/print_dir.c:25: undefined reference to `puts'
/home/matteo/Desktop/pps/src/print_dir.c:27: undefined reference to `free'
/usr/lib/gcc/i586-mingw32msvc/4.4.4/../../../../i586-mingw32msvc/lib/libmingw32.a(main.o):(.text+0x85): undefined reference to `_WinMain#16'
collect2: ld returned 1 exit status
make: *** [bin/pps-win32] Error 1
How do I force the recompilation of the objects file just compiled with a different compiler?
Thank you.
By making the object files compiler-dependent too, rather than trying to overwrite the same .o file in place with different contents, eg.
LINUX_OBJS = $(addprefix $(LINUX_OBJ_DIR)/,$(_OBJS))
...
$(BIN_DIR)/pps-linux: $(LINUX_OBJS)
NB. you may be able to do it more tidily by just using a target-dependent definition of OBJ_DIR, ie,
$(BIN_DIR)/pps-linux: OBJ_DIR = linux-obj
but I'd have to try it to be sure.
I would suggest using separate OBJ_DIR and BIN_DIR directories to accomplish this, with the names being constructed in part from the compiler vendor:
OBJ_DIR = obj-$(CC)
BIN_DIR = bin-$(CC)
I use a similar approach that has completely separate build directories, and installation directories, with the names constructed from:
compiler vendor
compiler version
architecture
libc version (if linux)
which results in directories named (for example):
gcc_3.4.6-x86-libc_2.3.4
forte_5.10-x64
gcc_4.2.3-x86

Resources