ওএস মেকফিল সনাক্ত করছে


249

আমি নিয়মিতভাবে বিভিন্ন কম্পিউটার এবং বিভিন্ন অপারেটিং সিস্টেমগুলিতে কাজ করি যা ম্যাক ওএস এক্স, লিনাক্স বা সোলারিস। যে প্রকল্পে আমি কাজ করছি তার জন্য আমি আমার কোডটি একটি দূরবর্তী গিট সংগ্রহস্থল থেকে টানছি।

আমি কোন প্রকল্পে থাকি তা নির্বিশেষে আমার প্রকল্পগুলিতে কাজ করতে সক্ষম হতে চাই। এখনও অবধি, আমি যতবার কম্পিউটার স্যুইচ করেছি প্রতিবার মেকফিল পরিবর্তন করে ওএসের পরিবর্তনগুলি ঘটার উপায় খুঁজে পেয়েছি। তবে এটি ক্লান্তিকর এবং মাথা ব্যাথার একগুচ্ছ কারণ হয়ে দাঁড়ায়।

আমি কীভাবে আমার মেকফিলটি সংশোধন করতে পারি যাতে এটি সনাক্ত করে যে আমি কোন ওএস ব্যবহার করছি এবং সেই অনুযায়ী বাক্য গঠনটি সংশোধন করে?

এই মেকফাইলটি এখানে:

cc = gcc -g
CC = g++ -g
yacc=$(YACC)
lex=$(FLEX)

all: assembler

assembler: y.tab.o lex.yy.o
        $(CC) -o assembler y.tab.o lex.yy.o -ll -l y

assembler.o: assembler.c
        $(cc) -o assembler.o assembler.c

y.tab.o: assem.y
        $(yacc) -d assem.y
        $(CC) -c y.tab.c

lex.yy.o: assem.l
        $(lex) assem.l
        $(cc) -c lex.yy.c

clean:
        rm -f lex.yy.c y.tab.c y.tab.h assembler *.o *.tmp *.debug *.acts

উত্তর:


282

এখানে ইতিমধ্যে অনেক ভাল উত্তর রয়েছে তবে আমি আরও একটি সম্পূর্ণ উদাহরণ ভাগ করতে চেয়েছিলাম যে উভয়:

  • ধরে unameনেই উইন্ডোজে উপস্থিত রয়েছে
  • প্রসেসর সনাক্ত করে

এখানে সংজ্ঞায়িত সিসিএফএলএগএস প্রয়োজনীয়ভাবে প্রস্তাবিত বা আদর্শ নয়; তারা ঠিক সেই প্রকল্পটিতে আমি ওএস / সিপিইউ স্বয়ংক্রিয় সনাক্তকরণ যুক্ত করছিলাম 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

8
দুর্ভাগ্যক্রমে PROCESSOR_ARCHITECTUREenvvar প্রক্রিয়াটি 32-বিট বা 64-বিট কিনা তার উপর নির্ভর করে ভার্চুয়ালাইজড বলে মনে হচ্ছে। সুতরাং যদি আপনার make32-বিট হয় এবং আপনি একটি 64-বিট অ্যাপ্লিকেশন তৈরি করার চেষ্টা করছেন, এটি ব্যর্থ হবে। একযোগে এটা ব্যবহার করে PROCESSOR_ARCHITEW6432আমার জন্য কাজ (দেখুন এই , এবং যে )
থমাস

4
চমৎকার যদি হতে চান makeদলের OS দিয়ে জাদু ভেরিয়েবল দুয়েক সম্ভবত খুব কষ্ট জুড়তে এবং খিলান,।
অ্যালেক্স

6
@ জানুস ট্রেলসন: OSউইন্ডোজ নন সিস্টেমগুলিতে সেট করা আছে কিনা তা বিবেচ্য নয় । ট্রিটগুলি খালি হিসাবে একই সেট না করে রাখুন, যা unameবেসড ব্লকে ঝাঁপ দেবে । আপনাকে কেবল সেখানে একটি ফ্রিবিএসডি চেক যুক্ত করতে হবে।
ট্রেভর রবিনসন

3
এটি ওক্সেও ভেঙে যায়। /bin/sh: -c: line 0: syntax error near unexpected token , উইন্ডোজ_এনটি '/ বিন / শ: -সি: লাইন 0:ifeq (,Windows_NT)' make: *** [os] Error 2
107

1
@ ক্রিস্টি মনে হচ্ছে আপনি এটি শেল কমান্ড হিসাবে চালিয়েছেন, মেকফিল নির্দেশের প্রসঙ্গে নয়।
ফোর্ড

119

