মেকফাইলে কোনও পরিবর্তনশীল কীভাবে মুদ্রণ করবেন


247

আমার মেকফাইলে, আমার একটি 'NDK_PROJECT_PATH' পরিবর্তনশীল রয়েছে, আমার প্রশ্নটি যখন এটি সংকলিত হয় তখন আমি কীভাবে এটি মুদ্রণ করতে পারি?

আমি "$ PATH" স্ট্রিং প্রদর্শিত ফাইল ইকো করুন পড়ি এবং আমি চেষ্টা করেছিলাম:

@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)

দুজনই আমাকে দেয়

"build-local.mk:102: *** missing separator.  Stop."

কেউ জানেন কেন এটি আমার পক্ষে কাজ করছে না?

উত্তর:


223

মেকফিলটি পড়ার সাথে সাথে আপনি ভেরিয়েবলগুলি মুদ্রণ করতে পারেন (এই প্রশ্নটি আপনি যথাযথভাবে ট্যাগ করেছেন বলে জিএনইউ তৈরি করে ধরে) এই পদ্ধতিটি ব্যবহার করে ("ভেরি" নামের একটি ভেরিয়েবল সহ):

$(info $$var is [${var}])

শেলটি কী তৈরি করবে তা দেখতে আপনি কোনও রেসিপিটিতে এই নির্মাণটি যুক্ত করতে পারেন:

.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world

এখন, এখানে যা ঘটে তা হ'ল সম্পূর্ণ রেসিপিটি ( $(info $$var is [${var}])echo Hello world) একক পুনরাবৃত্তভাবে প্রসারিত পরিবর্তনশীল হিসাবে সঞ্চয় করে । যখন রেসিপিটি চালানোর সিদ্ধান্ত নেবেন (উদাহরণস্বরূপ যখন আপনি এটি তৈরি করতে বলবেন all), এটি ভেরিয়েবলটি প্রসারিত করে এবং তারপরে প্রতিটি ফলাফলের লাইনটি পৃথকভাবে শেলের কাছে চলে যায়।

সুতরাং, বেদনাদায়ক বিস্তারিত:

  • এটি প্রসারিত হয় $(info $$var is [${var}])echo Hello world
  • এটি করার জন্য এটি প্রথমে প্রসারিত হয় $(info $$var is [${var}])
    • $$ আক্ষরিক হয় $
    • ${var}হয়ে যায় :-)(বলে)
    • পার্শ্ব প্রতিক্রিয়া $var is [:-)]এটি স্ট্যান্ডার্ড আউট প্রদর্শিত হয়
    • $(info...)যদিও এর প্রসার শূন্য
  • মেক দিয়ে রেখে দেওয়া হয় echo Hello world
    • echo Hello worldএটি শেলটি কী করতে বলছে তা আপনাকে জানাতে প্রথমে স্টাডাউটে প্রিন্টগুলি তৈরি করুন
  • Hello worldস্টলআউটে শেলটি প্রিন্ট করে।

2
এটি (বিন্দু) হওয়া উচিত। PHONY এর পরিবর্তে PHONY?
হামাদিয়ান

172

অনুযায়ী গনুহ করুন ম্যানুয়াল এবং উত্তর নিচে 'bobbogo' দ্বারা নির্দিষ্ট, আপনি ব্যবহার করতে পারেন তথ্য / সতর্কবাণী / ত্রুটি প্রদর্শন পাঠ্যে।

$(error   text…)
$(warning text…)
$(info    text…)

ভেরিয়েবল মুদ্রণ করতে,

$(error   VAR is $(VAR))
$(warning VAR is $(VAR))
$(info    VAR is $(VAR))

'ত্রুটি' ত্রুটির স্ট্রিং দেখানোর পরে, মেক এক্সিকিউশন বন্ধ করে দেবে


বাহ, এটা জানতাম না। প্রতিধ্বনির চেয়েও ভাল উপায়, যা লগগুলিতে কমান্ডটি সদৃশ করে।
26:38

148

একটি "মিস্টার পোস্ট করুন" থেকে https://www.cmcrossroads.com/article/printing-value-makefile- পরিবর্তনযোগ্য

আপনার মেকফাইলে নিম্নলিখিত বিধি যুক্ত করুন:

print-%  : ; @echo $* = $($*)

তারপরে, আপনি যদি কোনও মেকফিল ভেরিয়েবলের মান সন্ধান করতে চান তবে:

make print-VARIABLE

এবং এটি ফিরে আসবে:

VARIABLE = the_value_of_the_variable

আপনি এটি লেখকের চেয়ে ভাল ব্যাখ্যা করেছেন। থাম্বস আপ!
f0nzie

