মেকফাইলে মাল্টি-লাইন স্ট্রিং ভেরিয়েবল তৈরি করা কি সম্ভব?


122

আমি একটি মেকফিল ভেরিয়েবল তৈরি করতে চাই যা একটি বহু-লাইন স্ট্রিং (যেমন একটি ইমেল প্রকাশের ঘোষণার মূল অংশ)। কিছুটা এইরকম

ANNOUNCE_BODY="
Version $(VERSION) of $(PACKAGE_NAME) has been released

It can be downloaded from $(DOWNLOAD_URL)

etc, etc"

তবে আমি এটি করার উপায় খুঁজে পাচ্ছি না। এটা কি সম্ভব?

উত্তর:


172

হ্যাঁ, আপনি একাধিক-লাইন ভেরিয়েবলটি ঘোষণার জন্য সংজ্ঞায়িত কীওয়ার্ডটি ব্যবহার করতে পারেন:

define ANNOUNCE_BODY
Version $(VERSION) of $(PACKAGE_NAME) has been released.

It can be downloaded from $(DOWNLOAD_URL).

etc, etc.
endef

কৌতুকপূর্ণ অংশটি আপনার মাল্টি-লাইন ভেরিয়েবলটি মেকফিলের বাইরে চলে আসছে। আপনি যদি কেবল "প্রতিধ্বনি $ (ANNOUNCE_BODY)" ব্যবহারের স্পষ্ট কাজটি করেন, আপনি অন্যরা এখানে পোস্ট করেছেন এমন ফলাফলটি দেখতে পাবেন - শেলটি ভেরিয়েবলের দ্বিতীয় এবং পরবর্তী লাইনগুলি নিজেরাই কমান্ড হিসাবে পরিচালনা করার চেষ্টা করে।

যাইহোক, আপনি শেল থেকে পরিবেশের পরিবর্তনশীল হিসাবে ভেরিয়েবলের মানটি রফতানি করতে পারেন এবং তারপরে এটি শেল থেকে পরিবেশের পরিবর্তনশীল হিসাবে উল্লেখ করতে পারেন (মেক ভেরিয়েবল নয়)। উদাহরণ স্বরূপ:

export ANNOUNCE_BODY
all:
    @echo "$$ANNOUNCE_BODY"

$$ANNOUNCE_BODYশেল এনভায়রনমেন্ট ভেরিয়েবল রেফারেন্সের পরিবর্তে এর ব্যবহারটি লক্ষ্য করুন $(ANNOUNCE_BODY), যা নিয়মিতভাবে পরিবর্তনশীল রেফারেন্স হবে। এছাড়াও আপনার পরিবর্তনশীল রেফারেন্সের চারপাশে উদ্ধৃতিগুলি ব্যবহার করার বিষয়টি নিশ্চিত করুন, নিশ্চিত হয়ে নিন যে নতুন লাইনের শেল নিজেই ব্যাখ্যা করে না।

অবশ্যই, এই নির্দিষ্ট কৌশলটি প্ল্যাটফর্ম এবং শেল সংবেদনশীল হতে পারে। আমি এটি GNU ব্যাশ 3.2.13 দিয়ে উবুন্টু লিনাক্সে পরীক্ষা করেছি; YMMV।


1
export ANNOUNCE_BODYকেবলমাত্র ভেরিয়েবলের মধ্যে নিয়মগুলি সেট করে - এটি vari ANNOUNCE_BODY কে অন্যান্য ভেরিয়েবলগুলি সংজ্ঞায়িত করতে দেয় না।
অ্যানাটোলি টেকটোনিক

@ টেকটোনিক যদি আপনি ANNOUNCE_BODYঅন্যান্য ভেরিয়েবল সংজ্ঞাতে মান ব্যবহার করতে চান তবে এটি অন্য কোনও পরিবর্তনশীলের মতোই উল্লেখ করুন। উদাহরণস্বরূপ OTHER=The variable ANNOUNCE_BODY is $(ANNOUNCE_BODY),। আপনি exportযদি OTHERকমান্ডের সাথে বেরিয়ে আসতে চান তবে অবশ্যই আপনার প্রয়োজন হবে need
এরিক মেলস্কি