আনম কমান্ড ( http://developer.apple.com/docamentation/Darwin/References/ManPages/man1/uname.1.htmlকোনও প্যারামিটারযুক্ত ) আপনাকে অপারেটিং সিস্টেমের নামটি জানাতে হবে না। আমি এটি ব্যবহার করব, তারপরে রিটার্ন মানের উপর ভিত্তি করে শর্ত তৈরি করব।

উদাহরণ

UNAME := $(shell uname)

ifeq ($(UNAME), Linux)
# do something Linux-y
endif
ifeq ($(UNAME), Solaris)
# do something Solaris-y
endif

কেবল স্পষ্ট করে বলতে গেলে, সেই লাইনটি আপনার মেকফাইলে যায়। আমি কেবল সাইগউইন এবং ওএসএক্সে মেকফিলগুলিতে নির্মাণের চেষ্টা করেছি এবং এটি প্রত্যাশা অনুযায়ী কাজ করেছে। চেষ্টা করার কিছু: আপনার কমান্ড লাইনে আনম টাইপ করুন। এটি আপনাকে সেই ওএসের মান বলবে। ওএসএক্স সম্ভবত "ডারউইন" হবে।
dbrown0708

GnuWin32 প্রকল্পে উভয় অজানা এবং Gnu স্থানীয় উইন্ডোজ অ্যাপ্লিকেশন হিসাবে উপলব্ধ করে তোলে, এই কৌশলটি উইন্ডোজের কমান্ড প্রম্পটে মিংডাব্লু-তে পাশাপাশি সাইগউইনকে বহনযোগ্য করে তোলে।
আরবেরটিগ

মেকফিলের অভ্যন্তরে এটি আমার সোলারিস মেশিনে ব্যর্থ হয়। Uname কমান্ড সেই সিস্টেমে উপলব্ধ।
সামোজ 21

4
মনে রাখবেন যে আপনি এটি কোনও মেকেরেজেটের ভিতরে রাখলে তা অবশ্যই যুক্ত হয় না।
নিলুন্ড

4
": =" সিনট্যাক্সটি কি জিএনইউ মেকের সাথে নির্দিষ্ট নয়?
অঙ্কুর শেঠি

40

দুটি সহজ কৌশল ব্যবহার করে অপারেটিং সিস্টেমটি সনাক্ত করুন:

  • প্রথমে পরিবেশ পরিবর্তনশীল 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

আপনি যদি সাইগউইন / মিনজিডাব্লু / এমএসওয়াইএস / উইন্ডোজকে আলাদা করতে চান তবে কেন জ্যাকসন একটি আকর্ষণীয় বিকল্প প্রস্তাব করেছেন। তার উত্তর দেখুন যা দেখতে দেখতে:

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 -suname -o দেখুন ।

  • OS(পরিবর্তে uname) এর ব্যবহার সনাক্তকরণ অ্যালগরিদমকে সহজতর করে। আপনি এখনও সম্পূর্ণরূপে ব্যবহার করতে পারেন unameতবে if/elseসমস্ত মিনিজিডাব্লু, সাইগউইন ইত্যাদির বিভিন্নতা পরীক্ষা করতে আপনাকে ব্লকগুলি মোকাবেলা করতে হবে।

  • পরিবেশের পরিবর্তনশীল OSসর্বদা "Windows_NT"বিভিন্ন উইন্ডোজ সংস্করণে সেট করা থাকে ( %OS%উইকিপিডিয়ায় পরিবেশ পরিবর্তনশীল দেখুন )।

  • এর বিকল্প OSহ'ল পরিবেশ পরিবর্তনশীল MSVC(এটি এমএস ভিজ্যুয়াল স্টুডিওর উপস্থিতি পরীক্ষা করে , ভিজ্যুয়াল সি ++ ব্যবহার করে উদাহরণ দেখুন )।


নীচে আমি ব্যবহার করে makeএবং gccএকটি ভাগ করা লাইব্রেরি তৈরি করতে একটি সম্পূর্ণ উদাহরণ সরবরাহ করি : *.soবা *.dllপ্ল্যাটফর্মের উপর নির্ভর করে। আরও বোধগম্য হওয়ার উদাহরণটি যতটা সম্ভব সহজ।

উইন্ডোজ ইনস্টল করতে makeএবং সাইগউইন বা মিনজিডাব্লু দেখুনgcc

আমার উদাহরণ পাঁচটি ফাইলের উপর ভিত্তি করে

 ├── 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"

আরও জানতে, সিএফআই দ্বারা নির্দেশিত হিসাবে স্বয়ংক্রিয় চলক ডকুমেন্টেশন পড়ুন

উত্স কোড

- 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কমান্ড উভয় প্ল্যাটফর্মের উপর একই। প্রদত্ত আউটপুটটি ইউনিক্স-এর মতো ওএসগুলিতে রয়েছে:

> 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'

ইউনিক্সের মতো ওএসে, আপনি LD_LIBRARY_PATHপরিবেশের পরিবর্তনশীলটি ব্যবহার করতে পারেন :

> export LD_LIBRARY_PATH=lib

উইন্ডোতে কমান্ডটি চালান:

> app/app.exe
hello

ইউনিক্সের মতো ওএসে কমান্ডটি চালান:

> app/app
hello

আমি আপনার প্রচেষ্টার প্রশংসা করি, তবে মূল প্রশ্নটি ছিল অপারেটিং সিস্টেমটি সনাক্ত করা। আপনার উদাহরণটি কেবল লিনাক্স সনাক্ত করে এবং অন্যথায় সরাসরি উইন্ডোজকে ধরে নেয়।
শাহবাজ

হাই @ শাহবাজ আপনি ঠিক বলেছেন, আমার উত্তর অন্যান্য উত্তরগুলির চেয়ে আলাদা দৃষ্টিভঙ্গি দেয় না। তদুপরি, আমার স্ক্রিপ্টটি ধরে নেয় প্ল্যাটফর্মটি উইন্ডোজ যখন unameলিনাক্স নয়। আমি কেবল একটি উদাহরণ দিচ্ছি যা আপনার প্রয়োজন নাও পারে তবে এটি কাউকে Makefileউভয় প্ল্যাটফর্মের জন্য প্রয়োগ করার উপায় (ওয়েবে) সন্ধান করতে সহায়তা করতে পারে ;-) আমার উত্তরে আমার কী পরিবর্তন করা উচিত? চিয়ার্স
ওলিব্রে