44

আপনি যদি কেবল কিছু আউটপুট চান তবে আপনি $(info)নিজেই এটি ব্যবহার করতে চান । আপনি এটি কোনও মেকফিলের যে কোনও জায়গায় করতে পারেন, এবং যখন সেই লাইনটি মূল্যায়ন করা হয় তখন তা প্রদর্শিত হবে:

$(info VAR="$(VAR)")

VAR="<value of VAR>"প্রক্রিয়া যখনই লাইন তৈরি করে আউটপুট দেয় Will এই আচরণটি খুব অবস্থান নির্ভর, তাই আপনাকে অবশ্যই নিশ্চিত করতে হবে যে $(info)পরিবর্ধনটি যা কিছু সংশোধন করতে পারে $(VAR)তার আগেই ঘটেছে!

একটি আরও জেনেরিক বিকল্পটি একটি ভেরিয়েবলের মান মুদ্রণের জন্য একটি বিশেষ নিয়ম তৈরি করা। সাধারণত বলতে গেলে, ভেরিয়েবলগুলি নির্ধারিত হওয়ার পরে নিয়মগুলি কার্যকর করা হয়, সুতরাং এটি আপনাকে প্রকৃতপক্ষে ব্যবহৃত হচ্ছে এমন মানটি প্রদর্শন করবে। (যদিও, কোনও নিয়মের পক্ষে একটি পরিবর্তনশীল পরিবর্তন করা সম্ভব )) ভাল ফর্ম্যাটিংটি ভেরিয়েবলটি কী সেট করা হয়েছে তা পরিষ্কার করতে সহায়তা করবে এবং $(flavor)ফাংশনটি আপনাকে বলবে যে কোনও পরিবর্তনশীল কোন ধরণের কি। সুতরাং এই নিয়মে:

print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
  • $*নিয়মে % প্যাটার্নটি মেলে এমন কান্ডে প্রসারিত হয় ।
  • $($*)যার নাম দ্বারা প্রদত্ত ভেরিয়েবলের মান প্রসারিত হয় $*
  • [এবং ]পরিষ্কারভাবে পরিবর্তনশীল সম্প্রসারণ অঙ্কিত। এছাড়াও আপনি ব্যবহার করতে পারে "এবং "বা অনুরূপ।
  • $(flavor $*)এটি কী ধরণের পরিবর্তনশীল তা আপনাকে জানায়। দ্রষ্টব্য: $(flavor) একটি পরিবর্তনশীল নাম নেয় এবং এর প্রসারণ হয় না। সুতরাং আপনি যদি বলেন make print-LDFLAGS, আপনি পাবেন $(flavor LDFLAGS), যা আপনি চান।
  • $(info text)আউটপুট সরবরাহ করে। প্রসারণের পার্শ্ব-প্রতিক্রিয়া হিসাবে এর স্টডআউটে প্রিন্টগুলি তৈরি করুনtext$(info)যদিও এর প্রসার শূন্য। আপনি এটির মতো ভাবতে পারেন @echoতবে গুরুত্বপূর্ণভাবে এটি শেলটি ব্যবহার করে না, তাই আপনাকে শেল উদ্ধৃতি বিধি সম্পর্কে উদ্বিগ্ন হওয়ার দরকার নেই।
  • @trueনিয়মের জন্য একটি কমান্ড দেওয়ার জন্য এখানে কি আছে? যে ছাড়া, মেক এছাড়াও আউটপুট হবে print-blah is up to date। আমি মনে করি @trueএটি আরও স্পষ্ট করে দিয়েছে যে এটি বোঝানো হচ্ছে কোনও অপ-অপশন নয়।

এটি চালানো, আপনি পেতে

$ make print-LDFLAGS
LDFLAGS is a recursive variable set to [-L/Users/...]

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

পর্যালোচনা করার জন্য ধন্যবাদ। আমি বুঝতে পারি যে আমি যথেষ্ট খ্যাতি পেয়ে একবার মন্তব্য করতে পারি, তবে এর মধ্যে আমার কী করা উচিত? আমার বিশ্বাস আমার উত্তরটি অতিরিক্ত মান সরবরাহ করে, তাই আমি কি এটি যুক্ত করব না?
জিম ন্যাসবি

1
আমি এটিকে পুনরায় লেখার পরামর্শ দিচ্ছি যে আপনি যে মন্তব্যে মন্তব্য করছেন তার সাথে প্রতিদ্বন্দ্বিতা করা একটি স্বতন্ত্র উত্তর, বরং এটিকে উত্তরের স্থানের বাইরে মন্তব্য হিসাবে চিহ্নিত করা উচিত।
চার্লস ডাফি

