Extraneous text after `else' directive - makefile

First
I reference gnu make manual 3.81, because my version is 3.81 (make --v)
section 7.2
conditional-directive
text-if-one-is-true
else conditional-directive
text-if-true
else
text-if-false
endif
so my makefile
version=ag101p
ifeq ($(version),ag101p)
ag101p:ag101p.o zigbee.o
cc -o $# $(CFLAGS) $^
else ifeq($(version),test)
#echo "test"
else
CFLAGS += -DM2C
m2c:m2c.o zigbee.o
cc -o $# $(CFLAGS) $^
endif
.PHONY:clean
clean:CLL
rm -rf *.o ag101p m2c
CLL:
but console display
Makefile:7: Extraneous text after `else' directive

By adding a space between "else ifeq" and "(" works on linux platform. But on windows it won't work. I fix this on windows by adding anther endif make the "if else" nested.
ifeq ($(version),ag101p)
ag101p:ag101p.o zigbee.o
cc -o $# $(CFLAGS) $^
else
ifeq ($(version),test)
#echo "test"
else
CFLAGS += -DM2C
m2c:m2c.o zigbee.o
cc -o $# $(CFLAGS) $^
endif
endif
.PHONY:clean
clean:CLL
rm -rf *.o ag101p m2c
CLL:

I run into the same issue. Solution: Install GNU version of make with Cygwin installer.

Related

BSD make & GNU make

I have Makefile. This runs on FreeBSD with gmake and make. In BSD Make command not output log same with gmake.
$ gmake
compile main.cpp
linking myout
$ make
c++ -O2 -pipe -c main.cpp -o main.o
linking myout
$ cat Makefile
TARGET = myout
default: $(TARGET)
SRCS = main.cpp
OBJS = $(SRCS:%.cpp=%.o)
default: $(BIN)
%.o: %.cpp
#echo compile $<
#$(CXX) -c $< -o $#
$(TARGET): $(OBJS)
#echo linking $#
#$(CXX) $(OBJS) -o $#
clean:
#rm -f $(OBJS) $(TARGET)
According to the FreeBSD make documentation, it doesn't support pattern rules. So your rule here:
%.o: %.cpp
#echo compile $<
#$(CXX) -c $< -o $#
in FreeBSD make is just an explicit rule telling make how to build the literal file %.o from the literal file %.cpp. Since you don't try to build a file named %.o (you're trying to build main.o), this rule is ignored / never used.
It looks like if you want something that will work the same way between both versions of make you'll have to restrict yourself to the POSIX standard suffix rules format, like this:
.SUFFIXES: .cpp .o
.cpp.o:
#echo compile $<
#$(CXX) -c $< -o $#
The default build utilities are different. FreeBSD uses a different implementation of make than GNU/Linux. The respective man pages outline differences.
https://forums.freebsd.org/threads/difference-gmake-gnu-and-freebsd-make.28784/

How to use source in my makefile while keep my previous makefile content

I am writing an makefile and I need to set up env.
I use source /opt/intel/oneapi/setvars.sh to set up my env but I want to make it in my Makefile.
I search for how to use source in Makefile and I learn to write this:
SHELL=/bin/bash
s:
source /opt/intel/oneapi/setvars.sh
CC = mpicc
OPT = -Ofast
CFLAGS = -Wall -std=c99 $(OPT) -fopenmp -march=native
LDFLAGS = -Wall -fopenmp
LDLIBS = $(LDFLAGS)
targets = benchmark-naive benchmark-omp benchmark-mpi
objects = check.o benchmark.o stencil-naive.o stencil-omp.o stencil-mpi.o
.PHONY : default
default : all
.PHONY : all
all : clean $(targets)
benchmark-naive : check.o benchmark.o stencil-naive.o
$(CC) -o $# $^ $(LDLIBS)
benchmark-omp : check.o benchmark.o stencil-omp.o
$(CC) -o $# $^ $(LDLIBS)
benchmark-mpi : check.o benchmark.o stencil-mpi.o
$(CC) -o $# $^ $(LDLIBS)
%.o : %.c common.h
$(CC) -c $(CFLAGS) $< -o $#
.PHONY: clean
clean:
rm -rf $(targets) $(objects)
But after run make it just load my env and do nothing. Can anyone help me to put my source in my makefile while keep my previous makefile content?
You have to call make with the env set recursively if it wasn't set:
ifndef <some test to see if env is missing>
%:
source /opt/intel/oneapi/setvars.sh $(MAKE) $(MAKECMDGOALS)
else
<normal makefile>
endif
You can look at the following makefile:
# makefile
all: prog
prog:
export ASD=asd
echo $$ASD
export ASD=asd; echo $$ASD
The output is:
export ASD=asd
echo $ASD
export ASD=asd; echo $ASD
asd
A makefile is not a bash script. 'make' is processing a makefile and it creates a child process for each line to run a shell to execute the statements. The variable that you set in a line is only valid for that child process, it will not be inherited back to the parent or to subsequent child processes.
I know this does not solve your issue, but at least it is some kind of an explanation why it does not work.
Can you try this :
SHELL=/bin/bash --rcfile /opt/intel/oneapi/setvars.sh