অন্যান্য অপারেটিং সিস্টেমগুলিও সঠিকভাবে চিহ্নিত করার উপায়গুলি নিয়ে আসার চেষ্টা করুন! লক্ষ্যটি এমন একটি পদ্ধতি সন্ধান করা যা খুব জটিল নয় তবে আরও গুরুত্বপূর্ণভাবে বুলেট প্রুফ। অর্থাত্, এটি যাই হোক না কেন ভুল করবে না।
শাহবাজ

1
@ অলিবিরে বিস্তারিত উদাহরণের জন্য ধন্যবাদ, অনেক প্রশংসা করেছে এবং আমাকে দ্রুত শুরু করতে সহায়তা করে। ইন lib/Makefileউদাহরণস্বরূপ, targetজন্য ব্যবহার করা হয় .soবনাম .dll। এর জন্য একটি সমান্তরাল উদাহরণ অ্যাপ্লিকেশন ফাইল app/makefileনামের তুলনায় empty stringবনাম .exeতুলনায় কার্যকর হবে। উদাহরণস্বরূপ, আমি সাধারণত app.exeইউনিক্স-এর মতো ওএসে দেখতে পাই না । ;-)

1
LSF? LFS? ভুল টাইপ করেছেন?
ফ্রাঙ্কলিন ইউ

19

আমি নিজেকে জিজ্ঞাসা করছি এই প্রশ্নের উত্তর দেওয়ার জন্য আমি সম্প্রতি পরীক্ষা-নিরীক্ষা করছিলাম। আমার সিদ্ধান্তগুলি এখানে:

উইন্ডোজে যেহেতু আপনি নিশ্চিত হতে পারবেন না যে unameকমান্ডটি উপলব্ধ, আপনি ব্যবহার করতে পারেন gcc -dumpmachine। এটি সংকলক লক্ষ্য প্রদর্শন করবে।

unameআপনি কিছু ক্রস সংকলন করতে চাইলে ব্যবহার করার সময়ও সমস্যা হতে পারে ।

এর সম্ভাব্য আউটপুটটির উদাহরণের তালিকা এখানে রয়েছে gcc -dumpmachine:

  • mingw32
  • i686-পিসি cygwin
  • , x86_64-system-লিনাক্স

আপনি এইভাবে মেকফিলের ফলাফলটি পরীক্ষা করতে পারেন:

SYS := $(shell gcc -dumpmachine)
ifneq (, $(findstring linux, $(SYS)))
 # Do Linux things
else ifneq(, $(findstring mingw, $(SYS)))
 # Do MinGW things
else ifneq(, $(findstring cygwin, $(SYS)))
 # Do Cygwin things
else
 # Do things for others
endif

