Makefile variable to c program - c

Hello i need help with makefile variables.
make build //(compiler server)
make run PORT=something //(run server on port something)
I need save this variable and post to the server.c and client.c Here is my Makefile
SERVER=server
CLIENT=client
FILES=src/server.c src/client.c
CFLAGS=-std=gnu99 -Wall -Wextra -Werror -pedantic
CC=gcc
build:
$(CC) $(CFLAGS) -o $(SERVER) src/server.c
$(CC) $(CFLAGS) -o $(CLIENT) src/client.c
run:
./server
clean:
$(RM) *.o src/$(CLIENT) src/$(SERVER

A plausible outline for a compile-time decision about port number might be:
SERVER = server
CLIENT = client
SERVER.c = src/server.c
CLIENT.c = src/client.c
CFLAGS = -std=gnu99 -Wall -Wextra -Werror -pedantic
PORT = 9823
DFLAGS = -DPORT=$(PORT)
CC = gcc
all: build
build: $(CLIENT) $(SERVER)
$(CLIENT): $(CLIENT.c)
$(CC) $(CFLAGS) $(DFLAGS) -o $(CLIENT) $(CLIENT.c)
$(SERVER): $(SERVER.c)
$(CC) $(CFLAGS) $(DFLAGS) -o $(SERVER) $(SERVER.c)
run: $(CLIENT) $(SERVER)
./$(SERVER)
clean:
$(RM) *.o $(CLIENT) $(SERVER)
The code for the client and the server contains code such as this, preferably in a common header:
#ifndef PORT
#define PORT 1234
#endif
and references PORT where the port number is needed.
If it is strictly a run-time decision, then maybe you use:
SERVER = server
CLIENT = client
SERVER.c = src/server.c
CLIENT.c = src/client.c
CFLAGS = -std=gnu99 -Wall -Wextra -Werror -pedantic
PORT = 9823
CC = gcc
all: build
build: $(CLIENT) $(SERVER)
$(CLIENT): $(CLIENT.c)
$(CC) $(CFLAGS) -o $(CLIENT) $(CLIENT.c)
$(SERVER): $(SERVER.c)
$(CC) $(CFLAGS) -o $(SERVER) $(SERVER.c)
run: $(CLIENT) $(SERVER)
./$(SERVER) -p $(PORT)
clean:
$(RM) *.o $(CLIENT) $(SERVER)
You'd also need to tell the client to connect to the given port number, of course. You should still have a default port number that is shared by both client and server in some common header.
You might use a hybrid of these solutions, where you define the default port number in the build process and use it in the run rule too.

Related

Can't compile a C program in Windows 7 with MinGW make

I want to compile a C program from GitHub on Windows 7 and get an error that a file is not found. I have installed MinGW Make and its dependancies. I think maybe this program is only intended to run on Linux.
The Console output:
E:\work-c\iso2opl-clone\iso2opl>make
gcc -std=gnu99 -pedantic -usr\include -usr\local\inc
lude -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -c isofs.c -o isofs.o
process_begin: CreateProcess(NULL, gcc -std=gnu99 -pedantic -F:\programs\mingw\i
nclude -F:\programs\mingw\local\include -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SO
URCE -c isofs.c -o isofs.o, ...) failed.
make (e=2): Le fichier spécifié est introuvable.
make: *** [isofs.o] Erreur 2
the makefile:
CC = gcc
CFLAGS = -std=gnu99 -pedantic -I/usr/include -I/usr/local/include -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
#CFLAGS += -DDEBUG
ifeq ($(_WIN32),1)
CFLAGS += -D_WIN32
endif
OBJS = isofs.o \
iso2opl.o
all: $(TARGET)
rm-elf:
-rm -f $(TARGET) $(OBJS)
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $#
clean:
rm -r $(OBJS) $(TARGET)
I don't know maybe the paths are wrongs.
Best Regards
Try to run the make in the MSYS2 shell (https://www.msys2.org/). I was able to build the sources from https://github.com/arcadenea/iso2opl without issue.

make: the system cannot find the file specified (Error 2)

I'm trying to compile a C program on Windows for use on a linux dev board.
When I try to compile using a makefile I get this output:
$ make
arm-linux-gnueabihf-gcc -g -Wall main.c -o filetest
process_begin: CreateProcess(NULL, arm-linux-gnueabihf-gcc -g -Wall main.c -o filetest, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [filetest] Error 2
This happens whether or not a blank file called filetest is present or not in the same directory. If it is present, I can run make clean and it will remove the file.
Here is the makefile I'm using:
#
TARGET = filetest
ALT_DEVICE_FAMILY ?= soc_cv_av
SOCEDS_ROOT ?= $(SOCEDS_DEST_ROOT)
HWLIBS_ROOT = $(SOCEDS_ROOT)/ip/altera/hps/altera_hps/hwlib
CROSS_COMPILE = arm-linux-gnueabihf-
CFLAGS = -g -Wall -D$(ALT_DEVICE_FAMILY) -I$(HWLIBS_ROOT)/include/$(ALT_DEVICE_FAMILY) -I$(HWLIBS_ROOT)/include/
LDFLAGS = -g -Wall
CC = $(CROSS_COMPILE)gcc
ARCH= arm
build: $(TARGET)
#
$(TARGET):main.c
$(CC) $(LDFLAGS) $^ -o $#
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -f $(TARGET) *.a *.o *~
I used tabs in my actual makefile instead of spaces for the code block above ^^
Also, I'm working within Intel's FPGA SoC EDS for a Cyclone V board.

Makefile compilation

I have to compile a client.c file; in this file there are macro defined in utiliy_lib.h
When I run :
gcc -Wall -c client.c utility_lib.h
The compiler doesn't find macro definitions.
I have this file in the same folder "code":
client.c
server.c
utility_lib.c //it contains generic macro using by every file
utility.c //it contains utility function, used by client and server
msg_queue.c // it contains function to manipulate message queue (this is a little project for a chatroom)
send_receive.c //it contains function to send and receive message
the makefile that I tried is:
CC = gcc -Wall -O0 -g
LDFLAGS = -lpthread
ARCH = $(shell uname -m)
all: client server
server: common.h main.c msg_queue.c send_recv.c util.c
rm -f build/*.o
$(CC) -c main.c -o build/main.o
$(CC) -c send_recv.c -o build/send_recv.o
$(CC) -c util.c -o build/util.o
$(CC) -c msg_queue.c -o build/msg_queue.o
$(CC) -o server build/*.o $(LDFLAGS)
client:
ln -s -f client-$(ARCH) client
:phony
clean:
rm -f client server build/*.o
Anyone could help me please?
Client.C needs to
#include "utility_lib.h"
Near the top of the file
That gives it the definitions
Then compile is
gcc -Wall -c client.c

Makefile compile twice different define

I'm trying to build two binaries with the same sources, just with a different define.
Basically what I'm doing right now is:
OBJ = $(SRC:.cpp=.o)
CPPFLAGS_S = $(INC) -Wall -Wextra -O3 -g -D SERVER
CPPFLAGS_C = $(INC) -Wall -Wextra -O3 -g -D CLIENT
server: CPPFLAGS= $(CPPFLAGS_S)
client: CPPFLAGS= $(CPPFLAGS_C)
server: $(OBJ)
g++ $(OBJ) -o $(NAME_S) $(CPPFLAGS_S) $(LIB)
client: $(OBJ)
g++ $(OBJ) -o $(NAME_C) $(CPPFLAGS_C) $(LIB)
all: server client
Obviously it's not working. What it's doing is compiling everything with the SERVER define, and because the .o files are already there, they will be used again to create the client binary, still using the SERVER define. I could use some help.
Well, it's a pretty fundamental tenet of filesystems that you can only have one file with a given name in the same directory. There's not much make can do about that!
So you have three choices: you can delete all the object files after you build each target, or you can create differently-named object files for each target, or you can build the objects into different subdirectories for each target.
Personally I prefer the latter, so you'd need to write new rules to explain to make how to create a file in a subdirectory:
SERVEROBJ = $(SRC:%.cpp=server/%.o)
CLIENTOBJ = $(SRC:%.cpp=client/%.o)
CXX = g++
CPPFLAGS = $(INC)
CXXFLAGS = -Wall -Wextra -O3 -g
server: CPPFLAGS += -DSERVER
client: CPPFLAGS += -DCLIENT
all: server client
server client:
$(CXX) $^ -o $# $(CXXFLAGS) $(LIB)
server: $(SERVEROBJ)
client: $(CLIENTOBJ)
server/%.o: %.cpp
mkdir -p $(#D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $# $<
client/%.o: %.cpp
mkdir -p $(#D)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $# $<

Makefile, Compiling and Linking

I have a question regarding compiling and linking in Makefile (and perhaps in general).
I have a server.c file which consists of the main program which has a main() function. server.c includes rio.c. I have a module called rio which consists of rio.c and rio.h. It has no main() function.
I have two questions, how to actually write the Makefile, and the best practice for doing such a thing.
Q1: How to write the Makefile
I have the following Makefile:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
all: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o sysstatd
server.o: server.c
$(CC) $(CFLAGS) -c server.c
rio.o: rio.c rio.h
$(CC) $(CFLAGS) -c rio.c
clean:
rm -f *~ *.o sysstatd
I am having linking issues with this. It says that I have multiple definitions of all the functions used in C. I'm not sure how this is possible since server.c is compiled with the -c flag so nothing is actually linked. It should know that some functions exist but not actually link them until the all rule compiles both object files together and produces a single object file which has everything linked.
What is the issue here?
Q2: Best practice
Since I have a module and then another file which contains the main program, should I compile the main program, server.c, as a separate module and then compile both together in all, or compile server.c in all and add the rio.o module there? Note that this still produces the same linking problem I have above so I'm pretty sure I have my issue lies somewhere else.
You should revise the structure a little:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
all: sysstatd
sysstatd: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o sysstatd
server.o: server.c
$(CC) $(CFLAGS) -c server.c
rio.o: rio.c rio.h
$(CC) $(CFLAGS) -c rio.c
clean:
rm -f *~ *.o sysstatd
The difference is that the phoney rule all depends on sysstatd being up to date, and sysstatd is up to date when it is up to date w.r.t the object files.
Now it is just rather verbose, writing the compilation actions explicitly. It would be sufficient to use:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
all: sysstatd
sysstatd: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o sysstatd
server.o: server.c
rio.o: rio.c rio.h
clean:
rm -f *~ *.o sysstatd
You could also debate: does server.c not use rio.h? If it does, the dependency should be listed. If not, why does rio.h exist? make will assume that server.o depends on server.c, so you don't have to specify that (but it won't make assumptions about the headers). You could also use a macro to prevent repetition of the program name:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
PROG = sysstatd
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $#
server.o: rio.h
rio.o: rio.h
clean:
rm -f *~ *.o $(PROG) core a.out
If you needed other libraries, then you might use:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
PROG = sysstatd
LOCALLIBDIR = /usr/local/lib
LDFLAGS = -L$(LOCALLIBDIR)
LDLIBS = -lone -ltwo
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $# $(LDFLAGS) $(LDLIBS)
server.o: rio.h
rio.o: rio.h
clean:
rm -f *~ *.o $(PROG) core a.out

Resources