25

'আপনার মাল্টি-লাইন ভেরিয়েবলটি মেকফাইলের বাইরে ফিরিয়ে আনতে' (এরিক মেলস্কি দ্বারা 'ট্র্যাফিক অংশ' হিসাবে চিহ্নিত) এর জন্য আরেকটি পদ্ধতি হ'ল আপনার মাল্টি-লাইনের স্ট্রিংয়ের সাথে substপ্রবর্তিত নিউলাইনগুলি প্রতিস্থাপনের জন্য ফাংশনটি ব্যবহার করার পরিকল্পনা করা । তারপরে তাদের ব্যাখ্যার জন্য ব্যবহার করুন। এটি করা প্রতিধ্বনি পেতে আপনাকে .SHELL = ব্যাশ সেট করতে হবে। define\necho

এই পদ্ধতির একটি সুবিধা হ'ল আপনি এ জাতীয় অন্যান্য পালানো অক্ষরগুলিও আপনার পাঠ্যে রেখেছেন এবং তাদের সম্মান করেছেন।

এই ধরণের এখনও পর্যন্ত উল্লিখিত সমস্ত পদ্ধতির সংশ্লেষ করে ...

আপনি সাথে বাধা:

define newline


endef

define ANNOUNCE_BODY=
As of $(shell date), version $(VERSION) of $(PACKAGE_NAME) has been released.  

It can be downloaded from $(DOWNLOAD_URL).  

endef

someTarget:
    echo -e '$(subst $(newline),\n,${ANNOUNCE_BODY})'

চূড়ান্ত প্রতিধ্বনিতে একক উদ্ধৃতিগুলি গুরুত্বপূর্ণ Note


4
নোট করুন যে "ইকো -e" পোর্টেবল নয়। পরিবর্তে আপনার সম্ভবত প্রিন্টফ (1) পছন্দ করা উচিত।
ম্যাডসায়েন্টিস্ট

2
দুর্দান্ত উত্তর, তবে এটি চালানোর জন্য আমাকে =পরে সরিয়ে ফেলতে হয়েছিল define ANNOUNCE_BODY
মিসচিলি

13

ধরে নিই যে আপনি কেবলমাত্র আপনার ভেরিয়েবলের সামগ্রীটি স্ট্যান্ডার্ড আউটপুটে মুদ্রণ করতে চান, এর জন্য আরও একটি সমাধান রয়েছে:

do-echo:
    $(info $(YOUR_MULTILINE_VAR))

1
এটি কোন সমিতি নিয়ম কোনও অবাঞ্ছিত বার্তা উত্পাদিত: make: 'do-echo' is up to date.। একটি "কোন অপ" ব্যবহারের comand আমি এটা নীরবতা সক্ষম ছিল:@: $(info $(YOUR_MULTILINE_VAR))
Guillaume, Papin

@ গুইলাউম পেপিন কিছুটা দেরি করে গেছে, তবে আপনি .PHONYআপনার মেকফিলকে বলতে পারেন যে এই নিয়মটি পরীক্ষা করার মতো কিছুই নেই। মেকফিলগুলি মূলত সংকলকগুলির জন্য ছিল, যদি আমার ভুল makeনা হয় তবে কিছু জাদু করছে যা আমি ধারণা করতে বুঝতে পারি না যে নিয়মটি কোনও পরিবর্তন করবে না এবং যেমনটি এটি 'সম্পন্ন' বলে ধরে নিয়েছে। .PHONY do-echoআপনার ফাইলে যুক্ত করা makeএটিকে উপেক্ষা করতে এবং যেভাবেই কোড চালাতে বলবে ।
এম