এটি আমার পক্ষে ভাল কাজ করেছে, তবে আমি নিশ্চিত না যে এটি সিস্টেমের ধরণের পাওয়ার একটি নির্ভরযোগ্য উপায়। কমপক্ষে এটি মিনিজিডাব্লু সম্পর্কে নির্ভরযোগ্য এবং উইন্ডোজে unameকমান্ড বা এমএসওয়াইএস প্যাকেজ থাকা দরকার না বলে এটিই আমার প্রয়োজন ।

যোগফল করার জন্য, unameআপনি সিস্টেম দেয় উপর আপনি কম্পাইল করছি যা, এবং gcc -dumpmachineআপনি সিস্টেম দেয় জন্য যা আপনি কম্পাইল করা হয়।


এটি একটি ভালো দিক. যাইহোক, না unameসঙ্গে আসা MinGWযাহাই হউক না কেন? তবুও, ক্রস সংকলন সম্পর্কিত অতিরিক্ত নোট দুর্দান্ত।
শাহবাজ

2
@ শাহবাজ মিনজিডাব্লু সেটআপটি এমএসওয়াইএস ইনস্টল করতে পারে (এতে নাম নেই) তবে এটি nচ্ছিক। কেবলমাত্র
মিনিজিডব্লু জিসিসি

1
এটি কোথাও কাজ করে না ওএস এক্স এবং ফ্রিবিএসডি এর মতো ক্ল্যাং হ'ল ডিফল্ট সংকলক।
মার্কাসজে

@ সেবাস্তিয়ানগোডলেট @ মারকাসজে একটি সহজ ফিক্স $(shell $(CC) -dumpmachine)। ওএস এক্স সিয়েরা হিসাবে, -ডাম্পমাছাইন কমান্ড কলংয়ে কাজ করে।
ভোর্টিকো

উপর OS X এর 10.12.5 এটা x86_64-apple-darwin16.6.0এবং আপনি খাসি কাজ সেটিতে কল যে gcc, ccঅথবা clang, কিন্তু নাcl
MarcusJ

17

Git Makefile কিভাবে ছাড়া autoconf / automake, এখনো এখনও unixy প্ল্যাটফর্মের একটি বৃন্দ কাজ পরিচালনা করার জন্য অনেক উদাহরণ রয়েছে।


13
গিট অটফুলগুলি কোনওভাবেই ব্যবহার করে না তা জেনে আমার কাছে তাদের ঘৃণা প্রকাশের কারণে আমি ন্যায়সঙ্গত বোধ করি ...
ড্যান মোল্ডিং

11
"Autofools"? এটা কি ইচ্ছাকৃত টাইপ ছিল? :)
জেস্পেআর

6
ইহা ছিল. তবে দ্বিতীয় চিন্তায়, আমি মনে করি আমি "অটোস্টুলস" আরও ভাল পছন্দ করি। : ডি
ড্যান মোল্ডিং

বিটিডব্লিউ, আপনি "তাদের" দ্বারা কে বোঝাতে চেয়েছিলেন? গিট বা অটোটুলের লোকেরা? : ডি
জেস্পেআর

8
ইংরাজী এমন এক অনর্থক ভাষা। এটি সম্পর্কে কীভাবে: if (!usesAutotools(git)) aversionTo(autotools) = justified;আমি আরও স্পষ্ট করে বলব যে এটি কেবলমাত্র সরঞ্জামগুলি যা আমি বিরত করছি। আমি নিশ্চিত অটটুলের লোকেরা খুব ভাল লোক।
ড্যান মোল্ডিং

11

আপডেট: আমি এখন এই উত্তরটি অপ্রচলিত বলে বিবেচনা করি। আমি আরও নিচে একটি নতুন নিখুঁত সমাধান পোস্ট করেছি।

যদি আপনার মেকফাইলটি নন-সাইগউইন উইন্ডোজ চলমান থাকে তবে এটি unameউপলব্ধ নাও হতে পারে। এটি বিশ্রী, তবে এটি একটি সম্ভাব্য সমাধান। এটি খারিজ করার জন্য আপনাকে প্রথমে সাইগউইনকে যাচাই করতে হবে, কারণ এটির PATHপরিবেশের ক্ষেত্রেও উইন্ডো রয়েছে ।

ifneq (,$(findstring /cygdrive/,$(PATH)))
    UNAME := Cygwin
else
ifneq (,$(findstring WINDOWS,$(PATH)))
    UNAME := Windows
else
    UNAME := $(shell uname -s)
endif
endif