make wildcard target always get Nothing to be done

I wrote a makefile which contains some wildcard target for building and running.
My makefile contents are the following.
ALL_EXES=$(shell ls *.exe 2>/dev/null)
.PHONY: all clean $(ALL_EXES) foo
CC=gcc
CFLAGS=-g -Wall
GTKFLAGS=$(shell pkg-config --cflags gtk+-3.0)
GTKLIBS=$(shell pkg-config --libs gtk+-3.0)
PWD=$(shell pwd)
clean:
#echo cleanning
$(shell sh -c "rm *.exe 2>/dev/null")
%: %.c
$(CC) $(GTKFLAGS) -o $# $< $(GTKLIBS) $(CFLAGS)
%.exe: %
#echo running $#
$(shell sh -c "$(PWD)/$#")
I can run make some-program successfully, but Nothing to be done for 'some-program.exe' is always occurs when I run make some-program.exe.
The line %: %.c should be %.exe: %.c , because that is the rule for creating a .exe file based on a .c source.
The line %.exe: % should be something else, e.g. run: foo.exe .
Finally, my workaround makefile is the followings.
ALL_EXES=$(shell ls *.exe 2>/dev/null)
.PHONY: all clean
CC=gcc
CFLAGS=-g -Wall
GTKFLAGS=$(shell pkg-config --cflags gtk+-3.0)
GTKLIBS=$(shell pkg-config --libs gtk+-3.0)
PWD=$(shell pwd)
clean:
#echo cleanning $(shell ls *.exe 2>/dev/null)
$(shell sh -c "rm *.exe 2>/dev/null")
%.exe: %.c
#echo building $<
$(CC) $(GTKFLAGS) -o $# $< $(GTKLIBS) $(CFLAGS)
run_%.exe: %.exe
#echo running $<
$(PWD)/$<
example-stack.exe: example-stack.c stack.c
$(CC) -I. -o $# $^ $(CFLAGS)

Quiet makefile not working