আপনি $(info ...)একটি মেক রুলের বাইরে রাখতে পারেন । এটি এখনও আউটপুট উত্পন্ন করবে।
ড্যানিয়েল স্টিভেন্স


3

হ্যাঁ. আপনি নতুন লাইনের সাথে এড়িয়ে চলুন \:

VARIABLE="\
THIS IS A VERY LONG\
TEXT STRING IN A MAKE VARIABLE"

হালনাগাদ

আহ, আপনি নিউলাইন চান? তাহলে না, ভ্যানিলা মেক করার কোনও উপায় নেই বলে আমি মনে করি না। তবে আপনি সর্বদা কমান্ড অংশে একটি এখানে-নথি ব্যবহার করতে পারেন

[এটি কার্যকর হয় না, ম্যাড সায়েন্টিস্টের মন্তব্য দেখুন]

foo:
    echo <<EOF
    Here is a multiple line text
    with embedded newlines.
    EOF

এটি সত্য, তবে এটি আমাকে কোনও বিন্যাস দেয় না (নিউলাইনগুলি)। এটি কেবল
পাঠ্যর

মাল্টি-লাইন এখানে-নথিগুলি জিএনইউ মেক-এ বর্ণিত হিসাবে কাজ করে না।
ম্যাট বি।

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

2

এরিক মেলস্কির উত্তরের কেবল একটি পোস্টস্ক্রিপ্ট: আপনি পাঠ্যে কমান্ডের আউটপুট অন্তর্ভুক্ত করতে পারেন, তবে আপনাকে অবশ্যই শেল সিনট্যাক্স "f (foo)" এর পরিবর্তে Makefile সিনট্যাক্স "$ (শেল ফু)" ব্যবহার করতে হবে। উদাহরণ স্বরূপ:

define ANNOUNCE_BODY  
As of $(shell date), version $(VERSION) of $(PACKAGE_NAME) has been released.  

It can be downloaded from $(DOWNLOAD_URL).  

endef

2

এটি এখানে কোনও নথি দেয় না, তবে এটি পাইপগুলির জন্য উপযুক্ত এমন উপায়ে একটি বহু-লাইন বার্তা প্রদর্শন করে।

=====

MSG = this is a\\n\
multi-line\\n\
message

method1:
     @$(SHELL) -c "echo '$(MSG)'" | sed -e 's/^ //'

=====

আপনি গ্নুর কলযোগ্য ম্যাক্রোগুলিও ব্যবহার করতে পারেন:

=====

MSG = this is a\\n\
multi-line\\n\
message

method1:
        @echo "Method 1:"
        @$(SHELL) -c "echo '$(MSG)'" | sed -e 's/^ //'
        @echo "---"

SHOW = $(SHELL) -c "echo '$1'" | sed -e 's/^ //'

method2:
        @echo "Method 2:"
        @$(call SHOW,$(MSG))
        @echo "---"

=====

এখানে ফলাফল:

=====

$ make method1 method2
Method 1:
this is a
multi-line
message
---
Method 2:
this is a
multi-line
message
---
$

=====


1

আপনি কেন আপনার স্ট্রিংয়ে-n বর্ণটি ব্যবহার করবেন না লাইনের শেষের সংজ্ঞাটি দেওয়ার জন্য? একাধিক লাইনে এটি যুক্ত করতে অতিরিক্ত ব্যাকস্ল্যাশ যুক্ত করুন।

ANNOUNCE_BODY=" \n\
Version $(VERSION) of $(PACKAGE_NAME) has been released \n\
\n\
It can be downloaded from $(DOWNLOAD_URL) \n\
\n\
etc, etc"

আমি এরিক মেলস্কির উত্তর পছন্দ করি তবে এটি আপনার প্রয়োগের উপর নির্ভর করে আপনার জন্য ইতিমধ্যে কৌশলটি করতে পারে।
রোল্ট

