How to include Apache Avro C header files? - c

I am trying to use Apache Avro C in a program to better understand how it works. I downloaded Apache Avro for C and installed it on my system (CentOS 7.8.2003). I'm trying to run a copy of the example program provided in the Avro documentation.
// avro_test.c
#include <avro.h>
#include <stdio.h>
#include <stdlib.h>
...
My directory structure looks like this:
avro_test.c
Makefile
avro-c-1.10.0
- build
- src
- libavro.a
- libavro.so
- src
- avro.h
- avro
- // Other header files referenced in avro.h
My Makefile is similar to the one provided here and is listed below:
CC=gcc
CFLAGS=-c -Wall
LDFLAGS=-lavro
SOURCES=avro_test.c
OBJECTS=$(SOURCES:.c=.o)
EXECUTABLE=avro_test
INC_PATH=/avro-c-1.10.0/src/
INC=-I/avro-c-1.10.0/src/ -I/avro-c-1.10.0/src/avro
LIB=-L/avro-c-1.10.0/build/src
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(LIB) $(OBJECTS) -o $#
.c.o:
$(CC) $(INC) $(CFLAGS) $< -o $#
clean:
rm -rf *.o avro_test
When I run make from the outermost directory, I receive the following error:
gcc -I/avro-c-1.10.0/src/ -I/avro-c-1.10.0/src/avro -c -Wall avro_test.c -o avro_test.o
avro_test.c:18:18: fatal error: avro.h: No such file or directory
#include <avro.h>
^
compilation terminated.
make: *** [avro_test.o] Error 1
I've also tried replacing <avro.h> with "avro.h", but the same error appeared.
Any help is appreciated. Thanks!

I figured it out, it was a silly mistake on my part. In the Makefile, I changed the paths from absolute paths to relative paths (INC_PATH=/avro-c-1.10.0/src/ became INC_PATH=./avro-c-1.10.0/src/). Once I changed all the paths the issue disappeared.

Related

Makefile not detecting changes to source file when running make

Issue Description
I have a Makefile that is not recognizing when changes to the underlying source code are made. When I attempt a build I get the following message to the console: "make: Nothing to be done for 'all'." My sense is that this probably has to do with a flawed understanding on my part regarding how to work with files in different directories. I have seen similar questions on StackOverflow but none seem to deal quite with this issue or the issue appears to result from other problems.
Project Structure
src: the source code files live here.
include: header files live here.
build: object files live here.
bin: executables live here.
test: test code lives here.
Makefile: the make file.
Makefiles
I have created a basic source file called main.c and placed it in src and implemented a simple make file as follows:
CC = gcc
CFLAGS = -DTESTABLE -Wall -std=c99 -g
all: bin/main
bin/main: build/main.o
build/main.o: src/main.c
clean:
rm -f build/main.o
rm -f bin/main
Source File
#include <stdio.h>
int main( int argc, char *argv[] )
{
printf( "Hi there. For real." );
}
These lines:
bin/main: build/main.o
build/main.o: src/main.c
tell make that to build bin/main it needs build/main.o and to build build/main.o it needs src/main.c, but you haven't actually told make how to build either build/main.o or bin/main. You have to provide a recipe that make can use to actually do the build; maybe:
bin/main: build/main.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $^ $(LDLIBS)
build/main.o: src/main.c
$(CC) $(CFLAGS) -c -o $# $<