@ জিমনাস্বি হ্যাঁ, চার্লস যা পরামর্শ দিয়েছেন। প্রকৃতপক্ষে এটি একটি সূচনা জাতীয় ধরণের হিসাবে কেবল "ধরণের মন্তব্য করার মতো যথেষ্ট প্রতিনিধিত্বমূলক নয়" অংশটি ধরণের সরানোর পক্ষে সাহায্য করতে পারে। আপনি যদি এটি একটি সম্পূর্ণ উত্তরে রূপান্তর করেন (আপনার পছন্দ মতো এটি সম্পাদনা করতে পারেন), এটি বেশ দুর্দান্তভাবে করা উচিত। চিয়ার্স।
ড্রাগন এনার্জি

দুর্দান্ত - এটি এখন আরও ভাল উত্তর। :)
চার্লস ডফি

6

@echo $ (NDK_PROJECT_PATH) এটি করার ভাল উপায়। আমি মনে করি না ত্রুটিটি সেখান থেকে এসেছিল। সাধারণত আপনি যখন উদ্দেশ্যটিকে ভুল টাইপ করেছেন তখন এই ত্রুটিটি উপস্থিত হয়: আমার মনে হয় আপনার এমন একটি ফাঁকা জায়গা রয়েছে যেখানে আপনার একটি ট্যাব থাকা উচিত।


2
আমি '@echo $ (NDK_PROJECT_PATH)' চেষ্টা করেছি, এখনও আমি "বিল্ড-লোকাল.এমকেএম 2: *** হারিয়ে যাওয়া বিভাজক একটি ত্রুটি পেয়েছি।" 'ইকো' এর পরে আমার ঠিক 1 স্থান আছে, '@ ইকো' এর আগে কোনও স্থান বা ট্যাব নেই।
মাইকেল

আপনি কি নিশ্চিত যে এই লাইন থেকে ত্রুটি এসেছে? এই লাইন একটি নিয়মে? তিনি সম্ভবত

6

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

myTarget: myDependencies
        @echo hi

যেখানে দ্বিতীয় লাইনের প্রথম অক্ষরটি অবশ্যই ট্যাব হবে।


4

চালান make -n; এটি আপনাকে ভেরিয়েবলের মান দেখায় ..

Makefile নামক ...

all:
        @echo $(NDK_PROJECT_PATH)

COMMAND:

export NDK_PROJECT_PATH=/opt/ndk/project
make -n 

আউটপুট:

echo /opt/ndk/project

যদিও এটি কার্যকর বেশ কার্যকর এবং আমি মৃত্যুদন্ড কার্যকর করার পরিবর্তে--just-print একই ব্যবহার করি
ফ্রেড্রিক গাউস

3

এটি makefile'নিখোঁজ বিভাজক' ত্রুটি বার্তা উত্পন্ন করবে:

all
    @echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)

done:
        @echo "All done"

এর আগে একটি ট্যাব রয়েছে @echo "All done"(যদিও done:নিয়ম এবং ক্রিয়াটি বেশিরভাগ ক্ষেত্রে অতিরিক্ত অতিরিক্ত) তবে এর আগে নয় @echo PATH=$(PATH)

সমস্যাটি হ'ল লাইনটি শুরু হওয়ার সাথে সাথে allএকটি কোলন :বা সমান হওয়া উচিত =এটি চিহ্নিত করতে যে এটি একটি লক্ষ্য রেখা বা ম্যাক্রো লাইন, এবং এর কোনওটি নেই, তাই বিভাজকটি নিখোঁজ রয়েছে।

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

মূলটিতে আপনার সম্ভবত 102 রেখার কাছে একটি অভিন্ন সমস্যা রয়েছে makefile। যদি আপনি ইকো অপারেশনগুলি ব্যর্থ হওয়ার আগে 5 টি শূন্য, নন-মন্তব্য লাইনগুলি দেখান তবে সম্ভবত এই রোগ নির্ণয়টি শেষ করা সম্ভব হবে। তবে, ২০১৩ সালের মে মাসে যে প্রশ্নটি জিজ্ঞাসা করা হয়েছিল, সম্ভবত ভাঙাটি makefileএখনই পাওয়া যায় (আগস্ট ২০১৪), সুতরাং এই উত্তরটি আনুষ্ঠানিকভাবে বৈধ হওয়া যায় না। এটি কেবলমাত্র একটি সমস্যাযুক্ত উপায়ে চিত্রিত করতে ব্যবহার করা যেতে পারে যেখানে সমস্যা দেখা দিয়েছে।


3