So I've a recursive makefile that's on a project, but for some reason, AR is the only command that still prints output.
How can I force it to be quiet? It has already '#' at the beginning, and I don't want to pipe the output to null.
How i'm calling this makefile?
#cd libc; make clean --no-print-directory
Here's the troublemaker makefile:
include ../Makefile.inc
LIB=../libc.a
SOURCES=$(wildcard *.c)
SOURCES_ASM=$(wildcard asm/*.asm)
OBJECTS=$(SOURCES:.c=.o)
OBJECTS_ASM=$(SOURCES_ASM:.asm=.o)
all: $(LIB)
#echo -e " libC [ \033[0;32mOK \033[0m]"
$(LIB): $(OBJECTS) $(OBJECTS_ASM)
#$(AR) $(ARFLAGS) -c $(LIB) $(OBJECTS_ASM) $(OBJECTS)
$(OBJECTS): $(SOURCES)
$(OBJECTS_ASM): $(SOURCES_ASM)
%.o: %.c
#$(GCC) $(GCCFLAGS) -c $< -o $#
%.o: %.asm
#$(ASM) $(ASMFLAGS) $< -o $#
clean:
#rm -rf *.o ../*.a
.PHONY:
all clean
and here's the output:
a - asm/syscall.o
a - syscall.o
a - string.o
a - stdio.o
a - integer.o
libC [ OK ]
Thanks in advance
If you don't want ar to print output then stop telling it to do so! :)
Since you haven't shown any setting for ARFLAGS I assume you're using the default value, which in GNU make is rv and the v flag means "verbose" (see man ar).
So, just setting:
ARFLAGS = r
in your makefile should turn off the verbose output from ar.
I suggest you to simply redirect the stdout to a log file for AR command only, as follows:
#$(AR) $(ARFLAGS) -c $(LIB) $(OBJECTS_ASM) $(OBJECTS) >> $(LOG_FILE)
It keeps the errors displayed because it does not redirect stderr.

Makefile problems with gcc flags (file not recognized; shared libraries)

I'm a little confused now. I'm trying to get the Makefile work but it breaks. I Hope someone can help me with this bad and frustrating time-killer.
I've written a small and lightweight part of a Compiler.
The project has the following structure:
/Compiler.cpp
/Makefile
/Buffer/
/Buffer/Makefile
/Scanner/
/Scanner/Makefile
/SymTable/
/SymTable/Makefile
When I'm compiling Buffer, Scanner and SymTable manual (changing the directory and typing 'make mode=release' it's no problem and each shared-library is compiled). But when I run the Makefile from within where the 'Master Makefile' /Makefile is, it fails and the terminal prints something like:
Buffer/libBuffer.so: file not recognized: File format not recognized
collect2: ld returned 1 exit status
make: \*** [Compiler] Error 1
Here is the listing of the Makefile of /Buffer/Makefile (the same for Scanner and SymTable):
CXX = g++
ifeq ($(mode),release)
CXXFLAGS = -g -fPIC -O3 -ffunction-sections -march=native
else
mode = debug
CXXFLAGS = -g3
endif
MODUL = Buffer
COMPONENTS = Buffer.h
MK_LIBRARY = lib$(MODUL).so
all: $(MK_LIBRARY)
$(MK_LIBRARY): $(COMPONENTS)
$(CXX) $(CXXFLAGS) -shared -o $# $^
clean:
rm -f $(MK_LIBRARY)
.PHONY: all
.PHONY: clean
The 'Master Makefile' looks like:
CXX = g++
ifeq ($(mode),release)
CXXFLAGS = -g -O3 -ffunction-sections -fwhole-program -march=native
else
mode = debug
CXXFLAGS = -g3
endif
TARGET = Compiler
COMPONENTS = $(TARGET)
DIRS = Buffer Scanner SymTable
MAKE = make
MFLAGS = mode=$(mode)
all: $(COMPONENTS)
$(TARGET): Compiler.cpp libBuffer.so libScanner.so libSymTable.so
$(CXX) $(CXXFLAGS) -IBuffer -IScanner -ISymTable \
-LBuffer -LScanner -LSymTable \
-lBuffer -lScanner -lSymTable -o $# Compiler.cpp
libBuffer.so: force_look
cd Buffer; $(MAKE) $(MFLAGS)
libScanner.so: force_look
cd Scanner; $(MAKE) $(MFLAGS)
libSymTable.so: force_look
cd SymTable; $(MAKE) $(MFLAGS)
clean:
rm -f $(COMPONENTS)
#for d in $(DIRS); do (cd $$d; $(MAKE) clean ); done
check:
#for d in $(DIRS); do (cd $$d; $(MAKE) check ); done
force_look:
true
.PHONY: all
.PHONY: clean
.PHONY: check
I hope some has an answer for me! Thanks!
There's something very weird about this part:
MODUL = Buffer
COMPONENTS = Buffer.h
MK_LIBRARY = lib$(MODUL).so
$(MK_LIBRARY): $(COMPONENTS)
$(CXX) $(CXXFLAGS) -shared -o $# $^
This rule tries to build libBuffer.so out of Buffer.h, the header file. How can this possibly work, without the definitions of the things in Buffer.cc? I would do it this way:
lib%.so: %.o
$(CXX) $(CXXFLAGS) -shared -o $# $^
EDIT:
You have the definitions of Buffer in Buffer.h? All right, you have more than one problem, and the only way to solve them is to do what almost always works: retreat to a simpler problem and solve that first. Can you make Buffer.o? And can you then link that into your executable (bypassing libBuffer.so)? And if not, can you write a "HelloWorld" in Buffer/, and link Buffer.o into that?

Resources