তৈরি করতে কমান্ড লাইন থেকে অতিরিক্ত ভেরিয়েবল পাস করা


613

কমান্ড লাইন আর্গুমেন্ট হিসাবে আমি কোনও জিএনইউ মেকফিলকে ভেরিয়েবলগুলি পাস করতে পারি? অন্য কথায়, আমি কিছু যুক্তি পাস করতে চাই যা শেষ পর্যন্ত মেকফাইলে ভেরিয়েবল হয়ে উঠবে।

উত্তর:


752

আপনার মেকফিলের বাইরে থেকে ভেরিয়েবল সেট আপ করার জন্য আপনার কাছে বেশ কয়েকটি বিকল্প রয়েছে:

  • পরিবেশ থেকে - প্রতিটি পরিবেশের ভেরিয়েবল একই নাম এবং মান সহ একটি মেকফিল ভেরিয়েবলে রূপান্তরিত হয়।

    আপনি -eবিকল্প (ওরফে --environments-override) চালু করতেও পারেন , এবং আপনার পরিবেশের ভেরিয়েবলগুলি মেকফাইলে তৈরি অ্যাসাইনমেন্টগুলিকে ওভাররাইড করবে (যদি না এই অ্যাসাইনমেন্টগুলি নিজেরাই overrideনির্দেশিকা ব্যবহার না করে However তবে, এটি প্রস্তাবিত নয়, এবং ?=অ্যাসাইনমেন্টটি ব্যবহার করার ক্ষেত্রে এটি আরও ভাল এবং নমনীয় (শর্তাধীন ভেরিয়েবল) অ্যাসাইনমেন্ট অপারেটর, ভেরিয়েবলটি এখনও সংজ্ঞায়িত না হলে এর কেবলমাত্র একটি প্রভাব রয়েছে):

    FOO?=default_value_if_not_set_in_environment
    

    নোট করুন যে কিছু পরিবর্তনশীল পরিবেশ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত নয়:

    • MAKE স্ক্রিপ্টের নাম থেকে প্রাপ্ত
    • SHELLহয় একটি মেকফিলের মধ্যে সেট করা হয়, বা এতে ডিফল্ট হয় /bin/sh(যুক্তি: কমান্ডগুলি মেকফিলের মধ্যে নির্দিষ্ট করা হয়, এবং সেগুলি শেল-নির্দিষ্ট)।
  • কমান্ড লাইন থেকে - makeতার কমান্ড লাইনের অংশ হিসাবে লক্ষ্যগুলি মিশ্রিত করে পরিবর্তনীয় অ্যাসাইনমেন্ট গ্রহণ করতে পারে:

    make target FOO=bar
    

    কিন্তু তারপর সব বরাদ্দকরণ FOOMakefile মধ্যে পরিবর্তনশীল উপেক্ষা করা হবে যদি না আপনি ব্যবহার overrideডিরেক্টিভের নিয়োগ হবে। (প্রভাবটি -eভেরিয়েবলের বিকল্প হিসাবে একই )

  • পিতামাতার মেক থেকে রফতানি করা - যদি আপনি মেকফাইল থেকে মেক কল করেন তবে আপনার সাধারণত স্পষ্টভাবে এই জাতীয় পরিবর্তনশীল অ্যাসাইনমেন্টগুলি লেখা উচিত নয়:

    # Don't do this!
    target:
            $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
    

    পরিবর্তে, আরও ভাল সমাধান হতে পারে এই ভেরিয়েবলগুলি রফতানি করা। একটি ভেরিয়েবল রফতানি করা প্রতিটি শেল আবেদনের পরিবেশে এটি তৈরি করে এবং এই আদেশগুলি থেকে কলগুলি উপরে উল্লিখিত হিসাবে এই পরিবেশটি পরিবর্তনশীল চয়ন করে।

    # Do like this
    CFLAGS=-g
    export CFLAGS
    target:
            $(MAKE) -C target
    

    আপনি তর্ক ছাড়াই ব্যবহার করে সমস্ত পরিবর্তনশীল রফতানি করতে পারেন export


10
কমান্ড লাইন থেকে ফাঁকা জায়গাগুলির সাথে কিছু করার জন্যmake A='"as df"'
সিরো সান্তিলি 法轮功 冠状 病 六四 事件 法轮功

