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).
Related
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 &
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'm trying to use powf function in an rtems application.
When I call powf(a,b); inside Init() function, it compiles ok.
But when I call powf in some other function, the compiler gives me 'undefined reference to powf' message even though I have those #include <math.h> and #include <float.h>. I event tried merging the file, but it is the same.
#define CONFIGURE_...
#define CONFIGURE_...
#include <rtems/confdefs.h>
rtems_task Init( rtems_task_argument ignored)
{
powf(a,b); // ok
}
int my_other_func()
{
powf(c,d); // undefined reference error..
}
What can be the problem?
EDIT(ADD) : I added source code and makefile below. The compiled rtems OS package is specified by shell environment variable RTEMS_MAKEFILE_PATH.
Makefile :
include ../Makefile.base
_RAM_START = 0x60000000
XCFLAGS = -qnolinkcmds -T ../../lib/linkcmds.abts3 -D_RAM_START=$(_RAM_START)
XCFLAGS += -lm -DALDEBARAN_RTEMS
../Makefile.base :
#
# RTEMS_MAKEFILE_PATH is typically set in an environment variable
#
PGM=${ARCH}/faster_rcnn.exe
# optional managers required
MANAGERS=all
# C source names
VPATH = ../src
VPATH += ../../../../abfrcnn/bare-c/lrn_layer
CSRCS = init.c
CSRCS += lrn_layer.c
CSRCS1 = $(notdir $(CSRCS))
COBJS_ = $(CSRCS1:.c=.o)
include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
#XCFLAGS += -I../../include
COBJS = $(COBJS_:%=${ARCH}/%)
OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)
#all: ${ARCH} $(PGM) RUNTCL
all: ${ARCH} $(PGM)
$(PGM): $(OBJS)
$(make-exe)
RUNTCL:
echo 'system_init' > run.tcl
echo 'load_image o-optimize/faster_rcnn.exe' >> run.tcl
echo 'run $(_RAM_START)' >> run.tcl
clean:
-$(RM) -r $(ARCH)
../src/init.c :
...
#include <math.h>
rtems_status Init(rtems_argument ignored)
{
...
printf(" pow(1.1,2.2) = %f\n", powf(1.1,2.2)); // <== powf compiles liks ok
//zf_coco();
}
../../../../abfrcnn/bare-c/lrn_layer/lrn_layer.c
#include <stdio.h>
#include <math.h>
int lrn_layer(... args... )
{
...
val = 1./powf((1.+a/(float)(k^2)*tmp),b); // method1
...
} // main ROI loop
The result of make command :
test -d o-optimize || mkdir o-optimize
sparc-ab-rtems-gcc --pipe -B/home/ckim/prj/abts/rtems-qt/rtems-4.10.99-kernel/build-rtems/rtems-package/sparc-ab-rtems/aldebaran2/lib/ -specs bsp_specs -qrtems -Wall -qnolinkcmds -T ../../lib/linkcmds.abts3 -D_RAM_START=0x60000000 -lm -DALDEBARAN_RTEMS -O4 -mtune=v8 -msoft-float -fcommon -DTARGET_ALDEBARAN -c -o o-optimize/init.o ../src/init.c
../src/init.c:120:2: warning: missing braces around initializer [-Wmissing-braces]
{0}, // rtems_chain_control;
^
../src/init.c:120:2: warning: (near initialization for 'ald_sd_card_driver_table[0].queue.Chain') [-Wmissing-braces]
sparc-ab-rtems-gcc --pipe -B/home/ckim/prj/abts/rtems-qt/rtems-4.10.99-kernel/build-rtems/rtems-package/sparc-ab-rtems/aldebaran2/lib/ -specs bsp_specs -qrtems -Wall -qnolinkcmds -T ../../lib/linkcmds.abts3 -D_RAM_START=0x60000000 -lm -DALDEBARAN_RTEMS -O4 -mtune=v8 -msoft-float -fcommon -DTARGET_ALDEBARAN -c -o o-optimize/lrn_layer.o ../../../../abfrcnn/bare-c/lrn_layer/lrn_layer.c
../../../../abfrcnn/bare-c/lrn_layer/lrn_layer.c: In function 'lrn_layer':
../../../../abfrcnn/bare-c/lrn_layer/lrn_layer.c:201:12: warning: 'w_idx' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (w_idx == w && h_idx == h) {
^
sparc-ab-rtems-gcc --pipe -B/home/ckim/prj/abts/rtems-qt/rtems-4.10.99-kernel/build-rtems/rtems-package/sparc-ab-rtems/aldebaran2/lib/ -specs bsp_specs -qrtems -Wall -qnolinkcmds -T ../../lib/linkcmds.abts3 -D_RAM_START=0x60000000 -lm -DALDEBARAN_RTEMS -O4 -mtune=v8 -msoft-float -fcommon -DTARGET_ALDEBARAN -L/opt/abde-rtems/lib/gcc/sparc-ab-rtems/4.8.2/soft -L/opt/abde-rtems/sparc-ab-rtems/lib/soft -mtune=v8 -msoft-float -fcommon -DTARGET_ALDEBARAN -o o-optimize/faster_rcnn.exe o-optimize/init.o o-optimize/lrn_layer.o
o-optimize/lrn_layer.o: In function `lrn_layer':
lrn_layer.c:(.text+0x4a8): undefined reference to `powf'
collect2: error: ld returned 1 exit status
make: *** [o-optimize/faster_rcnn.exe] Error 1
The compile process is composed of compilation of each individual .c files and final linking. I found somehow the -lm option which was added through XCFLAGS is being applied to the compilation command but not in the linking command. So I added -lm option in the object list so that that option is naturally following the object list in the link command. (I guess the proper way is to add -lm to the XLDFLAG because I found the variable in rtems build tree : extra LD flags). I'll try later..
OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS) -lm
I am trying to make a Makefile and I am getting errors:
make: * No rule to make target main.c, needed by main.o. Stop.
Can anyone explain why I am getting this error, or even suggest a fix if possible, Thank you.
TARGET = example
SRC_FILES = \
Makefile \
README \
a.c \
a.h \
b.c \
b.h \
main.c
OBJS = \
main.o \
a.o \
b.o
CC = gcc
CFLAGS = -g -Wall -std=c99
(TARGET): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $#
$(TARGET): $(TARGET).html $(TARGET).pdf
$(TARGET).html: $(TARGET).umt
$(UMT) $< >$#
$(TARGET).pdf: $(TARGET).html
$(HTML2PS) -N 0 -n $(TARGET).html > $(TARGET).ps
$(PS2PDF) $(TARGET).ps
rm -f $(TARGET).ps
clean:
rm -f $(TARGET).html $(TARGET).pdf
a.o: a.c a.h
b.o: b.c b.h
main.o: main.c a.h b.h
Deduplicator already explained why you are getting this error. Suggested fix: Provide a main.c, or change the file names in the make file to the names of the files you have (example.c maybe).
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.)