Makefile that distinguishes between Windows and Unix-like systems
I solved this by looking for an env variable that will only be set on windows.
ifdef OS
RM = del /Q
FixPath = $(subst /,\,$1)
else
ifeq ($(shell uname), Linux)
RM = rm -f
FixPath = $1
endif
endif
clean:
$(RM) $(call FixPath,objs/*)
Because %OS% is the type of windows, it should be set on all Windows computers but not on Linux.
The blocks then setups up variables for the different programs as well as a function for converting the forward slashes into backslashes.
You to have to use $(call FixPath,path) when you call an outside command (internal commands work fine). You could also use something like:
/ := /
and then
objs$(/)*
if you like that format better.
OS detecting makefile
There are many good answers here already, but I wanted to share a more complete example that both:
- doesn't assume
uname
exists on Windows - also detects the processor
The CCFLAGS defined here aren't necessarily recommended or ideal; they're just what the project to which I was adding OS/CPU auto-detection happened to be using.
ifeq ($(OS),Windows_NT)
CCFLAGS += -D WIN32
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
CCFLAGS += -D AMD64
else
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
CCFLAGS += -D AMD64
endif
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
CCFLAGS += -D IA32
endif
endif
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
CCFLAGS += -D LINUX
endif
ifeq ($(UNAME_S),Darwin)
CCFLAGS += -D OSX
endif
UNAME_P := $(shell uname -p)
ifeq ($(UNAME_P),x86_64)
CCFLAGS += -D AMD64
endif
ifneq ($(filter %86,$(UNAME_P)),)
CCFLAGS += -D IA32
endif
ifneq ($(filter arm%,$(UNAME_P)),)
CCFLAGS += -D ARM
endif
endif
tell if make is running on windows or linux
uname command should give you the basic info about the OS. Can you use that, and then make an IF based on the return value?
As not to rewrite everything, here - these two questions may be of some interest to you
1. OS detecting makefile
2. Makefile that distincts between Windows and Unix-like systems
How in 'make' check the current operating system is?
Simple add this in Makefile:
ifeq ($(UNAME_S),Linux)
OPCJE = -Wall -Wno-unused-const-variable
else
OPCJE = -Wall
endif
Use the same makefile for make (Linux) and nmake (Windows)
It's probably not impossible, but most likely so hard that it would be easier to write two makefiles anyway.
Both GNU make (used in Linux) and nmake have include directives though, so some common things can be put in a common makefile that is included by the main makefile.
Platform-dependent Makefile
Why not just use include
?
ifeq ($(OS),Windows_NT)
include Makefilewin
else
include MakefileLinux
endif
?
GNU makefile syntax for loop in windows
I made certain changes after reading nmake syntax. Now the problem is resolved.
The %: is not needed and @for does not work. So we need to turn off echo using @echo off: and then for loop will work with simple 'for' keyword instead of @for.
Working code is here:
SHELL = sh
# %:
@echo off :
for i in $(subdirs) ; \
do \
(cd $$i && $(MAKE) $@) || break; \
done
# eof
Can't check file existense in a makefile
Drop the quotes around the filename. They might be okay in bash or perl, but in a makefile, they are considered the first and last characters of the filename.
FILE = tact1.pdf
Related Topics
How to Create a Device Node from the Init_Module Code of a Linux Kernel Module
When Should I Use Tcp_Nodelay and When Tcp_Cork
Command Line Utility to Print Statistics of Numbers in Linux
What's the Point of Eval/Bash -C as Opposed to Just Evaluating a Variable
Bash Command Substitution on Remote Host
How to Get Child Process from Parent Process
Identify User in a Bash Script Called by Sudo
How to Pass a Wildcard Parameter to a Bash File
Extract Lines Between Two Patterns from a File
Using "$Random" to Generate a Random String in Bash
How to Find the Maximum Stack Size
What's the Purpose of Each of the Different Uids a Process Can Have
How to Configure Linux Capabilities Per User