I have attached the sample of the make file.
# SELECT TARGET OPERATING SYSTEM
override OS = LINUX
#OS = WINDOWS
CC = gcc
SRC_DIR = src
INC_DIR = inc
OBJ_DIR = obj
CFLAGS = -c -Wall -I$(INC_DIR)
# CONDITIONAL COMPILATION
ifeq ($(OS), "WINDOWS")
SERIAL = Winsrcfile
CLEAR = cls
endif
ifeq ($(OS), "LINUX")
SERIAL = Linsrcfile
CLEAR = clear
endif
I am trying to achieve this...
make OS=WINDOWS // compile for windows
or
make OS=LINUX // compile for linux
from linux shell or windows command prompt and want default to be linux, if OS is not specified while executing 'make'. But the ifeq returns false in both cases, generating an error 'No rule to make target'. I read override directive & conditional syntax but it seems i havent got a clear idea of it. I have tried every alternate syntax of conditional syntax. But get error 'invalid syntax in conditional. Stop'
Make doesn't distinguish quotation marks. What you should do instead is:
ifeq ($(OS),LINUX)
# do stuff
endif
What's actually done here is that the arguments are expanded and then compared literally. $(OS) expands to the value of the variable and LINUX expands to LINUX. Your example would for example require make OS='"Linux"' in order to work
Related
I've been given a makefile for ubuntu, and I'm trying to use it with nmake on Windows 10.
nmake doesn't seem to recognize the filter-out keyword such as in the following line:
OBJS_TEST = $(filter-out $(EXE_OBJ), $(OBJS))
Does nmake have a keyword with the same functionality?
For completeness, the lines from the beginning of the file before the above line (and a few lines below) are as follows:
EXE = main
TEST = test
OBJS_DIR = .objs
###############################################
### THE LINE IN QUESTION IS BELOW #############
OBJS_TEST = $(filter-out $(EXE_OBJ), $(OBJS))
###############################################
CPP_TEST = $(wildcard tests/*.cpp)
# CPP_TEST += uiuc/catch/catchmain.cpp
# The above line doesn't work with the "+=" extension in nmake; replace with below.
CPP_TEST = $(CPP_TEST) $(wildcard tests/*.cpp)
The error reported is:
fatal error U1001: syntax error : illegal character '-' in macro
As far as I'm aware there is no equivalent to filter-out in nmake. Also, nmake does not support the wildcard function so you'll have to deal with that. And, I'm suspicious that your replacement for += won't work; in most versions of POSIX make FOO = $(FOO) is illegal as it gives an infinite loop of variable lookup. Maybe nmake works differently, though.
nmake is SO different from POSIX make and GNU make that you will either have to rewrite the makefile from scratch, or else just go get a version of GNU make for Windows (or build it yourself). GNU make is quite portable and runs well on Windows. That would be a LOT less work.
I am using makefile to build my program in multiple system. Some system have installed colorgcc script. In my Makefile i want to check, if script exists
and depending on it i setting up CC variable. But my Makefile don't work correctly - in system, that haven't colorgcc, make always set $(CC) as colorgcc. Here's part of Makefile:
ifneq ("$(wildchar /usr/bin/colorgcc)","")
CC=colorgcc
else
CC=gcc
endif
I also tried to use this variant:
ifeq ( $(shell test -e /usr/bin/colorgcc), )
CC=colorgcc
else
CC=gcc
endif
In both case $(CC) doesn't depend of existence file /usr/bin/colorgcc
How can i solve my problem?
In the first case, you mistyped the function $(wildcard ...) so you get nothing, always.
In the second case, the output of test is always the empty string. It will set its exit code depending on whether the condition is true or not, but you are not examining its exit code, just the output it prints, which will always be nothing at all.
I am using a makefile to control the compilation of my project. At the start of my Makefile, I have:
ifdef PIXEL
CFLAGS += -DBY_PIXEL
else
ifdef LINE
CFLAGS += -DBY_LINE
else
ifdef BLOCK
CFLAGS += -DBY_BLOCK
else
CFLAGS += -DBY_PIXEL (HERE)
endif
endif
endif
I have the error "No rule to make target XXX" where XXX is PIXEL, LINE or BLOCK. However when I don't write any parameter, it finds the target in the last else (where I put (HERE).
I dont fully understand why but I don't often write Makefile. Do you guys have an idea about it?
To specify a variable for make, set it to a value after the make command. For example, make PIXEL=foo build
I'm trying to use a commandline var to choose the toolkit we use to compile. When in command line I use a line like:
make all-arm OUR_TOOLKIT=1
And, in every makefile implied, i put this include
include ARM_Compiler.inc
Then, in every makefile,
all: setToolkit $(otherOperations)
And the contents of ARM_Compiler are the logic to choose the compiler:
setToolkit:
ifdef OUR_TOOLKIT
TOOLKIT=1
endif
ifdef CUSTOMER_TOOLKIT
TOOLKIT=2
endif
ifeq ($(TOOLKIT), 1)
$(info "=========Our toolkit selected======================")
rm=/bin/rm -f
CC= arm-linux-c++ -fPIC
CXX= arm-linux-c++ -fPIC
LINK= arm-linux-c++ -shared -Wl
AR= ar cq
RANLIB= ranlib
STRIP=arm-linux-strip
# para que se utilicen las herramientas y librerias del cross compiler
PATH:=$(PATH):/path/to/our/toolkit
LD_LIBRAY_PATH:=$(LD_LIBRAY_PATH):/path/to/our/toolkit
endif
ifeq ($(TOOLKIT), 2)
$(info "================Customer toolkit selected====================")
rm=/bin/rm -f
CC= arm-none-linux-gnueabi-c++ -fPIC
CXX= arm-none-linux-gnueabi-c++ -fPIC
LINK= arm-none-linux-gnueabi-c++ -shared -Wl
AR= ar cq
RANLIB= ranlib
STRIP= arm-none-linux-gnueabi-strip
# para que se utilicen las herramientas y librerias del cross compiler
PATH:=$(PATH):/path/to/other/toolkit
LD_LIBRAY_PATH:=$(LD_LIBRAY_PATH):/path/to/other/toolkit
endif
Thanks to the help of 0A0D, I discovered that TOOLKIT value is always empty. I've changed the code a little. Now the problem is that make throws the error
../makefile-includes/ARM-compiler.inc:10: *** commands commence before first target
at this line:
ifeq ($(TOOLKIT), 1)
Anyone has some idea?
Thanks
Variants of this question come up a lot.
Each command executes in its own subshell; a variable set in one command cannot be used in another.
But you can set variables outside the rules: just remove all of the leading TABs from your conditional statements above. This will work for everything except PATH and LD_LIBRARY_PATH. Neither of these is, in my opinion, something that Make should mess with, but there are ways to get the effect you want. You could handle PATH like this:
ifeq ($(TOOLKIT), 1)
TOOLKITPATH = /path/to/our/toolkit
endif
...
sometarget:
$(TOOLKITPATH)/sometool somearg
Or like this:
all:
export PATH=$$PATH:$(TOOLKITPATH) ; $(MAKE) $(otherOperations)
And you probably shouldn't use LD_LIBRARY_PATH at all.
I am trying to build a shared library with one set of code, and everything works, except for this issue with my Makefile. Here's my (simplified) Makefile thus far:
OBJS = bar.o
libfoo.so: OS = LINUX # These don't seem to happen
libfoo.dll: OS = WINDOWS
# Linux
ifeq ($(OS), LINUX)
CC = gcc
...
# Windows
else ifeq ($(OS), WINDOWS)
CC = i686-pc-mingw32-gcc
...
endif
all: libfoo.so libfoo.dll
libfoo.so: clean $(OBJS)
...
libfoo.dll: clean $(OBJS)
...
bar.o: bar_$(OS).c bar.h
...
So, when you type make libfoo.so, I expect it to set OS = LINUX first. Then, when it gets to bar.o (it is a dependency of libfoo) it should know which bar_$(OS).c to use. However, I get the error:
make: *** No rule to make target `bar_.c', needed by bar.o. Stop.
Which tells me that when it tries to make bar.o, $(OS) is not set. But shouldn't that be the first thing that happens when I try to make libfoo.so, and that rule is evaluated?
Target-specific variables are available in the body of the rule, not in its prerequisites. But even if you could get this to work, you'd be asking for trouble: if you build one library and then the other, there's no way for Make to know that the bar.o that was made for the first is wrong for the second and should not be used.
There are several ways to get the effect you want, but none is perfect. I'd suggest using two different object file names, like bar_unix.o and bar_windows.o.
If you want to set a target-specific variable, and then have that variable available outside the body of that rule, you can recursively call the Makefile, after exporting the variable:
OBJS ?= foo.o # Use ? so it isn't blown away on recursive call
libfoo.so: OS = LINUX
libfoo.so: OBJS += linux_only.o
libfoo.so:
$(MAKE) -s build_libfoo_linux
build_libfoo_linux: $(OBJS)
#echo "OS = $(OS)" # Should print "OS = LINUX"
export OS # Can be anywhere
You have to remember to export the variables you want to "persist" after the recursive make call. And also, as shown above, if you append to any variables before the call, you'll want to make their initial assignment with ?= so they aren't set the second time.
You might want to detect the OS using uname and then conditionally compile. This explains