I followed this guide to build a cross compiler for Raspberry Pi ARMv7. It works fine (compiles ok hello world) but the problem is I can't use Raspberry Pi libraries such as wiringpi, sqlite etc.
This is my Makefile.
CC = /opt/cross-pi-gcc/bin/arm-linux-gnueabihf-g++
QUOTE := "
CFLAGS = -g -lwiringPi -pthread -lpthread
PROGRAM = lora
OBJDIR = obj
CPP_SRCS += \
src/main.cpp \
src/radio/sx1276/sx1276.cpp \
src/radio/radio.cpp \
OBJ_FILES += \
$(OBJDIR)/main.o \
$(OBJDIR)/sx1276.o \
$(OBJDIR)/radio.o \
all: make_dir $(OBJ_FILES)
$(CC) $(OBJ_FILES) $(CFLAGS) -o $(PROGRAM)
make_dir:
mkdir -p $(OBJDIR)
$(OBJDIR)/main.o: src/main.cpp
$(CC) $(CFLAGS) -c -o $# $<
$(OBJDIR)/service.o: src/service/service.cpp
$(CC) $(CFLAGS) -c -o $# $<
$(OBJDIR)/sx1276.o: src/radio/sx1276/sx1276.cpp
$(CC) $(CFLAGS) -c -o $# $<
$(OBJDIR)/radio.o: src/radio/radio.cpp
$(CC) $(CFLAGS) -c -o $# $<
clean:
rm $(PROGRAM)
rm -rf $(OBJDIR)
The error I'm getting:
/opt/cross-pi-gcc/lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lwiringPi
I copied some libraries from my Pi into a folder on my home dir with this command.
rsync -vR --progress -rl --delete-after --safe-links pi#192.168.1.PI:/{lib,usr,opt/vc/lib} $HOME/raspberrypi/rootfs
Which I found it here.
But I'm not sure how to link them. Did I overlook something?
Note: The piece of code I'm trying to compile was compiling fine on Windows's cross-compiler.
I'm trying to setup a tool-chain on my Linux desktop. I'm using Manjaro.
You have to tell the linker where to look for the libraries.
You can add the flag -L$HOME/raspberrypi/rootfs/usr/lib, or wherever libwiringPi.so is located.
You have to point the compiler to the right headers as well. For that you use the -I flag. E.g. -I$HOME/raspberrypi/rootfs/usr/include. This goes in the CFLAGS of the targets that include wiringPi.h.
Also, -lwiringPi -pthread -lpthread don't belong in the CFLAGS, they are linker flags. You only need them in the target that builds PROGRAM. You could add a separate variable LDFLAGS, for example.
Related
I need to run C project written in Linux on Windows. The project contains the following: main.c, makefile, (.c) and (.h) files under folder (libs), and it includes "GL/glut.h" (openGL).
I have tried run it under Visual Studio, but didn't work out. Now, I am working with NetBeans under MinGW compiler. I did all steps mentioned to make NetBeans use MinGW compiler, but still the makefile doesn't compile, and I can't understand the error behind.
Any help is very appreciated. Thank you.
Find below the makefile:
EXECUTABLE = main
CC = g++
CWD=$(shell pwd)
INCLUDES =
CFLAGS= -O3 -funroll-loops -fomit-frame-pointer #-static -Wall
LIBFLAGS = -L./ -lGL -lGLU -lglut #-L/usr/X11R6/lib # -lXxf86vm
SOURCE_FILES = $(shell find -name \*.c)
INTERM_DIR=obj
all: $(EXECUTABLE)
clean:
$(RM) -rf $(INTERM_DIR) $(EXECUTABLE)
.PHONY: clean
$(INTERM_DIR) :
mkdir -p $#
$(INTERM_DIR)/%.dep: %.c
mkdir -p `dirname $#`
echo -n `dirname $#`/ > $#
$(CC) $(CFLAGS_COMMON) $< -MM | sed -r -e 's,^(.*)\.o\s*\:,\1.o $# :,g' >> $#
ifneq ($(MAKECMDGOALS),clean)
-include $(SOURCE_FILES:./%.c=./$(INTERM_DIR)/%.dep)
endif
$(INTERM_DIR)/%.o: ./%.c
mkdir -p `dirname $#`
$(CC) $(CFLAGS) -c $< -o $#
$(EXECUTABLE): $(SOURCE_FILES:./%.c=./$(INTERM_DIR)/%.o)
mkdir -p `dirname $#`
$(CC) $^ $(LIBFLAGS) -o $#
The error I got:
C:\cygwin64\bin\bash.exe -c 'C:/Program Files/mingw-w64/x86_64-7.1.0-posix-seh-rt_v5-rev0/mingw64/bin/gcc.exe' -MM
gcc.exe: fatal error: no input files
compilation terminated.
COMPILE FILE FAILED (exit value 1, total time: 306ms)
I believe when you install Visual Studio it gives the option to run with Linux. Another way you might be able to get around this is to use a VM with a Linux OS.
I'm trying to compile a project that has multiple *.c files and *.h file when I type the following command:
$gcc -c -I ../hdr main.c gestic.c menu.c
the hdr folder is where the *.h files are located, the .o files are created but when I try to link them using the command:
$gcc -o main.o gestic.o menu.o
I see errors
gestic.c:(.text+0x..): undefined reference to functions that are declared in *.h files
$gcc -Wall -c -I../hdr -o main.o main.c
$gcc -Wall -c -I../hdr -o menu.o menu.c
$gcc -Wall -c -I../hdr -o gestic.o gestic.c
$gcc -Wall -o myprogram main.o menu.o gestic.o
Using a Makefile is very common for this task
example (untested) Makefile:
CC=gcc
CFLAGS=-Wall -I../hdr
all: myprogram
myprogram: main.o menu.o gestic.o
$(CC) -o $# $^
gestic.o: gestic.c
$(CC) $(CFLAGS) -c -o $# $<
main.o: main.c
$(CC) $(CFLAGS) -c -o $# $<
menu.o: menu.c
$(CC) $(CFLAGS) -c -o $# $<
Try:
$ gcc main.o gestic.o menu.o
-o filename: Place output in filename
Firstly header files are not included, secondly you might use the function that doesn't contain the definition.
The message undefined reference to 'function_name' implies that of all the object files you're giving to the linker, none of them has a definition for function_name. That means that either
You're not linking with *.o
*.c (as compiled) does not contain a definition for function_name -- by 'as compiled' I mean with all of the various preprocessor options you use on it.
here -Iinclude/
try,
gcc -c file.c -I<include_dir>
If you compile more files better to have makefile to create the objects of those files, link those objects along with header.
Sample makefile,
CC = gcc
CFLAGS = -Wall
INCLUDE = sample.h
OBJ = samople1.o sample2.o
%.o: %.c $(INCLUDE)
$(CC) $(CFLAGS) -c -o $# $<
go: $(OBJ)
gcc $(CFLAGS) -o $# $^
FC= ifort
FCFLAGS=-O2 -r8 -openmp -mcmodel=large -extend-source -shared-intel -I$(HOME)/usr/include
LDFLAGS=-L$(HOME)/usr/lib -lfftw3 -lm
TARGET=Project
Project: a.o b.o c.o d.o
#
all : $(TARGET)
%: %.o
$(FC) $(FCFLAGS) -o $# $^ $(LDFLAGS)
%.o: %.f90
$(FC) $(FCFLAGS) -c $<
all : $(TARGET)
clean :
rm *.o
when I studied makefile, there is no information for
#
all : $(TARGET)
and function of % and $^. I wanna check about these things. Thanks for your help.
all is a target (repeated twice in that makefile for no reason). So is clean. Targets are how make works. See Rule Example.
$^ is one of the Automatic Variables available for use in target recipes.
% is a wildcard used in some make functions and in Pattern Rules.
So my task is simple, I have created the makefile (New with makefiles) and I want to keep my .o files in a different folder to have a cleaner directory and allow the usage of .o files by others.
I searched and found many solution pointing to using -o $< $#
However, it is giving me that g++: cannot specify -o with -c or -S with multiple files
This is what I want to do:
$(OBJECT_PATH)/file1.o: $(SOURCE_PATH)/file2.cpp $(SOURCE_PATH)/file1.cpp
$(CC) $(CFLAGS) $(SOURCE_PATH)/file2.cpp $(SOURCE_PATH)/file1.cpp -o $#
file1.cpp has #include "file1.h", so from what I read I should include file1.cpp in the dependencies. However, now I can't export to a different directory.
Is there a solution? Or do I have the concept wrong?
Use make -d or even better remake -x to understand what commands are invoked.
Run also make -p to understand what builtin rules are used.
We cannot help you more, because we have no idea if you redefined CFLAGS.
And C++ compilation should better be done with g++ that is CXX and CXXFLAGS, e.g. with (I am extracting this from my make -p output)
LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
CXX = g++
%.o: %.cc
$(COMPILE.cc) $(OUTPUT_OPTION) $<
I strongly suggest to have CXXFLAGS= -Wall -g at least during the development phase. Learn also to use gdb and valgrind.
You could have the following in your Makefile
CXXFLAGS= -g -Wall
SOURCES=f1.cc f2.cc
SOURCE_PATH=yoursourcedir/
OBJECT_PATH=yourobjectdir/
SRCFILES=$(patsubst %.cc,$(SOURCE_PATH)/%.cc,$(SOURCES))
OBJFILES=$(patsubst %.cc,$(OBJECT_PATH)/%.o,$(SOURCES))
PROGFILE=$(OBJECT_PATH)
.PHONY: all clean
all: $(PROGFILE)
$(PROGFILE): $(OBJFILES)
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $#
$(OBJECT_PATH)/%.o: $(SOURCE_PATH)/%.cc
$(COMPILE.cc) $(OUTPUT_OPTION) $<
clean:
$(RM) $(OBJECT_PATH)/*.o $(PROGFILE)
try
$(OBJECT_PATH)/file1.o: $(SOURCE_PATH)/file2.cpp $(SOURCE_PATH)/file1.cpp
$(CC) $(CFLAGS) $^ -c $#
and check that CFLAGS doesn't include -o -c or -s flags
also read about implicit rules. it might help you to orginzie your makefile
I am programming for a big project, so I cooperate with others.
To make the directory easily managed, my directory is like below:
project:
--include (header files from others supplied for me)
--lib (libraries from others supplied for me)
--L3_CVS (this folder include all my files)
-- Makefile
-- sourceFile (all my source files here)
-- include_private(all header files used only by myself)
-- appl (all my C files here)
My Makefile is below:
####################################################
CROSS_COMPILE=/home/powerpc-wrs-linux-gnu/x86-linux2/powerpc-wrs-linux-gnu-ppc_e500v2-glibc_cgl-
EXTRA_CFLAGS += -g
EXTRA_LDFLAGS +=
LIBSB =-Wl,--start-group -ldiag -ldiag_esw -lacl -ldiagcint -lcint -lsal_appl -lsal_appl_editline -lsal_appl_plat\
-lbcm -lbcm_esw -lbcm_common -lfirebolt -ltitan -ltrident -lhumv -lbradley -lherc -ldraco -lscorpion\
-ltriumph -ltrx -ltriumph2 -lenduro -lkatana -lflexctr -lptp -lsoc_esw -lsoc -lsoc_phy -lsoc_mcm\
-lsoccommon -lsoc_shared -lshared -lsal_core -lsal_core_plat -lcustomer -lsoc_nemo -lsoc_clsbuilder\
-lsoc_sal \
-lbcm_compat -lbcm_rpc -lcpudb -ltrx -lstktask -llubde -ldrivers -ldiscover -lcputrans \
-lrcu -lpthread -lrt -lm -Wl,--end-group
LIBS = -ldiag -lrcu
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
AR = $(CROSS_COMPILE)ar
STRIP = $(CROSS_COMPILE)strip
SRC_PATH := ./SourceFile/appl
HEAD_PATH := ./SourceFile/include-private
INC_DIR = ../include
LIB_PATH = ../lib
APP_NAME = L3appl
SRCS := $(wildcard $(SRC_PATH)/*.c)
export $(SRCS)
OBJS:= $(patsubst %.c,%.o,$(SRCS))
%.d: %.c
#set -e; rm -f $#; \
$(CC) -MM $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
sinclude $(SRCS:.c=.d)
INCLUDES = $(wildcard $(HEAD_PATH)/*.h)
$(APP_NAME):$(OBJS)
$(CC) -c -I$(INC_DIR) $(SRCS)
$(CC) -o $(APP_NAME) $(OBJS) -L$(LIB_PATH) $(LIBSB) -lpthread -lrt -lm
.PHONY:clean
clean:
rm -f $(OBJS) $(APP_NAME)
#################################################
My problem is that when I run make in terminal, it always show : ***No such file or directory
compilation terminated. which seems the .h files in ./SourceFile/include-private do not be included.
But, in fact, I have use "INCLUDES = $(wildcard $(HEAD_PATH)/*.h)" include these .h files.
I don't know where is wrong!
this is my first time to write makefile. So if there are mistakes in my makefile, I would appreciate that you would point them out !
thank you for your help very much!!!!!!!
You should have something like
CFLAGS = -Wall $(OPTIMFLAGS) $(INCLUDEFLAGS)
INCLUDEFLAGS = -I $(INC_DIR) -I $(HEAD_PATH)
OPTIMFLAGS = -g -O
You can use remake to debug your Makefile.
You can try to change $(CC) -c -I$(INC_DIR) $(SRCS) to $(CC) -c -I$(INC_DIR) -include $(INCLUDES) $(SRCS)
or $(CC) -c -I$(INC_DIR) $(SRCS) to $(CC) -c -I$(INC_DIR) -I$(INCLUDES) $(SRCS)
where INCLUDES is ./SourceFile/include-private (only the directory, no .h files)
Edit: Usually you don't have to explicitly include the .h files, but that's what the first change do. The second change does not add the .h files explicitely but provide the compiler another include directory where it could search for necessary .h files.
Refer to GCC man file for more info.
Regards