I wanted to create a C program to create several different executable binaries from the same Makefile with different names.
but as everytime I run "make" of a pretty large program, they have this bunch logs output... and if i made several of this the terminal would be so "dirty"
So the question, is it actually okay to run "make" in background, so i don't have to see those log?
is it a good idea? or does this actually has no relation with putting it to the background or so?
and if yes, how can i do so?
For the program it's more or less like below, where tmp2 is array of the binaries name
for (int j = 0; tmp2[j] != NULL; j++)
{
printf("-> %s\n", tmp2[j]);
char command[128] = "";
sprintf(command, "make -C %s TARGET=%s all", "file/path/", tmp2[j]);
system(command);
}
and I tried to look up for running linux command in background like adding & at the end of the command, but it still shows the log
text.c:442:3: warning: blablabla
gcc -W -Wall -Wextra -c -g -Os -I. test1.c
gcc -W -Wall -Wextra -c -g -Os -I. test2.c
gcc -g -o STEM_ECS2_SERVICE_3 main.o json.o config.o debug.o -lnsl -lm -ldl -lc -lmysqlclient -lm
/bin/mv *.o ./object
the log is sth like above, its the simplified version, it's just all the stuff from -Wall and the actual command like gcc stuff
So is there actually any way to not see the "make" log?
EDIT
for the make file
include ../../Make.cf
OBJ_DIR = ./object
CFLAGS = -g -Os $(INCDIR) $(MYSQLINC) -I./include -export-dynamic
LDFLAGS = $(SYSNLIB) $(SYSLIB) $(MYSQLLIB) $(THREADLIB) -L$(LIBDIR) \
-lmysqlclient -lm
C_OBJECTS = main.o \
json.o \
ecs_config.o \
ecs_debug.o \
######### define target #########
all: $(TARGET)
main.o: main.c
$(CC) -W -Wall -Wextra -c $(CFLAGS) $(DEFINES) main.c
json.o: json.c
$(CC) -W -Wall -Wextra -c $(CFLAGS) $(DEFINES) json.c
config.o: config.c
$(CC) -W -Wall -Wextra -c $(CFLAGS) $(DEFINES) config.c
debug.o: debug.c
$(CC) -W -Wall -Wextra -c $(CFLAGS) $(DEFINES) debug.c
$(TARGET): $(C_OBJECTS)
$(CC) $(CFLAGS) $(DEFINES) -std=gnu99 -o $(TARGET) $(C_OBJECTS) $(LDFLAGS)
$(MV) *.o $(OBJ_DIR)
touch:
$(TOUCH) *.c
clean:
$(RM) $(OBJ_DIR)/*.o
rm -f *.o core $(TARGET)
cp:
cp -f $(TARGET) $(BINDIR)/$(TARGET)
so this make file is actually made by someone else from the group, and I cant really show the exact path to stuff, but hope this help
First of all, running the same make/makefile in parallel with different instances of make can result in race conditions -- so no, it's not a good idea. (eg. if instance 1 of make was trying to access a dependency that instance 2 was in the process of updating, you could end up with corrupt data)
That being said, you can get around that by just using a single instance of make as so:
make -j targ1 targ2 targ3
This will build targ1, targ2, and targ3, will build dependencies only once for all targets, and will build everything in the correct order etc.
I'm not clear why you would want to call this from a c file rather than just use the command line, but if there is a reason for this, you would want it to look something like:
char command[1024] = "";
char *eo_command = command + sizeof(command);
char *ptr = command;
ptr += snprintf(command, sizeof(command) "make -C %s", "file/path/");
// add some checks to ptr here...
for (int j = 0; tmp2[j] != NULL; j++) {
ptr += snprintf(ptr, eo_command-ptr, " %s", tmp2[j]);
// add some checks to ptr here...
}
system(command);
If you don't want to see the output, you can pipe the output to /dev/null. Also, if you want it to build faster, you can pass a -j flag to the make command line which will allow it to build multiple targets in parallel.
I'm going to close this question since the solution given by #Someprogrammerdude is the best fitting to my question I think.
So I did fix my problem by changing the code a little bit
for (int j = 0; tmp2[j] != NULL; j++)
{
printf("-> %s\n", tmp2[j]);
char command[128] = "";
sprintf(command, "make -C %s TARGET=%s all 2> make_error_log.txt > make_log.txt", "file/path/", tmp2[j]);
system(command);
}
Although, since Bodo mentioned it i'm going to learn shell scripting too.
Thanks for all the help
it is possible to call the make command with a & at the end, so the process spawns in the background, and you get the PID.
Something like that:
make -SOME_FLAGS &
Related
Hi i'm having issues while compiling my c program.
I'm using Makefile to compile it.
this is my make file :
# flags per la compilazione
#CFLAGS = -std=c89 -Wpedantic
CC = gcc
SO_HEIGHT= SO_HEIGHT=20
SO_WIDTH= SO_WIDTH=60
LIBS=libs/
OBJ = $(LIBS)ipc_utilities.o $(LIBS)utilities.o $(LIBS)dijkstra.o
OBJMAIN = main.o
OBJSOSOURCES=so_sources.o
OBJTAXI=taxi.o
all : utilities main so_sources taxi clean run
main: $(OBJMAIN) $(OBJ)
$(CC) $(OBJMAIN) $(OBJ)-o main
so_sources: $(OBJSOSOURCES) $(OBJ)
$(CC) $(OBJSOSOURCES) $(OBJ) -o so_sources
taxi: $(OBJTAXI) $(OBJ)
$(CC) $(OBJTAXI) $(OBJ)-o taxi
utilities:
$(CC) -c -D $(SO_HEIGHT) -D $(SO_WIDTH) -o $(LIBS)utilities.o $(LIBS)utilities.c
clean:
rm -f *.o
rm -f $(LIBS)*.o
clear
# il target run si usa talvolta per eseguire l'applicazione
run:
./main
this is the error i get :
gcc -c -D SO_HEIGHT=20 -D SO_WIDTH=60 -o libs/utilities.o libs/utilities.c
gcc -c -o libs/ipc_utilities.o libs/ipc_utilities.c
In file included from libs/ipc_utilities.h:4,
from libs/ipc_utilities.c:8:
libs/utilities.h:44:27: error: ‘SO_HEIGHT’ undeclared here (not in a function)
44 | struct strada cityMap[SO_HEIGHT][SO_WIDTH];
| ^~~~~~~~~
libs/utilities.h:44:38: error: ‘SO_WIDTH’ undeclared here (not in a function)
44 | struct strada cityMap[SO_HEIGHT][SO_WIDTH];
| ^~~~~~~~
make: *** [<builtin>: libs/ipc_utilities.o] Error 1
On ipc_utilities.h i include utilities.h :
#include <stdio.h>
#include <stdlib.h>
#include "utilities.h" // error
I'm familiar with makefile , anynone can help?
There are a number of ways to put the pieces together, but since you need both the define name and its value, I would do something like the following:
SO_HEIGHT := 20
SO_WIDTH := 20
CFLAGS := -std=c11 -Wall -Wextra -pedantic -Wshadow
CFLAGS += -DSO_HEIGHT=$(SO_HEIGHT) -DSO_WIDTH=$(SO_WIDTH)
...
$(CCLD) -o $(APPNAME) $(OBJECTS) $(CFLAGS) $(LDFLAGS) $(LIBS)
Now you have the define label and value as part of your CFLAGS variable (e.g. -DSO_HEIGHT=$(SO_HEIGHT)) you do not need to include anything further in your makefile rule.
Of Course, you could also simply do:
SO_HEIGHT := SO_HEIGHT=20
SO_WIDTH := SO_WIDTH=20
CFLAGS := -std=c11 -Wall -Wextra -pedantic -Wshadow
CFLAGS += -D$(SO_HEIGHT) -D$(SO_WIDTH)
It's really however you want to do it.
I wrote a makefile which builds a C program attaching the x.264 header. After trying to execute the makefile in terminal I receive the fatal error:
"example.c line [line of #include ] x264.h no such file or directory". Below you can find the C code and makefile (located in the same folder, the library - containing the x264.pc file- is in the folder libx264 of the parent folder). I would be very grateful if you could help with the linkage.
Makefile:
CC = gcc
CFLAGS = -c -Wall `export PKG_CONFIG_PATH=../libx264 && pkg-config --cflags x264`
LDFLAGS = -static `export PKG_CONFIG_PATH=../libx264 && pkg-config --libs --static libx264`
all: Release
Debug: CFLAGS += -g
Debug: example
Release: example
test: example.o
$(CC) -o example example.o $(LDFLAGS)
test.o: example.c
$(CC) $(CFLAGS) example.c -o example.o
clean:
rm -f example.o example
example.c code
#include <stdio.h>
#include <x264.h>
int main( int argc, char **argv )
{
int width, height;
return 0;
}
You'd need to tell the compiler (to be more precise: the preprocessor) where the header file is using the -I option:
CFLAGS = -c -Wall -I../libx264
If I'm right, you need to unpack that .pc file, so that x264.h is indeed in ../libx264.
Similar thing for the linker flags (assuming there's a libx264.a file in ../libx264), where you have to specify where the library is using the -L option:
LDFLAGS = -static -L../libx264 -lx264
Alternatively you could of course also write:
LDFLAGS = -static ../libx264/libx264.a
I have to do a makefile to compile something, but I got a problem : when I type the make command, I got an error message saying that there is no rules for one of the targets. The problem is about the path to the target, using an environment var.
Here is the given start of the Makefile :
CC = mipsel-unknown-elf-gcc
AS = mipsel-unknown-elf-as
LD = mipsel-unknown-elf-ld
DU = mipsel-unknown-elf-objdump
SYS_OBJS = reset.o \
giet.o \
common.o \
ctx_handler.o \
drivers.o \
exc_handler.o \
irq_handler.o \
sys_handler.o
APP_OBJS = stdio.o main.o
GIET ?= /(my path)/giet
SYS_PATH = $(GIET)/sys
APP_PATH = $(GIET)/app
SYS_CFLAGS = -Wall -ffreestanding -mno-gpopt -mips32 -I$(SYS_PATH) -I.
APP_CFLAGS = -Wall -ffreestanding -mno-gpopt -mips32 -I$(APP_PATH) -I.
all: sys.bin app.bin
(I am supposed to finish it)
What I tried to do (rule for sys.bin works fine) :
common.o: common.c
mipsel-unknown-elf-gcc $(SYS_CFLAGS) common.o $(SYS_PATH)/common.c
The command I'm using to compile myself is : mipsel-unknown-elf-gcc -ffreestanding -mno-gpopt -mips32 -I$GIET/sys -I. -c -o common.o $GIET/sys/common.c
Could you help me to fix this ?
Thanks :)
I don't see a -o (output file specifier) at the end of $(SYS_CFLAGS) or before the common.o in the command for your rule. That's the important difference between your makefile and your manual command.
Without that specifier, it will try to act on common.o rather than produce it, attempting to combine both common.o and $(SYS_PATH)/common.c into (most likely) a.out.
To fix it, change the rule to:
common.o: common.c
mipsel-unknown-elf-gcc $(SYS_CFLAGS) -o common.o $(SYS_PATH)/common.c
# ^^
# Add this bit here (but not these two comment lines).
I'm having trouble linking the sha library with my makefile while compiling.
Here is my makefile:
CFLAGS= -g -Wall -Werror -std=c99 -pedantic
LDFLAGS=-lssl -lcrypto
CC = gcc
LD = gcc
OBJS = dhtnode.o
PROG = dhtnode
.c.o:
gcc $< -o $# $(CFLAGS)
all: $(PROG)
$(PROG): $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) -o $(PROG)
dhtnode.o: dhtnode.c dhtpackettypes.h
$(CC) $(CFLAGS) $(LDFLAGS) dhtnode.c
clean:
/bin/rm -f *.o dhtnode
My function using the lcrypto library is here:
#include <openssl/sha.h>
#include <stdlib.h>
#include <stdin.h>
//there are other includes but not concerning this part of the code
char sha() {
char *ibuf = malloc(sizeof(char));
ibuf ="172.0.0.1:11112";
char *obuf = malloc(SHA_DIGEST_LENGTH);
SHA1((unsigned char*)ibuf, strlen(ibuf), (unsigned char*)obuf);
int i;
for (i = 0; i < 20; i++) {
printf("%x" , (unsigned char)obuf[i]);
}
printf("\n");
return *ibuf;
}
Here is the error I get when building with Eclipse:
C/p2p/dhtnode.c:107: undefined reference to `SHA1'
Can anybody tell my what is wrong with my makefile or possible eclipse settings?
Thx in advance!
When compiling the object file, you don't need the LDFLAGS. You'll also need the -c compiler flag to produce an object file instead of linking a binary:
dhtnode.o: dhtnode.c dhtpackettypes.h
$(CC) $(CFLAGS) -c dhtnode.c
After making this change, the program compiles and links successfully for me.
I am currently failing to write a good makefile and don't know the reason why.. -.-
This is my main.c:
#include <windows.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("MEEEEEP");
return (0);
}
This is my makefile:
# make SYSTEM= OS= ENVIRONMENT=
# Binaries to use
ifeq ($(ENVIRONMENT),MINGW)
CXX = i686-pc-mingw32-g++
else
CXX = g++
endif
REMOVE = rm -vf
RC = windres
EXE = .exe
#############################################################
# Info
ifeq ($(CXX),g++)
INFO_CXX = g++ -dumpversion; g++ -dumpmachine
endif
#############################################################
# Flags
DEBUG = -DDEBUG -g
OPTIMIZATION = -O2 #-Winline -finline-functions
CFLAGS = -Wall -Wextra -W -static $(DEBUG) $(OPTIMIZATION) -D$(SYSTEM) -D$(OS) -D$(ENVIRONMENT) $(PRGFLAGS)
ifeq ($(SYSTEM),I686)
CFLAGS += -m32
ifeq ($(OS),WIN32)
CFLAGS += -D_WIN32
endif
ifeq ($(ENVIRONMENT),MINGW)
CFLAGS += -fexceptions
endif
endif
LFLAGS =
#############################################################
# Files
CFILES = main.c
OBJS = ${CFILES:.c=.o}
#############################################################
# Include
INCLUDES = -I.
#############################################################
# Library
LIBRARIES =
#############################################################
# Targets
.PHONY: all
all:
#echo == Standard build: make SYSTEM=I686 OS=WIN32 ENVIRONMENT=MINGW
#echo
#echo
make SYSTEM=I686 OS=WIN32 ENVIRONMENT=MINGW gyro
#############################################################
# Implicit rules and filename extensions...
.SUFFIXES: .h .o .c
.c.o: %.h
#echo Compiling $< for $(SYSTEM) $(OS) $(ENVIRONMENT) ...
#echo MEEP
$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $#
#echo MEEP2
#############################################################
# Target rules
gyro: $(OBJS)
#echo Building software for $(SYSTEM) ...
#echo
$(CXX) $(CFLAGS) $(LFLAGS) -o $#$(EXE) $(OBJS) $(LIBRARIES)
#############################################################
# Clean
.PHONY: clean
clean:
$(REMOVE) $(OBJS)
#############################################################
# Info
.PHONY: info
info:
#echo
#echo Information about C++ Compiler/Linker:
#echo
$(INFO_CXX)
When i type in make gyro,
i receive the output:
Compiling main.c for Windows_NT ...
MEEP
g++ -Wall -Wextra -W -static -DDEBUG -g -O2 -D -DWindows_NT -D -I. -c main.c -o main.o
makeNew.mak:83: recipe for target `main.o' failed
make: *** [main.o] Error 1
But Line number 83 is behind .c.o: %.h. And i don’t understand why.
Does anyone have a solution for me?
You see the two empty -D entries in the g++ command line? They're causing the problem. You must have values in the -D items e.g. -DWIN32
if you're insistent on using something like -D$(SYSTEM) -D$(ENVIRONMENT) then you can use something like:
SYSTEM ?= generic
ENVIRONMENT ?= generic
in the makefile which gives them default values.
Your output looks to be missing the all important output:
<command-line>:0:1: error: macro names must be identifiers
<command-line>:0:1: error: macro names must be identifiers
just to clarify, what actually got sent to g++ was -D -DWindows_NT, i.e. define a preprocessor macro called -DWindows_NT; which is of course not a valid identifier (similarly for -D -I.)