এটি এখন ভাল! তুমি কি একটা কথা বলতে পারো? আমি সাইগউইন ব্যবহার করি না, তবে আমি এটি প্যাথের বিন পাথের সাথে মিনিজিডাব্লু ইনস্টল করেছি। আমি যদি unameকোনও সাধারণ সেন্টিমিডি টার্মিনাল থেকে ইস্যু করি তবে এটি আমাকে এমএনডাব্লু দেয়। আমার অর্থ হ'ল unameসাইগউইনকে ব্যবহার না করেই আমার কাছে রয়েছে । আমার কাছে গিট ব্যাশও রয়েছে, তবে আমি এটিতে একা চেষ্টা করিনি (এখনই আমি লিনাক্সে আছি)। আপনি কি আমাকে বলতে পারেন কীভাবে এই দুটি আপনার কোডে সংযুক্ত করা যায়?
শাহবাজ

যদি আপনি নিশ্চিত হন যে আনম পাওয়া যায়, তবে এটিই সেরা সমাধান। কিন্তু আমার পরিবেশে, সবাই উইন্ডোজ ব্যবহার করছে ও কম লোকই পারেন আছে cygwin বা mingw ইনস্টল, তাই আমি কোন গ্যারান্টি যে এমনকি মান হিসেবে কিছু হিসাবে uname কাজ করবে না। আমি বর্তমানে উপরের কোডটি একটি সেন্টিমিডি শেলটিতে মেক.এক্সে চালানোতে কিছুটা সমস্যা বোধ করছি। উইন্ডোজ কাজ করতে খুব হতাশার প্ল্যাটফর্ম।
কেন জ্যাকসন 21

আমার অর্থ হ'ল, পাঠে উইন্ডোজের অস্তিত্বের জন্য পরীক্ষা করার আগে আপনি নিশ্চিত করে নিন যে আপনি সাইগউইন নিয়ে কাজ করছেন না, আপনি কীভাবে নিশ্চিত করতে পারবেন যে আপনি মিনজিডব্লিউয়ের সাথে কাজ করছেন না? উদাহরণস্বরূপ, কমান্ডটি চালানো যায় কি না তা কি মেকফাইলে পরীক্ষা করা সম্ভব, এবং যদি unameচালানো না যায় তবে আমরা বুঝতে পারি যে আমরা উইন্ডোজটিতে আছি?
শাহবাজ 17'12

আমি এই মিংডাব / সাইগউইন / শেল-বা-সেন্টিমিটার / লিনাক্সের একটি পরিষ্কার সমাধান খুঁজতে লড়াই করছি। দিন শেষে, প্রিমেক বা চটকের মতো কিছু মনে হয় সেরা ধারণা।
আইজাক নেউকিট্টেপাস

এটি আর সেরা সমাধান নয়। আমি পোস্ট করা নতুন সমাধানটি ';' 'সন্ধান করে দেশীয় উইন্ডোজকে পৃথক করে; PATH ভেরিয়েবলে শেল কল ছাড়াই।
কেন জ্যাকসন

7

জিএনইউর অটোমেক / অটোকনফ সমাধান করার জন্য তৈরি করা সেই কাজ । আপনি তাদের তদন্ত করতে চাইতে পারেন।

বিকল্পভাবে আপনি আপনার বিভিন্ন প্ল্যাটফর্মগুলিতে পরিবেশের ভেরিয়েবল সেট করতে পারেন এবং তাদের বিপক্ষে আপনাকে মেকফিল শর্তযুক্ত করতে পারেন।


11
আমি অটোমেক / অটোকনফ ব্যবহারের বিরুদ্ধে দৃ strongly়ভাবে পরামর্শ দিচ্ছি। তারা আপনার বিল্ড টাইমটি ব্যবহার করতে, আপনার ফাইলগুলিতে প্রচুর ওভারহেড যুক্ত করতে ক্লান্ত are এগুলি সাধারণত খুব সামান্য প্রভাবের জন্য জটিলতা যুক্ত করে (এখনও সিস্টেমের মধ্যে কোনও বহনযোগ্যতা নেই)।
জোহানেস ওভারম্যান

1
আমি makeযা করতে চাই তা করতে শিখতে বেশ কয়েকদিন ব্যয় করেছি। আমি কি এখন অটোমেক / অটোকনফেও যেতে চাই? - না কি করতে Makefile মধ্যে সম্পন্ন করা, অবশ্যই Makefile মধ্যে সম্পন্ন করা উচিত, যদি শুধু তাই আমি প্রত্যেক সময় আমি কম্পাইল & লিংক সংশোধন করতে চান পয়েন্ট বিভিন্ন স্টপ বন্ধ হবে না।
ইঞ্জিনিয়ার

