টিএল; ডিআর : error
ফাংশনটি ব্যবহার করুন :
ifndef MY_FLAG
$(error MY_FLAG is not set)
endif
নোট করুন যে লাইনগুলি অবশ্যই ইন্টেন্ট করা উচিত নয়। আরও স্পষ্টভাবে, কোনও ট্যাব অবশ্যই এই লাইনগুলির আগে না।
জেনেরিক সমাধান
আপনি যদি অনেকগুলি ভেরিয়েবল পরীক্ষা করতে চলেছেন তবে তার জন্য একটি সহায়ক ফাংশন সংজ্ঞায়িত করার মতো:
# Check that given variables are set and all have non-empty values,
# die with an error otherwise.
#
# Params:
# 1. Variable name(s) to test.
# 2. (optional) Error message to print.
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined $1$(if $2, ($2))))
এটি এখানে কীভাবে ব্যবহার করবেন তা এখানে:
$(call check_defined, MY_FLAG)
$(call check_defined, OUT_DIR, build directory)
$(call check_defined, BIN_DIR, where to put binary artifacts)
$(call check_defined, \
LIB_INCLUDE_DIR \
LIB_SOURCE_DIR, \
library path)
এটি এর মতো একটি ত্রুটি আউটপুট দেবে:
Makefile:17: *** Undefined OUT_DIR (build directory). Stop.
মন্তব্য:
আসল চেক এখানে করা হয়:
$(if $(value $1),,$(error ...))
এটি ifndef
শর্তাধীন আচরণকে প্রতিফলিত করে , যাতে খালি মানকে সংজ্ঞায়িত করা একটি ভেরিয়েবলটিকে "অপরিজ্ঞাত" হিসাবে বিবেচনা করা হয়। তবে এটি কেবল সহজ ভেরিয়েবল এবং স্পষ্টতই খালি পুনরাবৃত্ত ভেরিয়েবলগুলির ক্ষেত্রে সত্য:
# ifndef and check_defined consider these UNDEFINED:
explicitly_empty =
simple_empty := $(explicitly_empty)
# ifndef and check_defined consider it OK (defined):
recursive_empty = $(explicitly_empty)
মন্তব্যগুলিতে @ ভিক্টর সার্জিয়েনকো পরামর্শ অনুসারে, কিছুটা ভিন্ন আচরণ পছন্দ হতে পারে:
$(if $(value $1)
মানটি খালি না হলে পরীক্ষা করে। ভেরিয়েবলটি একটি খালি মান দিয়ে সংজ্ঞায়িত করা হয় তবে এটি কখনও কখনও ঠিক থাকে । আমি ব্যবহার করব$(if $(filter undefined,$(origin $1)) ...
এবং:
অধিকন্তু, যদি এটি একটি ডিরেক্টরির এবং এটা থাকা আবশ্যক যখন চেক সঞ্চালন করা হয়, আমি ব্যবহার করতে চাই $(if $(wildcard $1))
। তবে অন্য ফাংশন হবে।
লক্ষ্য-নির্দিষ্ট চেক
সমাধানটি প্রসারিত করাও সম্ভব যাতে একটি নির্দিষ্ট টার্গেট করা হয় তবেই কারও একটি পরিবর্তনশীল প্রয়োজন।
$(call check_defined, ...)
রেসিপি ভিতরে থেকে
কেবল চেকটিকে রেসিপিটিতে সরিয়ে ফেলুন:
foo :
@:$(call check_defined, BAR, baz value)
নেতৃস্থানীয় @
কমান্ড প্রতিধ্বনি বন্ধ চিহ্ন করিয়া এবং :
প্রকৃত কমান্ড, একটি শেল নো অপ শহরের উপর অসম্পূর্ণ নিবন্ধ ।
লক্ষ্য নাম দেখানো হচ্ছে
check_defined
ফাংশন এছাড়াও আউটপুট লক্ষ্য নাম (মাধ্যমে প্রদান করা থেকে উন্নত করা যায় $@
পরিবর্তনশীল):
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined $1$(if $2, ($2))$(if $(value @), \
required by target `$@')))
সুতরাং, এখন একটি ব্যর্থ চেক একটি সুন্দর বিন্যাসিত আউটপুট উত্পাদন করে:
Makefile:7: *** Undefined BAR (baz value) required by target `foo'. Stop.
check-defined-MY_FLAG
বিশেষ লক্ষ্য
ব্যক্তিগতভাবে আমি উপরের সহজ এবং সোজা সমাধানটি ব্যবহার করব। তবে উদাহরণস্বরূপ, এই উত্তরটি প্রকৃত চেক সম্পাদন করতে একটি বিশেষ লক্ষ্য ব্যবহার করার পরামর্শ দেয়। কেউ এটিকে সাধারণ করার চেষ্টা করতে পারে এবং লক্ষ্যটিকে একটি অন্তর্নিহিত নিদর্শন বিধ হিসাবে সংজ্ঞায়িত করতে পারে:
# Check that a variable specified through the stem is defined and has
# a non-empty value, die with an error otherwise.
#
# %: The name of the variable to test.
#
check-defined-% : __check_defined_FORCE
@:$(call check_defined, $*, target-specific)
# Since pattern rules can't be listed as prerequisites of .PHONY,
# we use the old-school and hackish FORCE workaround.
# You could go without this, but otherwise a check can be missed
# in case a file named like `check-defined-...` exists in the root
# directory, e.g. left by an accidental `make -t` invocation.
.PHONY : __check_defined_FORCE
__check_defined_FORCE :
ব্যবহার:
foo :|check-defined-BAR
লক্ষ করুন যে, check-defined-BAR
হিসেবে তালিকাভুক্ত করা হয় অর্ডার কেবল- ( |...
) পূর্বশর্ত।
পেশাদাররা:
- (যুক্তিযুক্তভাবে) আরও পরিষ্কার বাক্য গঠন
কনস:
আমি বিশ্বাস করি, কিছু eval
জাদু এবং গৌণ সম্প্রসারণ হ্যাকগুলি ব্যবহার করে এই সীমাবদ্ধতাগুলি অতিক্রম করা যেতে পারে , যদিও আমি নিশ্চিত নই যে এটির পক্ষে এটি উপযুক্ত।