दो सरल चाल का उपयोग कर ऑपरेटिंग सिस्टम का पता लगाएं:
- पहले पर्यावरण चर
OS
- फिर
uname
आज्ञा
ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10...
detected_OS := Windows
else
detected_OS := $(shell uname) # same as "uname -s"
endif
या अधिक सुरक्षित तरीका, यदि विंडोज पर uname
उपलब्ध नहीं है और अनुपलब्ध है:
ifeq ($(OS),Windows_NT)
detected_OS := Windows
else
detected_OS := $(shell sh -c 'uname 2>/dev/null || echo Unknown')
endif
यदि आप Cygwin / MinGW / MSYS / Windows को अलग करना चाहते हैं तो केन जैक्सन एक दिलचस्प विकल्प का प्रस्ताव करता है। उसका जवाब देखें जो इस तरह दिखता है:
ifeq '$(findstring ;,$(PATH))' ';'
detected_OS := Windows
else
detected_OS := $(shell uname 2>/dev/null || echo Unknown)
detected_OS := $(patsubst CYGWIN%,Cygwin,$(detected_OS))
detected_OS := $(patsubst MSYS%,MSYS,$(detected_OS))
detected_OS := $(patsubst MINGW%,MSYS,$(detected_OS))
endif
फिर आप संबंधित सामान का चयन कर सकते हैं detected_OS
:
ifeq ($(detected_OS),Windows)
CFLAGS += -D WIN32
endif
ifeq ($(detected_OS),Darwin) # Mac OS X
CFLAGS += -D OSX
endif
ifeq ($(detected_OS),Linux)
CFLAGS += -D LINUX
endif
ifeq ($(detected_OS),GNU) # Debian GNU Hurd
CFLAGS += -D GNU_HURD
endif
ifeq ($(detected_OS),GNU/kFreeBSD) # Debian kFreeBSD
CFLAGS += -D GNU_kFreeBSD
endif
ifeq ($(detected_OS),FreeBSD)
CFLAGS += -D FreeBSD
endif
ifeq ($(detected_OS),NetBSD)
CFLAGS += -D NetBSD
endif
ifeq ($(detected_OS),DragonFly)
CFLAGS += -D DragonFly
endif
ifeq ($(detected_OS),Haiku)
CFLAGS += -D Haiku
endif
टिप्पणियाँ:
आदेश uname
समान है uname -s
क्योंकि विकल्प -s
( --kernel-name
) डिफ़ॉल्ट है। देखें क्यों uname -s
की तुलना में बेहतर हैuname -o
।
OS
(के बजाय uname
) का उपयोग पहचान एल्गोरिथ्म को सरल करता है। आप अभी भी पूरी तरह से उपयोग कर सकते हैं uname
, लेकिन आपको if/else
सभी MinGW, Cygwin, आदि विविधताओं की जांच करने के लिए ब्लॉकों से निपटना होगा ।
पर्यावरण चर OS
हमेशा "Windows_NT"
अलग-अलग विंडोज संस्करणों पर सेट होता है ( %OS%
विकिपीडिया पर पर्यावरण चर देखें )।
OS
पर्यावरण चर का एक विकल्प है MSVC
(यह एमएस विज़ुअल स्टूडियो की उपस्थिति की जांच करता है , दृश्य सी ++ का उपयोग करके उदाहरण देखें )।
नीचे मैं एक साझा पुस्तकालय का उपयोग कर make
और एक पूर्ण उदाहरण प्रदान करता हूं gcc
: *.so
या *.dll
प्लेटफॉर्म पर निर्भर करता है। उदाहरण उतना ही सरल है जितना अधिक समझा जा सकता है।
विंडोज पर स्थापित करने make
और gcc
देखने के लिए Cygwin या MinGW देखें ।
मेरा उदाहरण पांच फाइलों पर आधारित है
├── lib
│ └── Makefile
│ └── hello.h
│ └── hello.c
└── app
└── Makefile
└── main.c
अनुस्मारक: सारणीकरणMakefile
का उपयोग करने के लिए प्रेरित किया जाता है । नमूना फ़ाइलों के नीचे कॉपी-पेस्ट करते समय सावधानी।
दो Makefile
फाइलें
1। lib/Makefile
ifeq ($(OS),Windows_NT)
uname_S := Windows
else
uname_S := $(shell uname -s)
endif
ifeq ($(uname_S), Windows)
target = hello.dll
endif
ifeq ($(uname_S), Linux)
target = libhello.so
endif
#ifeq ($(uname_S), .....) #See https://stackoverflow.com/a/27776822/938111
# target = .....
#endif
%.o: %.c
gcc -c $< -fPIC -o $@
# -c $< => $< is first file after ':' => Compile hello.c
# -fPIC => Position-Independent Code (required for shared lib)
# -o $@ => $@ is the target => Output file (-o) is hello.o
$(target): hello.o
gcc $^ -shared -o $@
# $^ => $^ expand to all prerequisites (after ':') => hello.o
# -shared => Generate shared library
# -o $@ => Output file (-o) is $@ (libhello.so or hello.dll)
2। app/Makefile
ifeq ($(OS),Windows_NT)
uname_S := Windows
else
uname_S := $(shell uname -s)
endif
ifeq ($(uname_S), Windows)
target = app.exe
endif
ifeq ($(uname_S), Linux)
target = app
endif
#ifeq ($(uname_S), .....) #See https://stackoverflow.com/a/27776822/938111
# target = .....
#endif
%.o: %.c
gcc -c $< -I ../lib -o $@
# -c $< => compile (-c) $< (first file after :) = main.c
# -I ../lib => search headers (*.h) in directory ../lib
# -o $@ => output file (-o) is $@ (target) = main.o
$(target): main.o
gcc $^ -L../lib -lhello -o $@
# $^ => $^ (all files after the :) = main.o (here only one file)
# -L../lib => look for libraries in directory ../lib
# -lhello => use shared library hello (libhello.so or hello.dll)
# -o $@ => output file (-o) is $@ (target) = "app.exe" or "app"
अधिक जानने के लिए, cfi द्वारा इंगित स्वचालित चर दस्तावेज़ पढ़ें ।
स्रोत कोड
- lib/hello.h
#ifndef HELLO_H_
#define HELLO_H_
const char* hello();
#endif
- lib/hello.c
#include "hello.h"
const char* hello()
{
return "hello";
}
- app/main.c
#include "hello.h" //hello()
#include <stdio.h> //puts()
int main()
{
const char* str = hello();
puts(str);
}
निर्माण
की कॉपी-पेस्ट को ठीक करें Makefile
(प्रमुख स्थानों को एक सारणीकरण द्वारा बदलें)।
> sed 's/^ */\t/' -i */Makefile
make
आदेश दोनों प्लेटफ़ॉर्म पर ही है। दिए गए आउटपुट यूनिक्स जैसे OSes पर है:
> make -C lib
make: Entering directory '/tmp/lib'
gcc -c hello.c -fPIC -o hello.o
# -c hello.c => hello.c is first file after ':' => Compile hello.c
# -fPIC => Position-Independent Code (required for shared lib)
# -o hello.o => hello.o is the target => Output file (-o) is hello.o
gcc hello.o -shared -o libhello.so
# hello.o => hello.o is the first after ':' => Link hello.o
# -shared => Generate shared library
# -o libhello.so => Output file (-o) is libhello.so (libhello.so or hello.dll)
make: Leaving directory '/tmp/lib'
> make -C app
make: Entering directory '/tmp/app'
gcc -c main.c -I ../lib -o main.o
# -c main.c => compile (-c) main.c (first file after :) = main.cpp
# -I ../lib => search headers (*.h) in directory ../lib
# -o main.o => output file (-o) is main.o (target) = main.o
gcc main.o -L../lib -lhello -o app
# main.o => main.o (all files after the :) = main.o (here only one file)
# -L../lib => look for libraries in directory ../lib
# -lhello => use shared library hello (libhello.so or hello.dll)
# -o app => output file (-o) is app.exe (target) = "app.exe" or "app"
make: Leaving directory '/tmp/app'
दौड़
आवेदन के लिए यह जानना आवश्यक है कि साझा पुस्तकालय कहां है।
विंडोज पर, एक सरल समाधान यह है कि लाइब्रेरी को कॉपी किया जाए जहां आवेदन है:
> cp -v lib/hello.dll app
`lib/hello.dll' -> `app/hello.dll'
यूनिक्स जैसे OSes पर, आप LD_LIBRARY_PATH
पर्यावरण चर का उपयोग कर सकते हैं :
> export LD_LIBRARY_PATH=lib
Windows पर कमांड चलाएँ:
> app/app.exe
hello
यूनिक्स की तरह OSes पर कमांड चलाएँ:
> app/app
hello
PROCESSOR_ARCHITECTURE
कि यह प्रक्रिया 32-बिट या 64-बिट के आधार पर एन्वारराइज की गई है। इसलिए यदि आपकाmake
32-बिट है और आप 64-बिट एप्लिकेशन बनाने का प्रयास कर रहे हैं, तो यह विफल हो जाएगा।PROCESSOR_ARCHITEW6432
मेरे साथ काम करने के संयोजन में इसका उपयोग करना ( यह देखें , और वह )