আপনার মেকফিলগুলি কয়টি প্ল্যাটফর্ম সমর্থন করে? আপনি অনেক প্ল্যাটফর্মে বহনযোগ্যতা চাইলে অটোমেক এবং অটোকনফ সত্যই তাদের নিজস্ব হয়ে আসে।
ডগলাস লিডার

2
আমি অকেজো নির্ভরতা প্রয়োজন না, এবং ওএস এর জন্য কী সংকলিত হচ্ছে তা সন্ধানের জন্য আমার পুরো বিল্ড সিস্টেমটি পরিবর্তন করুন।
মারকাসজে

7

অবশেষে আমি আমার জন্য এই সমস্যাটি সমাধান করে এমন নিখুঁত সমাধান খুঁজে পেয়েছি।

ifeq '$(findstring ;,$(PATH))' ';'
    UNAME := Windows
else
    UNAME := $(shell uname 2>/dev/null || echo Unknown)
    UNAME := $(patsubst CYGWIN%,Cygwin,$(UNAME))
    UNAME := $(patsubst MSYS%,MSYS,$(UNAME))
    UNAME := $(patsubst MINGW%,MSYS,$(UNAME))
endif

ইউএনএম ভেরিয়েবলটি লিনাক্স, সাইগউইন, এমএসওয়াইএস, উইন্ডোজ, ফ্রিবিএসডি, নেটবিএসডি (বা সম্ভবতঃ সোলারিস, ডারউইন, ওপেনবিএসডি, এআইএক্স, এইচপি-ইউএক্স), বা অজানাতে সেট করা আছে। এরপরে যেকোন ওএস-সংবেদনশীল ভেরিয়েবল এবং কমান্ড পৃথক করতে মেকফিলের বাকি অংশগুলির সাথে এটি তুলনা করা যেতে পারে।

মূলটি হ'ল উইন্ডোজ PATH ভেরিয়েবলের পৃথক পাথ পৃথক করতে সেমিকোলন ব্যবহার করে অন্য সবাই কলোন ব্যবহার করে। (নামে একটি ';' দিয়ে একটি লিনাক্স ডিরেক্টরি তৈরি করা সম্ভব এবং এটি PATH এ যুক্ত করা সম্ভব হবে যা এটি ভেঙে ফেলবে, তবে কে এই জাতীয় কাজ করবে?) দেশীয় উইন্ডোজ সনাক্ত করার পক্ষে এটি সবচেয়ে কম ঝুঁকিপূর্ণ পদ্ধতি বলে মনে হয় কারণ এটি শেল কল দরকার নেই সাইগউইন এবং এমএসওয়াইএস পাথ কলোন ব্যবহার করে এত অখাদ্য তাদের জন্য বলা হয়।

নোট করুন যে ওএস এনভায়রনমেন্ট ভেরিয়েবলটি উইন্ডোজ সনাক্ত করতে ব্যবহার করা যেতে পারে তবে সাইগউইন এবং নেটিভ উইন্ডোজের মধ্যে পার্থক্য করতে নয়। উদ্ধৃতিগুলির প্রতিধ্বনির জন্য পরীক্ষা করা কাজ করে তবে এটির জন্য শেল কল প্রয়োজন।

দুর্ভাগ্যবশত, Cygwin আউটপুট কিছু সংস্করণ তথ্য যোগ uname , তাই আমি 'patsubst' কল যোগ শুধু 'Cygwin' থেকে এটি পরিবর্তন করতে। এছাড়াও, এমএসওয়াইএসের জন্য অখাদে এমএসওয়াইএস বা এমইংডাব্লু দিয়ে শুরু হওয়া তিনটি সম্ভাব্য আউটপুট রয়েছে তবে আমি সমস্তকে কেবল 'এমএসওয়াইএস' এ রূপান্তর করতে প্যাটসবস্টও ব্যবহার করি।

পথে কোনও uname.exe ছাড়া এবং ছাড়া দেশীয় উইন্ডোজ সিস্টেমের মধ্যে পার্থক্য করা গুরুত্বপূর্ণ, এই লাইনটি সহজ কার্যভারের পরিবর্তে ব্যবহার করা যেতে পারে:

UNAME := $(shell uname 2>NUL || echo Windows)

অবশ্যই সব ক্ষেত্রে জিএনইউ মেক করা প্রয়োজন, বা অন্য কোনও মেক যা ব্যবহৃত ফাংশনগুলিকে সমর্থন করে।


6

আমি আজ এই সমস্যায় পড়েছি এবং সোলারিসে আমার এটির দরকার ছিল তাই করার জন্য এখানে একটি পসিক্স স্ট্যান্ডার্ড উপায় (খুব কাছাকাছি কিছু)।

