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)
Related
I have a basic Makefile setup for C OpenGL programming but when running there are 2 files passed to clang that shouldnt exist and i have no idea why. The problem happened after i added glad and glfw to the project.
code:
CC = clang
`CCFLAGS = -lGL -lglfw -std=c++20 -v -Wall -Wextra -Wepedantic -g -lgdi32
LDFLAGS = lib/glad/src/glad.o lib/glfw/src/libglfw3.a -lgdi32 -lm
SRC = $(wildcard src/*.c)
OBJ = $(SRC:.c=.o)
BIN = bin
all: libs build
libs:
cd lib/glad && $(CC) -o src/glad.o -Iinclude -c src/glad.c
cd lib/glfw && cmake . -G 'Unix Makefiles' && make
build: $(OBJ)
$(CC) -o $(BIN)/build $^ $(LDFLAGS)
%.o %.c:
$(CC) -o $# -c $< $(CCFLAGS)
run:
./bin/build.exe
ERROR:
clang: error: no such file or directory: 'all.o'
clang: error: no such file or directory: 'libs'
clang: error: no such file or directory: 'build'
When asking questions please include the command you typed, the command make printed, plus at least the first and last few lines of error messages (properly formatted as code blocks).
I'm assuming that the extra quote character is an error in your cut and paste; please take a moment to review your question after you post it (or even better, using the preview before you post it). You are writing this one time, but tens or hundreds of people will spend their time reading it. Please be considerate enough to make it easy for them.
Your problem is this:
%.o %.c:
$(CC) -o $# -c $< $(CCFLAGS)
You want to say "build a .o file from a .c file using this rule", but %.o %.c: says instead, "build both a .o and a .c file, from nothing, using this rule".
You need:
%.o: %.c
$(CC) -o $# -c $< $(CCFLAGS)
I have some code for handling all uart related functions and operations in a .h/.c pair that I usually include in my project. I have a makefile that compiles all of my .c files into .o files then links them all to one executable. For some reason, one of my projects using this pair compiles fine but the other gives this error:
obj/fiveax.o: In function `fiveax_init':
fiveax.c:(.text+0x10): undefined reference to `uart_init'
collect2: error: ld returned 1 exit status
when trying to link to the exectutable after compiling all the .o files. I have included my makefile below, it is the same for both projects with the only difference being the appname.
Makefile
########################################################################
####################### Makefile Template ##############################
########################################################################
# Compiler settings - Can be customized.
CC = avr-gcc
CXXFLAGS = -mmcu=atmega2560 -D BUILD=1
LDFLAGS = -Iinclude -Ilibs/FreeRTOS/include -Llibs/FreeRTOS -lfreertos
DEV = /dev/ttyUSB0
AVRCONF = -C/etc/avrdude.conf
AVRLOAD = $(AVRCONF) -v -patmega2560 -carduino -P$(DEV) -b57600 -D -Uflash:w:bin/$(APPNAME).hex:i
# Makefile settings - Can be customized.
APPNAME = FiveAx
EXT = .c
SRCDIR = src
OBJDIR = obj
INCDIR = include
DEPDIR = dep
############## Do not change anything from here downwards! #############
SRC = $(wildcard $(SRCDIR)/*$(EXT))
OBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)/%.o)
DEP = $(OBJ:$(OBJDIR)/%.o=$(DEPDIR)/%.d)
# UNIX-based OS variables & settings
RM = rm
DELOBJ = $(OBJ)
# Windows OS variables & settings
DEL = del
EXE = .exe
WDELOBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)\\%.o)
########################################################################
####################### Targets beginning here #########################
########################################################################
all: bin $(APPNAME)
# Builds the app
$(APPNAME): $(OBJ)
$(CC) $(CXXFLAGS) -o bin/$#.elf $^ $(LDFLAGS)
avr-objcopy -j .text -j .data -O ihex bin/$(APPNAME).elf bin/$(APPNAME).hex
bin:
mkdir -p $#
# Creates the dependecy rules
$(DEPDIR)/%.d: $(SRCDIR)/%$(EXT)
#$(CPP) $(CFLAGS) $< -MM -MT $(#:$(DEPDIR)/%.d=$(OBJDIR)/%.o) >$# $(LDFLAGS)
# Includes all .h files
-include $(DEP)
# Building rule for .o files and its .c/.cpp in combination with all .h
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
$(CC) $(CXXFLAGS) -o $# -c $< $(LDFLAGS)
load: bin $(APPNAME)
avrdude $(AVRLOAD)
################### Cleaning rules for Unix-based OS ###################
# Cleans complete project
.PHONY: clean
clean:
$(RM) -r $(DELOBJ) $(DEP) bin
# Cleans only all files with the extension .d
.PHONY: cleandep
cleandep:
$(RM) $(DEP)
edit: I have included the header file for uart.h in the source file.
edit: I was asked for the output of the makefile
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o obj/uart.o -c src/uart.c -Llibs/FreeRTOS -lfreertos
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o obj/servo.o -c src/servo.c -Llibs/FreeRTOS -lfreertos
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o obj/main.o -c src/main.c -Llibs/FreeRTOS -lfreertos
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o obj/fiveax.o -c src/fiveax.c -Llibs/FreeRTOS -lfreertos
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o bin/FiveAx.elf obj/uart.o obj/servo.o obj/main.o obj/fiveax.o
obj/fiveax.o: In function `fiveax_init':
fiveax.c:(.text+0x10): undefined reference to `uart_init'
collect2: error: ld returned 1 exit status
make: *** [Makefile:41: FiveAx] Error 1
It's impossible to read the information requested because it's not formatted as a code block so all the lines run together. Please use the live preview feature of the SO question editor to check that the content you're adding is readable, to save the sanity of the people trying to help you.
The link line appears to be this:
avr-gcc -mmcu=atmega2560 -D BUILD=1 -Iinclude -Ilibs/FreeRTOS/include -o bin/FiveAx.elf obj/uart.o obj/servo.o obj/main.o obj/fiveax.o
Here we can see that the library -lfreertos is not present, and also that all the object files come at the end after the flags. I don't see how this could have happened given the makefile you show above:
CXXFLAGS = -mmcu=atmega2560 -D BUILD=1
LDFLAGS = -Iinclude -Ilibs/FreeRTOS/include -Llibs/FreeRTOS -lfreertos
$(CC) $(CXXFLAGS) -o bin/$#.elf $^ $(LDFLAGS)
so it seems that the make output here doesn't match the makefile you've shown us. Are you sure you're using that makefile?
I am using this Git for Zbspac.exe
https://github.com/uyjulian/zbspac
And the following for my MinGW Distro:
https://nuwen.net/mingw.html
I have a MinGW distro set up to target my zbspac.exe Makefile. However, I keep getting bounced for
make (e=2): The system cannot find the file specified.
make: *** [Makefile:25: BitStream.o] Error 2
I have BitStream.c and Bitstream.h in the main directory, but it seems the object file doesn't register for the Distro. I feel that it's going to be the same for all the other object files.
My first idea was to create a duplicate file for each .c file into a .o file. This helped clear the issues relating to the .o not being found (although, this solution is probably not ideal). Is there a way to fix this (besides creating duplicate files)?
It then gives me the error
i686-w64-mingw32-gcc -o zbspac.exe BitStream.o ByteArray.o CmdArgs.o FileSystem.o HuffmanDecoder.o HuffmanEncoder.o Logger.o LzssDecoder.o LzssEncoder.o MinHeap.o NexasPacker.o NexasUnpacker.o ScriptPacker.o ScriptUnpacker.o StringUtils.o zbspac.o external/zlib/adler32.o external/zlib/compress.o external/zlib/crc32.o external/zlib/deflate.o external/zlib/gzclose.o external/zlib/gzlib.o external/zlib/gzread.o external/zlib/gzwrite.o external/zlib/infback.o external/zlib/inffast.o external/zlib/inflate.o external/zlib/inftrees.o external/zlib/trees.o external/zlib/uncompr.o external/zlib/zutil.o -static -static-libstdc++ -static-libgcc
process_begin: CreateProcess(NULL, i686-w64-mingw32-gcc -o zbspac.exe BitStream.o ByteArray.o CmdArgs.o FileSystem.o HuffmanDecoder.o HuffmanEncoder.o Logger.o LzssDecoder.o LzssEncoder.o MinHeap.o NexasPacker.o NexasUnpacker.o ScriptPacker.o ScriptUnpacker.o StringUtils.o zbspac.o external/zlib/adler32.o external/zlib/compress.o external/zlib/crc32.o external/zlib/deflate.o external/zlib/gzclose.o external/zlib/gzlib.o external/zlib/gzread.o external/zlib/gzwrite.o external/zlib/infback.o external/zlib/inffast.o external/zlib/inflate.o external/zlib/inftrees.o external/zlib/trees.o external/zlib/uncompr.o external/zlib/zutil.o -static -static-libstdc++ -static-libgcc, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [Makefile:22: zbspac.exe] Error 2
, which is a self-referential error, since I want to be compiling zbspac.exe, not referring to it.
For reference, the Makefile, which has not been edited:
EXE_TARGET = zbspac.exe
TXTS = License.txt Readme.txt Instructions.txt PackageFormat.txt ScriptTxtFormat.txt
PROJECT_FILE = Makefile .project .cproject
SRC_DIST = zbspac-src.7z
BIN_DIST = zbspac-bin.7z
CC = i686-w64-mingw32-gcc
LD = i686-w64-mingw32-ld
CFLAGS = -O2 -std=c99 -Werror -Wall -pedantic -pedantic-errors -Iexternal/zlib
LIBS = -static -static-libstdc++ -static-libgcc
DIST_MAKE = 7za a
ZLIB_SRCS = external/zlib/adler32.c external/zlib/compress.c external/zlib/crc32.c external/zlib/deflate.c external/zlib/gzclose.c external/zlib/gzlib.c external/zlib/gzread.c external/zlib/gzwrite.c external/zlib/infback.c external/zlib/inffast.c external/zlib/inflate.c external/zlib/inftrees.c external/zlib/trees.c external/zlib/uncompr.c external/zlib/zutil.c
SRCS = $(wildcard *.c) $(ZLIB_SRCS)
HEADERS = $(wildcard *.h)
OBJS = $(patsubst %.c, %.o, $(SRCS))
all: $(EXE_TARGET)
$(EXE_TARGET): $(OBJS)
$(CC) -o $(EXE_TARGET) $(OBJS) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $# $<
src_dist: $(SRC_DIST)
bin_dist: $(BIN_DIST)
$(SRC_DIST): $(SRCS) $(HEADERS) $(TXTS) $(PROJECT_FILE)
$(DIST_MAKE) $(SRC_DIST) $(SRCS) $(HEADERS) $(TXTS) $(PROJECT_FILE)
$(BIN_DIST): $(EXE_TARGET) $(TXTS)
$(DIST_MAKE) $(BIN_DIST) $(EXE_TARGET) $(TXTS)
.PHONY: clean
clean:
$(RM) $(OBJS) $(EXE_TARGET) $(SRC_DIST) $(BIN_DIST)
How do I solve this?
In a program, I have a list.c file, list.h file and run.c file. In the run.c file, the code contains my main program and also "#include list.h". In my list.h file, my functions are just void and being defined. Finally, in my list.c file, I include list.h again and I have the meaning and code of what each function is going to do. I made a makefile that looks like so:
SOURCES = run.c list.c
OBJECTS= run.o list.o
HEADERS = list.h
CC = gcc
CFLAGS = -g -Wall
lab1: $(OBJECTS)
(tab) $(CC) $(CFLAGS) $(OBJECTS) -o lab1
clean:
(tab) rm -fR *o lab1
There is nothing wrong in any of my code because it is already finished and I am just copying code. However, I am unsure how to use the makefile to run these multiple files. I am only familiar with runner files after compiling with gcc and using "./". Is there something wrong with my makefile or is there a step for compiling these files in a different way?
Thank you for any help
The given makefile is working and generates an executable lab1 file. However, the .o files depend on the list.h file, and this dependency is not captured.
You should specify targets to build the .o files, as follows:
SOURCES = run.c list.c
OBJECTS= run.o list.o
HEADERS = list.h
CC = gcc
CFLAGS = -g -Wall
lab1: $(OBJECTS)
(tab) $(CC) $(CFLAGS) $(OBJECTS) -o lab1
%.o: %.c $(HEADERS)
$(CC) -c $(CFLAGS) $< -o $#
clean:
rm -fR *o lab1
Word of caution: With this makefile, if the list of HEADERS grows, a change in any of the headers will warrant a rebuild of all .o files.
For example, imagine we also have buf.c which uses buf.h. Now HEADERS = list.h buf.h. If we change buf.h, our makefile would rebuild both list.o and buf.o, even though a buf.o rebuild would suffice.
To remedy this, we could use a more verbose makefile which identifies the specific header prerequisites for each .o file with rules such as the following:
list.o: list.c list.h
$(CC) -c $(CFLAGS) $< -o $#
buf.o: buf.c buf.h
$(CC) -c $(CFLAGS) $< -o $#
Solution 1: Simply list each .c file separately as input and compile once
gcc list.c run.c -o lab1
Solution 2: Compile each .c file separately
gcc -c list.c
gcc -c run.c
gcc -o lab1 list.o run.o
Your project is small and simple enough that a fully generalized makefile is overkill:
SOURCES = run.c list.c
CC = gcc
CFLAGS = -g -Wall
all:
$(CC) $(CFLAGS) $(SOURCES) -o lab1
clean:
rm -fR *o lab1
The all: is a default target that executes when you simply type make with no arguments.
After compiling, it did end up making a lab1 file that I could run and everything worked. My makefile ended up working fine, I was just completely oblivious to the fact that it was making a file called lab1. I did change my makefile to the above options and that also worked. Thank you
I am writing a C application using libcurl. I downloaded the libcurl from this link: http://curl.haxx.se/dlwiz/?type=lib&os=Win32&flav=-
I can compile and run the code when I set the path for header and library files in codeblocks. In codeblocks I gave the library path with library libcurldll.a I have kept libcurl.a, libcurl.dll and libcurldll.a in my executable forder. But when I write a makefile for this and give the path, then the code is not linking to curl libraries. I get the message undefined reference to _imp__curl_global_init and so on for all curl functions in code.
Following is my makefile for the code:
OBJS = http.o web_request.o
TARGET = http
INC_PATH = ./include
LIB_PATH= ./libs
CC = gcc
os = windows
CFLAGS = -c -g -I$(INC_PATH)
LDFLAGS = -L$(LIB_PATH)
LIBS = -lpthreadVC2 -lws2_32 -lcurl
$(TARGET): $(OBJS)
$(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS)
http.o: http.c
$(CC) $(CFLAGS) http.c
web_request.o: web_request.c
$(CC) $(CFLAGS) web_request.c
clean:
rm $(TARGET) $(OBJS)
Can anyone please tell what is wrong here? Thanks in advance for your responses.