4
মনে হচ্ছে আপনি যদি পরিবেশের ভেরিয়েবলগুলির বিষয়ে চিন্তা করেন তবে আপনি সমস্যার জন্য জিজ্ঞাসা করছেন। একটি জিনিসের জন্য, এটি ডিবাগিং দুঃস্বপ্নটি যদি এটি A এর জায়গায় কাজ করে এবং বি জায়গায় হয় না, কেবল কারণ তাদের আলাদা পরিবেশ রয়েছে।
জেমস মুর

12
কেবল অভিজ্ঞতার ভিত্তিতে, সিএফএলজিএসের মতো সামগ্রী রফতানি করা বড় প্রকল্পগুলির দুঃস্বপ্নের একটি রেসিপি। বড় প্রকল্পগুলিতে প্রায়শই তৃতীয় পক্ষের লাইব্রেরি থাকে যা কেবলমাত্র প্রদত্ত পতাকাগুলির সংকলন করে (যে কেউ ফিক্সিংয়ে বিরক্ত করে না)। আপনি যদি সিএফএলএজিএস রফতানি করেন তবে আপনার প্রকল্পের সিএফএলএজিএস 3 য় পক্ষের গ্রন্থাগারকে ওভাররাইড করে শেষ করে এবং সংকলনের ত্রুটিগুলি ট্রিগার করে। একটি বিকল্প উপায় হতে পারে এটি সংজ্ঞায়িত করা export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)এবং পাশাপাশি পাস করা make -C folder $(PROJECT_MAKE_FLAGS)। লাইব্রেরির মেকফিলকে পরিবেশ উপেক্ষা করার জন্য যদি কোনও উপায় থাকে তবে তা আদর্শ হবে (-e এর বিপরীতে)।
আরডি

24
সতর্কতা: উপরের "পিতামাতার থেকে রফতানি করা" বিভাগে, "এটি করবেন না!" হয় সমালোচকদের বিভ্রান্তিকর । কমান্ড লাইনে ভেরিয়েবলগুলি সাব-মেকফাইলে অ্যাসাইনাইড করে তবে এক্সপোর্ট করা ভেরিয়েবলগুলি সাব-মেকফাইলে অ্যাসাইনাইডগুলিকে ওভাররাইড করে না । একটি উপ-মেকফিলে ভেরিয়েবলগুলি পাস করার জন্য এই দুটি পদ্ধতি সমতুল্য নয় এবং তাদের বিভ্রান্ত করা উচিত নয়।
জোনাথন বেন-অভ্রাহাম

4
কোন পার্থক্য? make target FOO=bar make FOO=bar target?
gfan

213

সবচেয়ে সহজ উপায়:

make foo=bar target

তারপরে আপনার মেকফাইলে আপনি উল্লেখ করতে পারেন $(foo) । মনে রাখবেন এটি স্বয়ংক্রিয়ভাবে সাব-মেকগুলিতে প্রচার করবে না।

আপনি যদি সাব-মেক ব্যবহার করছেন তবে এই নিবন্ধটি দেখুন: একটি সাব-মেকের সাথে চলকগুলি যোগাযোগ করা


2
উপ-মাধ্যমে আপনি includedমূল মেকফিলের মেকফিলগুলি বোঝাতে চান ?
পাবলো

2
@ মিশেল: এর অর্থ মেকফাইলের ভেতর থেকে আবার মেক কল করা। আপনি এই বিবরণে আগ্রহী বলে মনে হচ্ছে বলে আমি আমার উত্তর আপডেট করেছি।
বায়ার্সকে চিহ্নিত করুন

2
"দ্রষ্টব্য যে এটি স্বয়ংক্রিয়ভাবে উপ-মেকগুলিতে প্রচার করবে না" " অসত্য! "ডিফল্টরূপে কেবল পরিবেশ বা কমান্ড লাইন থেকে আসা পরিবর্তনগুলি পুনরাবৃত্তির অনুরোধগুলিতে পাস করা হয় other gnu.org/software/make/manual/html_node/…
টমাসম্যাকলিউড

82

বলুন আপনার কাছে একটি মেকফাইল রয়েছে:

action:
    echo argument is $(argument)

আপনি তখন এটি কল হবে make action argument=something


5
সুতরাং লক্ষ্য এবং তর্কগুলি অবস্থানের দিক থেকে বিনিময় করা যায়?
পাবলো


25

ম্যানুয়াল থেকে :