আমি এই সম্পর্কে একটি প্রশ্ন পেয়েছিলাম। এটি মূলত সূক্ষ্মভাবে কাজ করে, আমি প্রতিটি লাইনের প্রারম্ভে (প্রথমটি বাদ দিয়ে) অতিরিক্ত "স্পেস" দেখি। এটি কি আপনার সাথে ঘটে? আমি সমস্ত পাঠ্যকে এক লাইনে রাখতে পারি, \ n এর দ্বারা আলাদা করে কার্যকরভাবে আমার পছন্দ মতো আউটপুট তৈরি করতে পারে। সমস্যাটি এটি মেকফাইলে নিজেই খুব কুরুচিপূর্ণ দেখাচ্ছে!
শাহবাজ

আমি একটি workaround খুঁজে পেয়েছি। আমি পাঠ্যটি দিয়েছিলাম $(subst \n ,\n,$(TEXT))যদিও আমার ইচ্ছা আরও ভাল উপায় ছিল!
শাহবাজ

1

এটি কেন কাজ করে না সে সম্পর্কে আমার উত্তর দেখুন (কমপক্ষে আমার প্রচেষ্টা থেকে)
রোল্ট

1
ম্যানুয়ালটি আপনাকে সঠিকভাবে কাজ করে তা দেখায়: ব্যবহার করুন echo
ডিঙ-ই চেন

1

আপনার নির্মাণ "সংজ্ঞায়িত / এন্ডাফ" ব্যবহার করা উচিত:

define ANNOUNCE_BODY
Version $(VERSION) of $(PACKAGE_NAME) has been released.

It can be downloaded from $(DOWNLOAD_URL).

etc, etc.
endef

তারপরে আপনার এই ভেরিয়েবলের মান শেল কমান্ডে পাঠানো উচিত। তবে, আপনি যদি ভেরিয়েবল সাবস্টিটিউশন মেক ব্যবহার করে এটি করেন তবে এটি আদেশটি একাধিকতে বিভক্ত করবে:

ANNOUNCE.txt:
  echo $(ANNOUNCE_BODY) > $@               # doesn't work

কোয়েটিং কোনওভাবেই সহায়তা করবে না।

মানটি পাস করার সর্বোত্তম উপায় হ'ল এটি পরিবেশের পরিবর্তনশীল মাধ্যমে পাস করা:

ANNOUNCE.txt: export ANNOUNCE_BODY:=$(ANNOUNCE_BODY)
ANNOUNCE.txt:
  echo "$${ANNOUNCE_BODY}" > $@

বিজ্ঞপ্তি:

  1. এই নির্দিষ্ট লক্ষ্যবস্তুর জন্য চলকটি রফতানি করা হয়, যাতে আপনি যে পরিবেশটি খুব দূষিত না হয়ে পুনরায় ব্যবহার করতে পারেন;
  2. এনভায়রনমেন্ট ভেরিয়েবল (ভেরিয়েবলের চারপাশে ডাবল কৌটস এবং কোঁকড়ানো বন্ধনী) ব্যবহার করুন;
  3. পরিবর্তনশীল চারপাশে উদ্ধৃতি ব্যবহার। এগুলি ছাড়াই নিউলাইনগুলি হারিয়ে যাবে এবং সমস্ত পাঠ্য এক লাইনে উপস্থিত হবে।

1

.ONESHLL এর চেতনায়, চূড়ান্ত পরিবেশের পক্ষে খুব কাছাকাছি যাওয়া সম্ভব ON

define _oneshell_newline_


endef

define oneshell
@eval "$$(printf '%s\n' '$(strip                            \
                         $(subst $(_oneshell_newline_),\n,  \
                         $(subst \,\/,                      \
                         $(subst /,//,                      \
                         $(subst ','"'"',$(1))))))' |       \
          sed -e 's,\\n,\n,g' -e 's,\\/,\\,g' -e 's,//,/,g')"
endef

ব্যবহারের উদাহরণটি এরকম কিছু হবে:

define TEST
printf '>\n%s\n' "Hello
World\n/$$$$/"
endef

all:
        $(call oneshell,$(TEST))

এটি আউটপুট দেখায় (পিড 27801 ধরে):

>
Hello
World\n/27801/

এই পদ্ধতির কিছু অতিরিক্ত কার্যকারিতা জন্য অনুমতি দেয়:

define oneshell
@eval "set -eux ; $$(printf '%s\n' '$(strip                            \
                                    $(subst $(_oneshell_newline_),\n,  \
                                    $(subst \,\/,                      \
                                    $(subst /,//,                      \
                                    $(subst ','"'"',$(1))))))' |       \
                     sed -e 's,\\n,\n,g' -e 's,\\/,\\,g' -e 's,//,/,g')"
endef

এই শেল বিকল্পগুলি:

  • প্রতিটি কমান্ড কার্যকর হওয়ার সাথে সাথে মুদ্রণ করুন
  • প্রথম ব্যর্থ কমান্ড থেকে প্রস্থান করুন
  • একটি ত্রুটি হিসাবে অপরিজ্ঞাত শেল ভেরিয়েবলের ব্যবহার বিবেচনা করুন

অন্যান্য আকর্ষণীয় সম্ভাবনা সম্ভবত তাদের পরামর্শ দেবে।


1

আমি আলহাদিসের উত্তরটি সবচেয়ে পছন্দ করি। তবে কলামার ফর্ম্যাটিং রাখতে আরও একটি জিনিস যুক্ত করুন।

SYNOPSIS := :: Synopsis: Makefile\
| ::\
| :: Usage:\
| ::    make .......... : generates this message\
| ::    make synopsis . : generates this message\
| ::    make clean .... : eliminate unwanted intermediates and targets\
| ::    make all ...... : compile entire system from ground-up\
endef

আউটপুট:

:: Synopsis: Makefile 
:: 
:: Usage: 
:: make .......... : generates this message 
:: make synopsis . : generates this message 
:: make clean .... : eliminate unwanted intermediates and targets 
:: make all ...... : compile entire system from ground-up

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

1
আমি বহুবার চেয়েছি কেবলমাত্র লক্ষ্যগুলি তৈরি করার তালিকাটি দেখতে। আপনার মন্তব্য কোন মানে করে না। ব্যবহারকারীরা যা প্রত্যাশা করেন তা অপ্রাসঙ্গিক হয় যদি তাদের কী করা উচিত তা জানতে 3 সেকেন্ড সময় লাগে, অন্যদিকে এই জাতীয় কোনও তথ্যের পরিবর্তে, এটি মাঝে মাঝে কয়েক ঘন্টা সময় নিতে পারে।
Xennex81

1
প্রত্যাশাকে কিছু করার কারণ হিসাবে ব্যবহার করাও একটি বিজ্ঞপ্তি যুক্তি: কারণ লোকেরা এটি প্রত্যাশা করে, আমাদের অবশ্যই এটি করা উচিত, এবং আমরা এটি করার কারণে তারা এটি প্রত্যাশা করে।
Xennex81

1

ওপির সাথে সম্পূর্ণ সম্পর্কিত নয়, তবে আশা করি এটি ভবিষ্যতে কাউকে সহায়তা করবে। (গুগল অনুসন্ধানে এই প্রশ্নটিই সবচেয়ে বেশি আসে)।

আমার মেকফাইলে, আমি কোনও ফাইলের বিষয়বস্তু, একটি ডকার বিল্ড কমান্ডের কাছে যেতে চেয়েছিলাম, অনেক কনসেন্টেশন পরে, আমি সিদ্ধান্ত নিয়েছিলাম:

 base64 encode the contents in the Makefile (so that I could have a single line and pass them as a docker build arg...)
 base64 decode the contents in the Dockerfile (and write them to a file)

নীচে উদাহরণ দেখুন।