মেকফিলটি সংশোধন করার দরকার নেই।

$ cat printvars.mak
print-%:
        @echo '$*=$($*)'

$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE

2

সমস্যাটি হল যে প্রতিধ্বনি কেবলমাত্র একটি এক্সিকিউশন ব্লকের অধীনে কাজ করে। যেমন "xx:" এর পরে কিছু

সুতরাং প্রথম এক্সিকিউশন ব্লকের উপরে যে কোনও কিছুই কেবল সূচনা হয় যাতে কোনও এক্সিকিউশন কমান্ড ব্যবহার করা যায় না।

সুতরাং একটি এক্সিকিউশন ব্লক তৈরি করুন


1

এটি জেনেরিক উপায়ে করা যেতে পারে এবং জটিল মেকফিল ডিবাগ করার সময় এটি খুব কার্যকর হতে পারে। অন্য উত্তরে বর্ণিত একই কৌশল অনুসরণ করে , আপনি যে কোনও মেকফাইলে নিম্নলিখিতটি সন্নিবেশ করতে পারেন:

# if the first command line argument is "print"
ifeq ($(firstword $(MAKECMDGOALS)),print)

  # take the rest of the arguments as variable names
  VAR_NAMES := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))

  # turn them into do-nothing targets
  $(eval $(VAR_NAMES):;@:))

  # then print them
  .PHONY: print
  print:
          @$(foreach var,$(VAR_NAMES),\
            echo '$(var) = $($(var))';)
endif

তারপরে আপনি যে কোনও ভেরিয়েবলের মান ডাম্প করতে কেবল "মুদ্রণ তৈরি করুন" করতে পারেন:

$ make print CXXFLAGS
CXXFLAGS = -g -Wall

1

আপনি আপনার মেক ফাইলে একটি ভার্স রুল তৈরি করতে পারেন, এর মতো:

dispvar = echo $(1)=$($(1)) ; echo

.PHONY: vars
vars:
    @$(call dispvar,SOMEVAR1)
    @$(call dispvar,SOMEVAR2)

এখানে সমস্ত ভেরিয়েবল ডাম্প করার আরও কিছু শক্তিশালী উপায় রয়েছে: gnu make: নির্দিষ্ট রানে সমস্ত ভেরিয়েবলের মান (বা "ম্যাক্রোস") তালিকাভুক্ত করুন


0

আপনি যদি নিজেই মেকফিলটি পরিবর্তন করতে চান না, আপনি --evalএকটি নতুন লক্ষ্য যুক্ত করতে ব্যবহার করতে পারেন , এবং তারপরে নতুন লক্ষ্যটি কার্যকর করতে পারেন , উদাহরণস্বরূপ

make --eval='print-tests: @echo TESTS $(TESTS) ' print-tests

আপনি কমান্ড লাইনে প্রয়োজনীয় TAB অক্ষরটি sertোকাতে পারেন CTRL-V, TAB

উপর থেকে উদাহরণস্বরূপ Makefile:

all: do-something

TESTS=
TESTS+='a'
TESTS+='b'
TESTS+='c'

do-something:
        @echo "doing something"
        @echo "running tests $(TESTS)"
        @exit 1

আমি আপনার স্ক্রিপ্টটি চালানোর চেষ্টা করছি তবে আমি ত্রুটি পাচ্ছিmake: *** missing separator. Stop.
রিনালাদি সেগেসিন

আহ, দুঃখিত, স্থির। "মুদ্রণ-পরীক্ষা" লক্ষ্য শেষে কোলন অনুপস্থিত ing
ওয়েড

আসলে আপনার make --eval='print-tests: ; @echo TESTS $(TESTS)' print-tests
নিউলাইন

0

যদি আপনি অ্যান্ড্রয়েড মেক ব্যবহার করেন (এম কে) @echo $(NDK_PROJECT_PATH)কাজ করবে না এবং যদি আপনি অ্যান্ড্রয়েড মেকগুলিতে ভেরিয়েবল মুদ্রণের চেষ্টা করছেন তবে এই উত্তরটি*** missing separator. Stop." ব্যবহার করতে ত্রুটি দেয়

NDK_PROJECT_PATH := some_value
$(warning $(NDK_PROJECT_PATH))

যে আমার জন্য কাজ করে


0

আমি পরিবর্তনশীল মানটি দেখতে চাইলে আমি সাধারণত একটি ত্রুটি সহ প্রতিধ্বনিত করি ((আপনি যদি মানটি দেখতে চান তবেই এটি কার্যকর করা বন্ধ করবে))

@echo $ (ত্রুটি NDK_PROJECT_PATH = $ (NDK_PROJECT_PATH))

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