#Detect OS
UNAME = `uname`

# Build based on OS name
DetectOS:
    -@make $(UNAME)


# OS is Linux, use GCC
Linux: program.c
    @SHELL_VARIABLE="-D_LINUX_STUFF_HERE_"
    rm -f program
    gcc $(SHELL_VARIABLE) -o program program.c

# OS is Solaris, use c99
SunOS: program.c
    @SHELL_VARIABLE="-D_SOLARIS_STUFF_HERE_"
    rm -f program
    c99 $(SHELL_VARIABLE) -o program program.c

1
ওএসএক্স-এ ত্রুটি পাওয়া: "মেকফিল: 22: *** নিখোঁজ বিভাজক Stop এই লাইনে: "- @ মেক। (ইউএনএমএস)"।
জজারেক টমজাক

ওএসএক্স সম্ভবত সামঞ্জস্যপূর্ণ নয় তাই এগুলি ক্রমে চেষ্টা করুন। (1) নিশ্চিত করুন যে আপনি লাইনটিতে প্রথম অক্ষর হিসাবে একটি ট্যাব ব্যবহার করছেন (২) মেকের (2 ক) সামনে "- @" সরান যদি 2 কাজ করে থাকে তবে একটি অক্ষর চেষ্টা করে দেখুন এবং অন্যটি (3) নিশ্চিত করুন UNAME_S সংজ্ঞায়িত করা হয়, প্রতিধ্বনি $ (UNAME_S) পরিবর্তে চেষ্টা - @ $ (UNAME_S) করা
নিতম্ব

6

এখানে একটি সাধারণ সমাধান যা আপনি উইন্ডোজ বা পোস্টিক্সের মতো (লিনাক্স / ইউনিক্স / সাইগউইন / ম্যাক) পরিবেশে আছেন কিনা তা যাচাই করে নিন:

ifeq ($(shell echo "check_quotes"),"check_quotes")
   WINDOWS := yes
else
   WINDOWS := no
endif

এটি প্যাসিক্সের মতো এবং উইন্ডোজ উভয় পরিবেশে প্রতিধ্বনি উপস্থিত রয়েছে এবং উইন্ডোতে শেলটি কোটগুলি ফিল্টার করে না তার সত্যতাটি গ্রহণ করে।


1
বেশ অনিরাপদ যেহেতু $PATHecho
অন্যটিকে

@YYYOYonnY আপনার পথটি কেন অন্য একটি প্রতিধ্বনি নির্দেশ করে? খুব অসম্ভব পরিস্থিতি বলে মনে হচ্ছে।
স্যামুয়েল

1
সত্যই নয়, গিট এটি করে, মিংডব্লু এটা করে, সাইগউইন এটি করে ... এবং আমি ব্যক্তিগতভাবে সি: \ উইন্ডোজ \ সিস্টেম 32 আমার পথের নীচে রেখেছি।
yyny

1
এই "সমাধান" "সমস্ত পরিবেশের জন্য" কাজ করে, তবে আমার বক্তব্যটি এটি নিরাপদে উইন্ডোজ সনাক্ত করতে পারে না। আমি যদি একটি -mwindowsপতাকা সেট করতে চাই বা একটি .dllবা এর মধ্যে বেছে নিতে চাই .soতবে এটি ব্যর্থ হবে।
yyny

1
@ YYYOYonnY স্পষ্ট করার জন্য ধন্যবাদ। আমার পরিস্থিতিতে আমি কেবল তখনই যত্নশীল যদি আমি সিএসউইন বা উইন্ডোজ বা লিনাক্স পরিবেশে থাকি তবে আমি যে ওএস-এ থাকতাম, তাই এটি আমার পক্ষে সহায়ক। আপনার প্রয়োজনের মতো শব্দগুলি আমার যা ছিল তার চেয়ে আলাদা।
স্যামুয়েল

3

নোট করুন যে মেকফিলগুলি ব্যবধানের জন্য অত্যন্ত সংবেদনশীল। এখানে একটি মেকফিলের উদাহরণ রয়েছে যা ওএস এক্সে একটি অতিরিক্ত কমান্ড চালায় এবং এটি ওএস এক্স এবং লিনাক্সে কাজ করে। সামগ্রিকভাবে, যদিও, অটোকনফ / অটোমেক হ'ল কিছুতেই তুচ্ছ-তুচ্ছ কিছুতেই যাওয়ার উপায়।