এনবি: আমার বিশেষ ক্ষেত্রে, https://vsupalov.com/build-docker-image-clone-private-repo-ssh-key/ ( উদাহরণ ব্যবহার করে) চিত্র ব্যবহারের সময় আমি একটি এসএস কী পাস করতে চেয়েছিলাম গিট রেপো ক্লোন করতে একটি মাল্টি স্টেজ ডকার বিল্ড, তারপরে বিল্ডের ২ য় পর্যায়ে চূড়ান্ত চিত্র থেকে ssh কীটি ফেলে দিন)

Makefile নামক

...
MY_VAR_ENCODED=$(shell cat /path/to/my/file | base64)

my-build:
    @docker build \
      --build-arg MY_VAR_ENCODED="$(MY_VAR_ENCODED)" \
      --no-cache \
      -t my-docker:build .
...

Dockerfile

...
ARG MY_VAR_ENCODED

RUN mkdir /root/.ssh/  && \
    echo "${MY_VAR_ENCODED}" | base64 -d >  /path/to/my/file/in/container
... 

1

জিএনইউ মেক ৩.৮২ এবং তারপরে, .ONESHELLমাল্টিলাইন শেল স্নিপেটের ক্ষেত্রে বিকল্পটি আপনার বন্ধু। অন্যান্য উত্তর থেকে ইঙ্গিত একত্র করা, আমি পেয়েছি:

VERSION = 1.2.3
PACKAGE_NAME = foo-bar
DOWNLOAD_URL = $(PACKAGE_NAME).somewhere.net

define nwln

endef

define ANNOUNCE_BODY
Version $(VERSION) of $(PACKAGE_NAME) has been released.

It can be downloaded from $(DOWNLOAD_URL).

etc, etc.
endef

.ONESHELL:

# mind the *leading* <tab> character
version:
    @printf "$(subst $(nwln),\n,$(ANNOUNCE_BODY))"

আপনার সম্পাদকের উপরোক্ত উদাহরণটি অনুলিপি করে আটকানোর সময় নিশ্চিত করুন যে কোনও <tab>অক্ষর সংরক্ষণ করা হয়েছে, অন্যথায়version লক্ষ্যটি ভেঙে যাবে!

মনে রাখবেন যে .ONESHELLমেকফিলের সমস্ত লক্ষ্য তাদের সমস্ত কমান্ডের জন্য একটি একক শেল ব্যবহার করবে।


দুর্ভাগ্যক্রমে এটি কাজ করে না: make version printf "Version 1.2.3 of foo-bar has been released. /bin/sh: 1: Syntax error: Unterminated quoted string make: *** [version] Error 2(জিএনইউ 3,81 তৈরি করুন)
নীল বর্ণযুক্ত

@ ব্লুয়েড, আমি কেবল এটি জিএনইউ মেক 3.82 এবং জিএনইউ ব্যাশ 4.2.45 (1) - এর সাথে পরীক্ষা করেছি - দয়া করে এটি প্রত্যাশার মতো কাজ করে। এছাড়াও, দয়া করে @printf ...বিবৃতিটির সামনে ফাঁকাগুলির পরিবর্তে শীর্ষস্থানীয় টিএবি চরিত্রের উপস্থিতি যাচাই করুন - দেখে মনে হচ্ছে যে টিএবিগুলি সর্বদা 4 স্পেস হিসাবে রেন্ডার করা হয় ...
স্পহাক্কা

এটি প্রদর্শিত হয় যা .ONESHELL3.82 তৈরিতে নতুন।
নীল রঙের

বিটিডব্লিউ: কোনও ট্যাবের পরিবর্তে ফাঁকা স্থান ব্যবহার করার সময় ত্রুটি হবে *** missing separator. Stop.
নীল রঙের

0

সত্যিকারের সহায়ক উত্তর নয়, তবে কেবল এটি নির্দেশ করতে যে অক্ষর দ্বারা দেওয়া উত্তর হিসাবে 'সংজ্ঞায়িত' কাজ করে না (কোনও মন্তব্যে মাপসই হয়নি):