মেক ইন ভেরিয়েবলগুলি এমন পরিবেশ থেকে আসতে পারে যেখানে মেক তৈরি হয়। প্রতিটি পরিবেশ পরিবর্তনশীল যা দেখতে শুরু করে তা একই নাম এবং মান সহ একটি মেক ভেরিয়েবলে রূপান্তরিত হয়। যাইহোক, মেকফাইলে একটি স্পষ্ট স্পেসমেন্ট বা কমান্ড আর্গুমেন্ট সহ পরিবেশকে ওভাররাইড করে।

সুতরাং আপনি (বাশ থেকে) করতে পারেন:

FOOBAR=1 make

FOOBARআপনার মেকফাইলে পরিবর্তনের ফলে ।


2
অন্য উপায় প্রকৃতপক্ষে প্রায় সব ক্ষেত্রেই ভাল। আমি এখানে পুরোপুরি রেখে যাব।
থমাস

এটিই একমাত্র উত্তর যা একই লাইনে মেক কমান্ডের আগে ভেরিয়েবলের অ্যাসাইনমেন্ট দেখায় - এটি সিনট্যাক্স ত্রুটি নয় এটি জেনে রাখা ভাল।
এম_এম

7

এখানে আর একটি বিকল্প উদ্ধৃত হয়নি যা স্টলম্যান এবং ম্যাকগ্রাথের জিএনইউ মেক বইয়ে অন্তর্ভুক্ত রয়েছে (দেখুন http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html )। এটি উদাহরণ প্রদান করে:

archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
        +touch archive.a
        +ranlib -t archive.a
else
        ranlib archive.a
endif

এটিতে কোনও প্রদত্ত প্যারামিটার উপস্থিত থাকলে যাচাই করা জড়িত MAKEFLAGS। উদাহরণস্বরূপ .. ধরুন যে আপনি সি ++ 11 এ থ্রেড সম্পর্কে অধ্যয়ন করছেন এবং আপনি একাধিক ফাইল ( class01, ...,,classNM ) এবং আপনি চান: তারপরে সমস্ত সংকলন করুন এবং স্বতন্ত্রভাবে চালনা করুন বা একটিতে একটি সংকলন করুন সময় এবং এটি চালান যদি একটি পতাকা নির্দিষ্ট করা হয় ( -rউদাহরণস্বরূপ)। সুতরাং, আপনি নিম্নলিখিতটি নিয়ে আসতে পারেন Makefile:

CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread

SOURCES = class01 class02 class03

%: %.cxx
    $(CXX) $(CXXFLAGS) -o $@.out $^ $(LDLIBS)
ifneq (,$(findstring r,  $(MAKEFLAGS)))
    ./$@.out
endif

all: $(SOURCES)

.PHONY: clean

clean:
    find . -name "*.out" -delete

যে থাকার পরে, আপনি:

  • একটি ফাইল তৈরি এবং চালনা w / make -r class02;
  • সমস্ত W / নির্মাণ make বা নির্মাণ make all;
  • সমস্ত ডব্লিউ / তৈরি করুন এবং চালান make -r(মনে করুন যে এগুলির মধ্যে কিছু নির্দিষ্ট ধরণের স্টোর স্টাফ রয়েছে এবং আপনি কেবল সেগুলি সব পরীক্ষা করতে চান)

6

এটা দেখতে

কমান্ড আরোগুলি এনভায়রনমেন্ট ভেরিয়েবল ওভাররাইট করে

Makefile নামক

send:
    echo $(MESSAGE1) $(MESSAGE2)

উদাহরণ চালান

$ MESSAGE1=YES MESSAGE2=NG  make send MESSAGE2=OK
echo YES OK
YES OK

5

আপনি যদি মেকফাইল নামে একটি ফাইল তৈরি করেন এবং এই জাতীয় unit (ইউনিটেস্ট) এর মতো একটি ভেরিয়েবল যুক্ত করেন তবে আপনি ওয়াইল্ডকার্ড সহ এমনকি মেকফিলের অভ্যন্তরে এই পরিবর্তনশীলটি ব্যবহার করতে সক্ষম হবেন

উদাহরণ:

make unittest=*

আমি BOOST_TEST ব্যবহার করি এবং --run_test = $ (ইউনিটেস্ট) প্যারামিটারে একটি ওয়াইল্ডকার্ড দিয়ে আমি তারপরে আমার মেকফিলটি চালানোর জন্য পরীক্ষার ফিল্টার করতে নিয়মিত অভিব্যক্তি ব্যবহার করতে সক্ষম হব


4
export ROOT_DIR=<path/value>

তারপরে ভেরিয়েবলটি $(ROOT_DIR)মেকফাইলে ব্যবহার করুন ।

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