Using a Makefile in C (make: *** No rule to make target .. needed by ... Stop

I'm trying to create a communication channel between two devices, such as two computers, that will work with the cryptographic network protocol Salt channelv2 and forward data to each other. I created 2 applications, where the first application demonstrates the functionality of the Salt channelv2 protocol and the second application creates a secure communication channel (specifically using the TCP / IP model). Applications are working, I compiled them using linking in the CLI and now I am trying to create a makefile file for easy compilation of the program for the user.
This is my Makefile:
CC=gcc
CFLAGS=-O2 -Wall -g -fcommon -I./salt_org -I./header_folders -I./library
#LDFLAGS=
all:program
program: salt_buffer.o libcrypto.a
$(CC) $(CFLAGS) -o program.exe salt_buffer.o libcrypto.a
randombytes.o: randombytes.c
$(CC) $(CFLAGS) -c randombytes.c
tweetnacl_modified.o: tweetnacl_modified.c tweetnacl_modified.h
$(CC) $(CFLAGS) -c tweetnacl_modified.c
tweetnacl_modified_wrapper.o: tweetnacl_modified_wrapper.c
$(CC) $(CFLAGS) -c tweetnacl_modified_wrapper.c
salt.o: salt.c salt.h salti_handshake.h salti_util.h
$(CC) $(CFLAGS) -c salt.c
salt_io.o: salt_io.c salti_util.h
$(CC) $(CFLAGS) -c salt_io.c
salti_handshake.o: salti_handshake.c salti_handshake.h
$(CC) $(CFLAGS) -c salti_handshake.c
salti_util.o: salti_util.c salti_util.h
$(CC) $(CFLAGS) -c salti_util.c
salt_modified.o: salt_modified.c salt_modified.h salt.h
$(CC) $(CFLAGS) -c salt_modified.c
salt_buffer.o: salt_buffer.c header_folders/salt.h \
header_folders/salti_handshake.h header_folders/salti_util.h \
header_folders/salt_modified.h header_folders/salt_io.h
$(CC) $(CFLAGS) -c salt_buffer.c
libcrypto.a: salt.o salti_handshake.o salti_util.o salt_io.o tweetnacl_modified_wrapper.o \
tweetnacl_modified.o randombytes.o salt_modified.o
ar -cvq -o libcrypto.a salt.o salti_handshake.o salti_util.o salt_io.o \
tweetnacl_modified_wrapper.o tweetnacl_modified.o randombytes.o salt_modified.o
clean:
rm -f program *.o *.a hlavickove_subory/*.gch
In one folder are source codes and folders such as salt_org, header_folders, library, salt_buffer.c, salt_modified.c and makefile. The main program is salt_buffer.c and salt_modified.c contains the source file I supplied with the body functions needed for the application that salt_buffer.c works with. With auxiliary source codes I try to create a static library libcrypto.a. Source codes such as randombytes.c, tweetnacl_modified.c, tweetnacl_modified_wrapper.c are in the library folder. Other source codes such as salt.c, salti_handshake.c, salti_util.c, salt_io.c are in the salt_org folder. All the header files I use are in the header_folders folder.
At work, I was inspired by the topic: enter link description here.
The problem I get when running the makefile file is:
gcc -o .o
gcc.exe: fatal error: no input files
compilation terminated.
make: *** [: .o] Error 1
In source files, I have paths to files like this for example salt_buffer.c:
#include "salt.h"
#include "salt_io.h"
#include "salti_util.h"
#include "salti_handshake.h"
#include "salt_modified.h"
I work with the Winlibs compiler with 11.2
Can you please advise me about my errors ?
First, when asking questions like this you should always include (via cut and paste) the actual compile line that generated the errors, not just the errors. The reason for errors like this is always found on the compile line.
Second, your problem is that you should never include the header files on the compile line. The compiler will include the headers because of the #include ... commands inside the source file: you must not include them on the compilation line as well. Rules like this:
salt.o: salt.c salt.h salti_handshake.h salti_util.h
$(CC) $(CFLAGS) -c salt.c salti_handshake.h salti_util.h
should simply be:
salt.o: salt.c salt.h salti_handshake.h salti_util.h
$(CC) $(CFLAGS) -c salt.c
and that's all. Ditto for all other recipes where header files appear on the compilation line.
There are many better ways to write this makefile so you don't have to repeat yourself so many times, but fixing the above should allow your current makefile to work properly.

C Makefile, Strange error with "No target" when a target is present

So I have the makefile
HEADERS = preferences.h distances.h
OBJECTS = movie_recommender.o preferences.o distances.o
default: movie_recommender
%.o: %.c $(HEADERS)
; gcc -c $< -o $#
movie_recommender: $(OBJECTS)
; gcc $(OBJECTS) -o $#
clean:
; -rm -f $(OBJECTS)
; -rm -f movie_recommender
And I receive the error:
No rule to make target 'movie_recommender.o', needed by 'movie_recommender'. Stop.
File paths
I've tried adding the target,
movie_recommender.o: movie_recommender.c
gcc -c movie_recommender.c
And I receive another error. Could anyone please tell me what I'm doing wrong?
Many thanks!
The make program only looks in the current directory for your files. There is no movie_recommender.c file in the current directory, so make doesn't see it and doesn't find any way to make movie_recommender.o.
The solution is to add make your makefile aware of the source and header directories, which you can do with the vpath directive. If you add
vpath %.c src
then it will automatically look for %.c files in the src directory.
Similarly, make won't find your headers.
GCC also won't find the headers, and it can't know about make's vpath, so instead you need to pass -Iinclude to GCC.

Makefile confusion phony hack

Folder structure:
Makefile
rect_01.c
rect_02.c
square_01.c
Makefile (relevant parts):
%.c:
echo 'Building $# for $(PLATFORM)...'
$(CC) $(CFLAGS) $# -o '$(DESTDIR)/$*'
Command:
make rect_01.c PLATFORM=FOO
Problem - gave me the output:
'rect_01.c up already to date'
So I tried a hack and added a dependency which I added to .Phony,
so that %.c should be executed every time. But now it tries to compile my
makefile even it hasn't the extension .c.
I wrote the following updated makefile (relevant parts):
.PHONY: phonyDummy
%.c: phonyDummy
echo 'Building $# for $(PLATFORM)...'
$(CC) $(CFLAGS) $# -o '$(DESTDIR)/$*'
Which gives me the following output:
make rect_01.c PLATFORM=LINUX_X86
echo 'Building Makefile.c for LINUX_X86...'
Building Makefile.c for LINUX_X86...
g++ -Wall -g Makefile.c -o '../Executables/Makefile'
Makefile: file not recognized: File format not recognized
Makefile:55: recipe for target 'Makefile.c' failed
make: *** [Makefile.c] Error 1
Can you explain this behaviour?
You should learn more about Makefile. You mix two important things: target and dependency.
The target is a file (in most cases) which should create with a rule. The dependency is the "source".
If you write:
%.c:
echo 'Building $# for $(PLATFORM)...'
$(CC) $(CFLAGS) $# -o '$(DESTDIR)/$*'
it means: "I want to create files with .c extension". You don't want to create .c files because you've many (three) .c files. The make checks the rect_01.c: it exists and it's up-to-date because it hasn't any dependency (after the : there isn't anything).
I think you want to build rect_01.so (or similar) - this is the target! So you want similar:
%.o: %.c
echo 'Building $# for $(PLATFORM)...'
$(CC) $(CFLAGS) -o $# $<
In this case if you want to build rect_01.o you should run make rect_01.o. The $(CC) will run if rect_01.o doesn't exist or older than rect_01.c (so the source rect_01.c is newer and doesn't rebuild yet).

Handling #include <folder/file.h> in C with makefiles

I am in the process of porting some code that was developed in the codeblocks IDE. I am transferring it to a Linux server where I can only use the command line to compile the code. The code is quite large (maybe 100 files) and I need to update the include commands in many files. For when I try to compile it errors on for instance: #include <gsl/gsl_math.h> with a file cannot be found error. I am assuming it cannot be found because the location of the gsl folder was declared in one of the search directory field options in the IDE. I could go through each file an update to the correct path, but is there a better way of doing this for use with a makefile?
Thanks!
EDIT Makefile In Question
# -c : do not link, just create object file
# -o : output file name
CFLAGS += -c -O2 -I../ctraj -I../cspice/include -I../SGP4 -I../cconj -I../GSL-1.13/include
LIBS = -L../ctraj -lctraj -L../cspice/lib -lcspice -L../SGP4 -lsgp4 -L../cconj -lcconj -L./ -lgsl-0 -lgslcblas-0 -lm
DEPS = light.h ../ctraj/ctraj.h ../cconj/cconj.h
OBJ = light.o tle.o propagator.o orbitfit.o conjunction.o light_displacement.o forces_LF.o
OUT = light.exe
%.o: %.c $(DEPS)
gcc -o $# $< $(CFLAGS)
light: $(OBJ)
cd ../ctraj/; make
gcc -o $(OUT) $(OBJ) $(LIBS)
clean:
rm *.o $(OUT)
Edit 2
Folder Structure
light->(GSL-1.13, Light, cconj, ctraj)
the makefile is inside the Light folder.
Error Message
cd ../ctraj/; make
make[1]: Entering directory `/light/ctraj'
gcc -o forces.o forces.c -c -Wall -Wno-maybe-uninitialized -Wno-unused-but-set-variable -O2 -I../cspice/include -Inrlmsise
In file included from ../Light/../cconj/cconj.h:12:0,
from ../Light/light.h:13,
from forces.c:3:
../Light/../cconj/../GSL-1.13/include/gsl/gsl_blas.h:26:28: fatal error: gsl/gsl_vector.h: No such file or directory
compilation terminated.
make[1]: *** [forces.o] Error 1
make[1]: Leaving directory /light/ctraj'
make: *** [light] Error 2
EDIT 3
Second makefile in cconj
# -c : do not link, just create object file
# -o : output file name
#-L../cconj -lcconj
CFLAGS += -c -O2 -I./ -I../GSL-1.13/include
LIBS = -L./ -lgsl-0 -lgslcblas-0 -lm
INC= -I../GSL-1.13/include
DEPS = cconj.h
OBJ = cconj_util.o ellipse_intersect.o collision_prob_real.o rcs2size.o
OUT = libcconj.a
%.o: %.c $(DEPS)
gcc -o $# $< $(CFLAGS)
cconj: $(OBJ)
ar rcs $(OUT) $(OBJ)
clean:
rm *.o $(OUT)
Try adding this line to your makefile, and tell us if it works:
CFLAGS += -I../GSL-1.13/include
In order to compile source code and produce object files, Make must use a rule. (If you don't put such a rule in the makefile, Make has a default rule for that purpose.) It looks something like this:
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
Without digging too deeply into how that works, we can say that CFLAGS is a list of arguments to be passed to the compiler. When we add -I../GSL-1.13/include, we tell the compiler "if you want to #include something and can't find it elsewhere, look in ../GSL-1.13/include".
If this approach doesn't work, then there's probably a rule in the makefile we must find and alter.
EDIT:
The problem isn't in this makefile (which already contains a reference to GSL-1.13/include). In this command:
cd ../ctraj/; make
this makefile launches a second Make process, which uses the Makefile in light/cconj/. According to the compiler output (gcc -o forces.o ...), that makefile does not include the reference. So try adding the same line there, and if that doesn't work, post that makefile and we'll keep looking.
Use -I option of gcc to specify where to look for includes.

Resources