VERSION=4.3.1
PACKAGE_NAME=foobar
DOWNLOAD_URL=www.foobar.com

define ANNOUNCE_BODY
    Version $(VERSION) of $(PACKAGE_NAME) has been released
    It can be downloaded from $(DOWNLOAD_URL)
    etc, etc
endef

all:
    @echo $(ANNOUNCE_BODY)

এটি একটি ত্রুটি দেয় যে 'এটি' কমান্ডটি পাওয়া যায় না, সুতরাং এটি একটি আদেশ হিসাবে ANNOUNCE BODY এর দ্বিতীয় লাইনের ব্যাখ্যা করার চেষ্টা করে।


0

এটি আমার পক্ষে কাজ করেছে:

ANNOUNCE_BODY="first line\\nsecond line"

all:
    @echo -e $(ANNOUNCE_BODY)

0

জিএনইউ মেকফিল নীচের মতো জিনিসগুলি করতে পারে। এটি কুরুচিপূর্ণ, এবং আমি বলব না যে এটি করা উচিত, তবে আমি কিছু পরিস্থিতিতে করি।

PROFILE = \
\#!/bin/sh.exe\n\
\#\n\
\# A MinGW equivalent for .bash_profile on Linux.  In MinGW/MSYS, the file\n\
\# is actually named .profile, not .bash_profile.\n\
\#\n\
\# Get the aliases and functions\n\
\#\n\
if [ -f \$${HOME}/.bashrc ]\n\
then\n\
  . \$${HOME}/.bashrc\n\
fi\n\
\n\
export CVS_RSH="ssh"\n  
#
.profile:
        echo -e "$(PROFILE)" | sed -e 's/^[ ]//' >.profile

make .profile কারও অস্তিত্ব না থাকলে একটি। প্রোফাইল ফাইল তৈরি করে।

এই সমাধানটি ব্যবহার করা হয়েছিল যেখানে অ্যাপ্লিকেশনটি কেবল পসিক্স শেল পরিবেশে GNU Makefile ব্যবহার করবে। প্রকল্পটি কোনও ওপেন সোর্স প্রকল্প নয় যেখানে প্ল্যাটফর্মের সামঞ্জস্যতা একটি সমস্যা।

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

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


0

আমি বিশ্বাস করি ক্রস-প্ল্যাটফর্ম ব্যবহারের সবচেয়ে নিরাপদ উত্তর হ'ল প্রতি লাইনে একটি প্রতিধ্বনি ব্যবহার করা:

  ANNOUNCE.txt:
    rm -f $@
    echo "Version $(VERSION) of $(PACKAGE_NAME) has been released" > $@
    echo "" >> $@
    echo "It can be downloaded from $(DOWNLOAD_URL)" >> $@
    echo >> $@
    echo etc, etc" >> $@

এটি প্রতিধ্বনির সংস্করণ উপলক্ষে কোনও অনুমান করা এড়ানো যায়।


0

স্ট্রিং প্রতিস্থাপন ব্যবহার করুন :

VERSION := 1.1.1
PACKAGE_NAME := Foo Bar
DOWNLOAD_URL := https://go.get/some/thing.tar.gz

ANNOUNCE_BODY := Version $(VERSION) of $(PACKAGE_NAME) has been released. \
    | \
    | It can be downloaded from $(DOWNLOAD_URL) \
    | \
    | etc, etc

তারপর আপনার রেসিপি, রাখুন

    @echo $(subst | ,$$'\n',$(ANNOUNCE_BODY))

এটি কাজ করে কারণ মেকটি সমস্ত ঘটনাকে (স্থানটি নোট করুন) প্রতিস্থাপন করছে এবং এটি একটি নতুন লাইন অক্ষর ( $$'\n') দিয়ে অদলবদল করছে । আপনি সমতুল্য শেল-স্ক্রিপ্টের আমন্ত্রণগুলি এই জাতীয় কিছু হিসাবে ভাবতে পারেন:

আগে:

$ echo "Version 1.1.1 of Foo Bar has been released. | | It can be downloaded from https://go.get/some/thing.tar.gz | | etc, etc"

পরে:

$ echo "Version 1.1.1 of Foo Bar has been released.
>
> It can be downloaded from https://go.get/some/thing.tar.gz
> 
> etc, etc"

আমি নিশ্চিত $'\n'নন-পসিক্স সিস্টেমে উপলব্ধ কিনা , তবে আপনি যদি একটি একক নতুন লাইন অক্ষরে (এমনকি বাহ্যিক ফাইল থেকে স্ট্রিং পড়েও) অ্যাক্সেস পেতে পারেন তবে অন্তর্নিহিত নীতিটি একই।

আপনার যদি এর মতো অনেক বার্তা থাকে তবে আপনি ম্যাক্রো ব্যবহার করে শব্দ কমিয়ে দিতে পারেন :

print = $(subst | ,$$'\n',$(1))

আপনি যেখানে এটির অনুরোধ করবেন:

@$(call print,$(ANNOUNCE_BODY))

আশা করি এটি কারও সাহায্য করবে। =)


আমি এই এক ভাল পছন্দ। তবে কলামার ফর্ম্যাটিং রাখতে আরও একটি জিনিস যুক্ত করুন। Y SYNOPSIS: = :: সংক্ষিপ্তসার: মেকফিল \ | :: \ | :: ব্যবহার: \ | :: Make ..........: এই বার্তাটি উত্পন্ন করে \ | :: সংক্ষিপ্তসার তৈরি করুন। : এই বার্তা উত্পন্ন। | :: পরিষ্কার করুন ....: অবাঞ্ছিত মধ্যস্থতাকারী এবং লক্ষ্যগুলি eliminate | :: সমস্ত তৈরি করুন ......: গ্রাউন্ড-আপ থেকে পুরো সিস্টেমটি সংকলন করুন \ এন্ডেফ
জ্লেটভিন

মন্তব্যগুলি কোডের অনুমতি দেয় না। উত্তর হিসাবে প্রেরণ করবে। আমি এই এক ভাল পছন্দ। তবে কলামার ফর্ম্যাটিং রাখতে আরও একটি জিনিস যুক্ত করুন। Y SYNOPSIS: = :: সংক্ষিপ্তসার: মেকফিল`। | :: `` | :: ব্যবহার: `` | :: তৈরি করুন ..........: এই বার্তাটি তৈরি করে `` | :: সংক্ষিপ্তসার তৈরি করুন। : এই বার্তাটি তৈরি করে `` | :: পরিষ্কার করুন ....: অবাঞ্ছিত মধ্যস্থতাকারী এবং লক্ষ্যগুলি নির্মূল করুন `। | :: সমস্ত তৈরি করুন ......: গ্রাউন্ড-আপ `এন্ডেফ` থেকে পুরো সিস্টেমটি সংকলন করুন
জ্লেটভিন

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

0

বিকল্প হিসাবে আপনি printf কমান্ডটি ব্যবহার করতে পারেন। এটি কম বৈশিষ্ট্যযুক্ত ওএসএক্স বা অন্যান্য প্ল্যাটফর্মগুলিতে সহায়ক।

কেবলমাত্র একটি বহুমাত্রিক বার্তা আউটপুট করতে:

all:
        @printf '%s\n' \
            'Version $(VERSION) has been released' \
            '' \
            'You can download from URL $(URL)'

আপনি যদি অন্য প্রোগ্রামে আর্গ হিসাবে স্ট্রিংটি পাস করার চেষ্টা করছেন তবে আপনি এটি করতে পারেন:

all:
        /some/command "`printf '%s\n' 'Version $(VERSION) has been released' '' 'You can download from URL $(URL)'`"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.