ইউএনএম: = $ (শেল আনম-এস)
সিপিপি = জি ++
সিপিপিএফএলএজিএস = -প্রেড-ওয়ানসি -ওয়াল-ওয়ারার -প্যাডেন্টিক -O0 -g3 -I / nexopia / অন্তর্ভুক্ত
LDFLAGS =-প্রসারিত -L / nexopia / lib -lboost_s সিস্টেম

শিরোনাম = ডেটা_স্ট্রাকচার। Http_client.h
ওবিজেইসিটিএস = http_client.o লোড.ও লক.ও সার্চ.ও সার্ভার.ও থ্রেড.ও ইউটিলিটি.ও vor.o

all: vor

পরিষ্কার:
    rm -f $ (OBJECTS) vor

ভোর: $ (ওবিজেসিটিএস)
    CP (সিপিপি) $ (এলডিএফএলএজিএস) -ও ভোর $ (ওবিজেইসিটিএস)
ifeq ($ (UNAME), ডারউইন)
    # বুস্ট লাইব্রেরির অবস্থান সেট করুন
    ইনস্টল_নাম_টুল-চেঞ্জ লাইববুস্ট_সিস্টেম.ডিলিব / নিউক্সোপিয়া / লিবি / লিবিবস্ট_সিস্টেম.আইডিলেব ভোর
যদি শেষ

% .o:% .cpp $ (শিরোনাম) মেকফিল
    $ (সিপিপি) $ (সিপিপিএফএলএজিএস) -সি $

2

এটি করার আরেকটি উপায় হ'ল "কনফিগার" স্ক্রিপ্ট ব্যবহার করে। আপনি যদি ইতিমধ্যে আপনার মেকফিলের সাথে একটি ব্যবহার করে থাকেন তবে জিনিসগুলি কার্যকর করার জন্য আপনি আনমেড এবং সিডের সংমিশ্রণটি ব্যবহার করতে পারেন। প্রথমে, আপনার স্ক্রিপ্টে, করুন:

UNAME=uname

তারপরে, এটি আপনার মেকফাইলে রাখার জন্য, Makefile.in দিয়ে শুরু করুন যার মতো কিছু হওয়া উচিত

UNAME=@@UNAME@@

এটা.

UNAME=unameবিট করার পরে আপনার কনফিগার স্ক্রিপ্টে নিম্নলিখিত সিড কমান্ডটি ব্যবহার করুন ।

sed -e "s|@@UNAME@@|$UNAME|" < Makefile.in > Makefile

এখন আপনার মেকফিলটি UNAMEপছন্দসই হিসাবে সংজ্ঞায়িত করা উচিত ছিল । যদি / এলিফ / অন্য বিবৃতি বাকী থাকে তবে!


প্রথম সমীকরণটি কি এটি হওয়া উচিত নয়? ইউএনএম = $ (একচেটিয়া)
কেন জ্যাকসন

0

আমার একটি মামলা ছিল যেখানে আমাকে ফেডোরার দুটি সংস্করণের মধ্যে পার্থক্য সনাক্ত করতে হবে
, ইনস্কেপের জন্য কমান্ড-লাইন বিকল্পগুলি সন্ধান করতে: - ফেডোরার 31-এ, ডিফল্ট ইনস্কেপটি 1.0beta যা ব্যবহার করে --export-file
- ফেডোরা <31 এ, ডিফল্ট ইনস্কেপটি রয়েছে 0.92 যা ব্যবহার করে--export-pdf

আমার মেকফিলটিতে নিম্নলিখিত রয়েছে

# set VERSION_ID from /etc/os-release

$(eval $(shell grep VERSION_ID /etc/os-release))

# select the inkscape export syntax

ifeq ($(VERSION_ID),31)
EXPORT = export-file
else
EXPORT = export-pdf
endif

# rule to convert inkscape SVG (drawing) to PDF

%.pdf : %.svg
    inkscape --export-area-drawing $< --$(EXPORT)=$@

এটি কাজ করে কারণ /etc/os-releaseএকটি লাইন রয়েছে

VERSION_ID=<value>

সুতরাং মেকফাইলে শেল কমান্ডটি স্ট্রিংটি ফিরিয়ে দেয় VERSION_ID=<value>, তারপরে ইভাল কমান্ড মেকফিল ভেরিয়েবল সেট করতে এটিতে কাজ করে VERSION_ID। মেটাডেটা কীভাবে সংরক্ষণ করা হয় তা নির্ভর করে অন্যান্য ওএসের জন্য এটি স্পষ্টতই টুইট করা যেতে পারে। নোট করুন যে ফেডোরায় কোনও ডিফল্ট পরিবেশ পরিবর্তনশীল নেই যা ওএস সংস্করণ দেয়, না হলে আমি এটি ব্যবহার করতাম!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.