I have a library with few source code files (.c) and header files and the output is shared library (.so).
Currently, i am using Makefile for generating .so
C = gcc
FLAGS = # -std=gnu99 -Iinclude
CFLAGS = -fPIC -g #-pedantic -Wall -Wextra -ggdb3
LDFLAGS = -shared
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
TARGET = libesys.so
SOURCES = $(wildcard *.c)
HEADERS = $(wildcard *.h)
OBJECTS = $(SOURCES:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(FLAGS) $(CFLAGS) $(LDFLAGS) $(DEBUGFLAGS) -o $(TARGET) $(OBJECTS)
clean:
rm *.o libesys.so
I want to create a recipe in my meta layer to perform the above operation and generate .so when I do bitbake core-image-minimal. Can you please provide an example recipe which does similar operation.
First, have a look at simple recipe for a single source file from the dev-manual and try to first get a simple recipe building. You are correct in placing this recipe in your own meta layer.
Also have a look at this section that covers recipes with a Makefile.
Here is something to get you started
DESCRIPTION = "My test recipe"
LICENSE = "CLOSED"
PR = "r1"
S = "${WORKDIR}
FILES_${PN} = "libesys.so"
# Better to use a git repo for large projects
SRC_URI="file://xxxxxx \
file://yyyyyy \
"
do_install(){
oe_runmake install DESTDIR=${D} INCLUDEDIR=${includedir}
install -d ${D}${libdir}
install -m 0644 libesys.so ${D}${libdir}
}
BBCLASSEXTEND = "native"
You will also need to modify the core-image-minimal recipe to add a depends to your recipe so that it pulls in your lib.
DEPENDS+="your_recipe_name_here"
You can add this directly into the recipe itself, or add it via a .bbappends file that can reside in your layer.
Related
When trying to compile my c code I keep getting basic.c:5:10: fatal error: 'fftw3.h' file not found. I am compiling my c code using MacOS terminal and have Xcode installed.
I'm trying to write some c code which uses the fftw-3 library. fftw-3 has been installed using sudo port install fftw-3 and I have entered port contents fftw-3 which returned:
/opt/local/include/dfftw.h
/opt/local/include/dfftw_threads.h
/opt/local/include/drfftw.h
/opt/local/include/drfftw_threads.h
/opt/local/include/fftw_f77.i
/opt/local/lib/libdfftw.2.dylib
/opt/local/lib/libdfftw.a
/opt/local/lib/libdfftw.dylib
/opt/local/lib/libdfftw_threads.2.dylib
/opt/local/lib/libdfftw_threads.a
/opt/local/lib/libdfftw_threads.dylib
/opt/local/lib/libdrfftw.2.dylib
/opt/local/lib/libdrfftw.a
/opt/local/lib/libdrfftw.dylib
/opt/local/lib/libdrfftw_threads.2.dylib
/opt/local/lib/libdrfftw_threads.a
/opt/local/lib/libdrfftw_threads.dylib
/opt/local/share/info/fftw.info
/opt/local/share/info/fftw.info-1
/opt/local/share/info/fftw.info-2
/opt/local/share/info/fftw.info-3
/opt/local/share/info/fftw.info-4
/opt/local/share/info/fftw.info-5
I have been using a makefile and am trying to work out what needs including in it. At the moment I have:
# define the name of your source file(s)
SRCS = basic.c
# define the name of the object files(s) - we can do this automatically
OBJS = $(SRCS:.c=.o)
# tell MAKE which compiler to use
CCOMP = gcc
# flags for the compiler
# don't forget the -O3
CFLAGS = -Wall -O3 -fstrict-aliasing -Iinclude
#CFLAGS = -c -Wall -Iinclude
# flags for the linker. note -lm for the math library
LDFLAGS = -O3 -lm -L/opt/lib -I/opt/lib -L/opt/local/include -I/opt/lib
# the name of your executable file (the target) - here we put it in the top directory
TARGET = basic
# actions
all: $(OBJS)
$(CCOMP) -o $(TARGET) $(OBJS) $(LDFLAGS)
%.o: %.c
$(CCOMP) -c -o $# $< $(CFLAGS)
# delete all objects and target
clean:
rm -f $(OBJS) $(TARGET)
I'm not sure if the #CFLAGS and #LDFLAGS sections are correct? I would appreciate troubleshooting and any advice on what I need to do to get this working. Thanks!
I am trying to run the Paho MQTT example in C on my raspberry pi: https://www.eclipse.org/paho/clients/c/
I tried just downloading the pre-built binaries and linking to lpaho-mqtt3c
I put that library here: /home/pi/mqtt_C_testing/Eclipse-Paho-MQTT-C-1.3.1-Linux/lib
And I added: LD_LIBRARY_PATH=/home/pi/mqtt_C_testing/Eclipse-Paho-MQTT-C-1.3.1-Linux/lib/
My makefile looks like this:
IDIR = /home/pi/mqtt_C_testing/Eclipse-Paho-MQTT-C-1.3.1-Linux/include
LDIR = /home/pi/mqtt_C_testing/Eclipse-Paho-MQTT-C-1.3.1-Linux/lib
CC = gcc
LD = gcc
CFLAGS = -Wall
LIBS = -lpaho-mqtt3c
PROG_NAME = main
# directories in project
BIN = bin
SRC = src
OBJ = obj
INCLUDE = include
INCLUDES = -I./$(INCLUDE)
all : $(PROG_NAME)
$(PROG_NAME) : $(BIN)/$$#
$(BIN)/% : $(OBJ)/%.o
$(CC) $(CFLAGS) $^ -o $# $(LIBS)
$(BIN)/main : $(addprefix $(OBJ)/, \
main.o)
$(OBJ)/main.o : $(addprefix $(INCLUDE)/, \
MQTTProperties.h MQTTReasonCodes.h MQTTSubscribeOpts.h MQTTClient.h \
MQTTClientPersistence.h MQTTAsync.h)
$(OBJ)/%.o : $(SRC)/%.c
$(CC) $(INCLUDES) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -f $(OBJ)/*.o
When I try to build though, gcc cannot find the library:
gcc -Wall obj/main.o -o bin/main -lpaho-mqtt3c
/usr/bin/ld: cannot find -lpaho-mqtt3c
collect2: error: ld returned 1 exit status
make: *** [makefile:26: bin/main] Error 1
My directory structure is like this:
pi#raspberrypi:~/mqtt_C_testing $ ls
bin Eclipse-Paho-MQTT-C-1.3.1-Linux include makefile obj src
And I have main.c (the mqtt example file) in src and I put all the MQTT header files in include.
The library files for mqtt are here: /home/pi/mqtt_C_testing/Eclipse-Paho-MQTT-C-1.3.1-Linux/lib
I'm really not sure if I'm the right track at all here, so any help is appreciated. Thanks!
To get this to compile I did the following:
1) I built the lib by cloning the repo at github.com/eclipse/paho.mqtt.c and ran make then make install. This puts the .so files in /usr/local/lib
2) I put all the .h files in the main folder of my project directory: /home/pi/mqtt_C_testing/
3) I called the paho mqtt synchronous example main.c and have that also in the main directory.
4) I can then simply use: gcc -Wall -o test main.c -lpaho-mqtt3c to build and create an executable called "test"
5) I had success writing a makefile also that is run just with make. I'm a noob to all this, but I found this website (http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/) really helped with creating the makefile. I have not really had success putting the .h files in their own include directory yet though.
CC = gcc
CFLAGS=-I.
DEPS = MQTTAsync.h MQTTClientPersistence.h MQTTProperties.h MQTTClient.h MQTTReasonCodes.h MQTTSub$
OBJ = main.o
LIBS= -lpaho-mqtt3c
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
mainmake: main.o
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
I was making a makefile for cross-compilation between a host and arm based microcontroller. So how do I add a specific library to the recipe of the makefile?
include sources.mk
ifeq ($(PLATFORM),MSP432)
# Platform Overrides
# Architectures Specific Flags
LINKER_FILE = msp432p401r.lds
CPU = cortex-m4
ARCH = thumb
SPECS = nosys.specs
CPP = -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS) -DMSP432
# Compiler Flags and Defines
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
endif
ifeq ($(PLATFORM),HOST)
CC = gcc
CPP= DHOST
endif
TARGET =c1m2
LDFLAGS = -Wl,-Map=$(TARGET).map -T $(LINKER_FILE)
CFLAGS = -Wall -Werror -g -O0 -$(CPP) -I/Desktop/ese-coursera-
course1/assessments/m2/include/common/platform.h
-std=c99
.PHONY: build
build: all
.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 $#
Is this the right way of doing it?(all the tabs and indents for the make file has been given properly, though it is not seen in the code here)
Iam getting this as the error
main.c:23:10: fatal error: platform.h: No such file or directory
#include "platform.h"
^~~~~~~~~~~~
compilation terminated.
Makefile:67: recipe for target 'main.o' failed
make: *** [main.o] Error 1
Also this is my source.mk file
SOURCES = Desktop/ese-coursera-course1/assessments/m2/src
# Add your include paths to this variable
INCLUDES = Desktop/ese-coursera-course1/assessments/m2/include/common/platform.h
Can anyone help me out?
First, try to make sure all paths you give are relative to the Makefile.
I'm surprised your compiler actually does anything since your SOURCES variable is a directory, not a list of .c files. It should probably look like:
SOURCES = src/main.c
this will make OBJS contain src/main.o and the implicit rule will be able to fire.
Next, the INCLUDES variable should reference a directory using the -I flag, like so:
INCLUDES = -Iinclude/common
You should then use it in the CFLAGS definition as follows:
CFLAGS = -Wall -Werror -g -O0 -$(CPP) $(INCLUDES) -std=c99
Other things I noticed:
Your LDFLAGS unconditionally uses the msp432p401r.lds linker script, even in the HOST case. This should probably be added conditionally in the ifeq block like so: LDFLAGS += -T msp432p401r.lds. You should be careful not to overwrite LDFLAGS later with LDFLAGS=, so it is best if you move the definition of CFLAGS and LDFLAGS to the top of the file or always use += to modify these variables.
Following on from that: if your link step uses the linker script, you should add an explicit rule that encodes this dependency: $(TARGET).out: $(LINKER_FILE).
The build -> all -> $(TARGET).out dependency chain is a bit redundant. Why not make build directly depend on $(TARGET).out?
I have this hello-world.c that I'd like to compile to hello-world binary. But hello-world.c depends on a few functions defined in ../helpers/a.c and ../helpers/b.c, and each of those helpers include ../helpers/a.h and ../helpers/b.h respectively.
My current Makefile looks like
CC = #gcc
CFLAGS = -g -Wall -Wextra -Werror
CFLAGS +=
LDLIBS =
LDLIBS +=
OBJS = ../helpers/a.o ../helpers/b.o
SOURCES = hello-world.c
DESTS = hello-world
new: clean all
clean:
#rm -rf *.o */*.o $(DESTS)
all: $(OBJS) $(DESTS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
%: %.c
$(CC) $(CFLAGS) -o $# $<
but it doesn't work, returning make: *** No rule to make target `../helpers/a.o', needed by `all'. Stop.
I understand that Makefile doesn't seem to see the rule for %.o, but I don't see why.
Edit: Makefile debug:
alexandernst#stupidbox:/media/sf_procmon/procmon$ make --debug=b
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
Reading makefiles...
Updating goal targets....
File `new' does not exist.
File `clean' does not exist.
Must remake target `clean'.
Successfully remade target file `clean'.
File `all' does not exist.
File `../helpers/a.o' does not exist.
Must remake target `../helpers/a.o'.
make: *** No rule to make target `../helpers/a.o', needed by `all'. Stop.
This is much easier to get working if you put the Makefile in the parent directory. Then you can write something like this:
CC = gcc
CFLAGS = -g -Wall -Wextra -Werror
CPPFLAGS = -Ihelpers
DESTS = hello-world/hello-world
OBJS = helpers/a.o helpers/b.o hello-world/hello-world.o
# Do not make 'all' depend directly on object files.
all: $(DESTS)
# Clean rules should always be prefixed with '-' to avoid
# errors when files do not exist. Do not use 'rm -r' when
# there shouldn't be directories to delete; do not delete
# wildcards when you can use explicit lists instead.
# Never use '#'.
clean:
-rm -f $(OBJS) $(DESTS)
# An explicit linkage rule is needed for each entry in DESTS.
hello-world/hello-world: hello-world/hello-world.o \
helpers/a.o helpers/b.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $^ $(LIBS)
# The main function of these dependency lists is to prevent
# Make from deleting object files after each build. We also
# take the opportunity to specify header dependencies.
# We rely on the built-in %.o:%.c rule for commands.
hello-world/hello-world.o: hello-world/hello-world.c \
helpers/a.h helpers/b.h
helpers/a.o: helpers/a.c helpers/a.h
helpers/b.o: helpers/b.c helpers/b.h
# This tells Make that 'all' and 'clean' are not files to be created.
.PHONY: all clean
For further exposition of this technique, see the watershed paper 'Recursive Make Considered Harmful' and the associated implementation notes.
I managed to fix my Makefile:
CC = gcc
CFLAGS = -g -Wall -Wextra -Werror
CFLAGS +=
LDLIBS =
LDLIBS +=
OBJS = ../helpers/a.o ../helpers/b.o hello-world.o
SOURCES = hello-world.c
DESTS = hello-world
new: clean all
clean:
#rm -rf *.o */*.o ../helpers/*.o $(DESTS)
all: $(DESTS)
hello-world: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $^ $(LIBS)
One of the problems was that a bad clean rule that I wrote had wiped a.c and b.c and Makefile was acting because of this.
I think to organize my project as follows:
my_project
|--src
|--include
|--test
The core files reside in the directories src and include, whereas the different test applications of the core are within test directory (multiple *.c containing each a main() function). The core should be build as static library which will be linked to all applications).
How to write a basic Makefile to match these requirements? I already googled and found the following website providing a Makefile template for building an executable 1 . How can this Makefile be extended for my needs?
If you think my project organization is bad or you have a better idea, let me know!
Any help is appreciated!
Thanks, Jonas
You haven't said where you want the library to go, so I'll assume it should go into src/ where the objects already go.
src/libcore.a: $(OBJECTS)
$(AR) -cvq $# $^
It looks as if the makefile you have will build test/testfoo.o from test/testfoo.c so I'll assume that that works. And you haven't said where you want the executable tests (e.g. testfoo) to go, so I'll put them in test/.
test/%: test/%.o src/libcore.a
$(CC) -o $# $< -Lsrc -lcore
EDIT:
If you want Make to build all of the tests by default, then you should have this before any other rule in the makefile:
TESTS := $(patsubst %.c,%,$(wildcard test/*.c))
all: $(TESTS)
There is a small project called dotmk which turns the creation of a Makefile very easy.
Here is the link:
https://github.com/swrh/dotmk
You just have to run the install script and create the Makefile like the examples
my Makefile now looks as follows:
SHELL = /bin/sh
CC = gcc
AR = ar
CFLAGS = -std=gnu99 -Iinclude -pedantic -Wall -Wextra -march=native -ggdb3
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
PROFILEFLAGS = -pg
ARFLAGS = -cvq
# core and test common includes
COMMON_INC = include/definitions.h include/debug.h
# core stuff
CORE_LIB = lib/libcore.a
CORE_SRC = $(shell echo src/*.c)
CORE_INC = $(shell echo include/*.h)
CORE_OBJ = $(CORE_SRC:.c=.o)
CORE_PUB_INC =
# test stuff
TEST_SERVER = test/server/server
TEST_SERVER_SRC = $(shell echo test/server/*.c)
TEST_SERVER_INC = $(shell echo test/server/*.h)
TEST_SERVER_OBJ = $(TEST_SERVER_SRC:.c=.o)
TEST_CLIENT = test/client/client
TEST_CLIENT_SRC = $(shell echo test/client/*.c)
TEST_CLIENT_INC = $(shell echo test/client/*.h)
TEST_CLIENT_OBJ = $(TEST_CLIENT_SRC:.c=.o)
all: $(CORE_LIB) $(TEST_SERVER) $(TEST_CLIENT)
core: $(CORE_LIB)
server: core $(TEST_SERVER)
client: core $(TEST_CLIENT)
$(CORE_LIB): $(CORE_OBJ)
$(AR) -cvq $# $^
$(TEST_SERVER): $(TEST_SERVER_OBJ)
$(CC) $(CFLAGS) -o $# $< -Llib -lcore
$(TEST_CLIENT): $(TEST_CLIENT_OBJ)
$(CC) $(CFLAGS) -o $# $< -Llib -lcore
debug: CFLAGS += $(DEBUGFLAGS)
debug: all
profile: CFLAGS += $(PROFILEFLAGS)
profile: all
release: CFLAGS += $(RELEASEFLAGS)
release: all
.PHONY : clean depend
clean:
-rm -f $(CORE_LIB) $(CORE_OBJ)
-rm -f $(TEST_SERVER) $(TEST_SERVER_OBJ)
-rm -f $(TEST_CLIENT) $(TEST_CLIENT_OBJ)
-rm -f gmon.out
depend:
#makedepend -- $(CFLAGS) -- $(CORE_SRC) $(TEST_SERVER_SRC) $(TEST_CLIENT_SRC)
I still have some problems:
- make creates the lib, the server and client test app. If I know modify one of the source files of the core (lib), make builds the lib newly, but not the server and client apps. Do I have a dependency problem?
- make or make all should build by default as DEBUG, whereas release and profile build a release, or profile version respectively.
I wonder, what is wrong in my makefile.
Thanks again!