উত্তর:
সিএমকে স্ক্রিপ্টগুলি লেখার সময় আপনাকে সিনট্যাক্স এবং সিএমকে কীভাবে ভেরিয়েবল ব্যবহার করবেন সে সম্পর্কে অনেক কিছু জানতে হবে।
স্ট্রিংগুলি ব্যবহার করে set()
:
set(MyString "Some Text")
set(MyStringWithVar "Some other Text: ${MyString}")
set(MyStringWithQuot "Some quote: \"${MyStringWithVar}\"")
বা সাথে string()
:
string(APPEND MyStringWithContent " ${MyString}")
ব্যবহারের তালিকা set()
:
set(MyList "a" "b" "c")
set(MyList ${MyList} "d")
বা এর সাথে আরও ভাল list()
:
list(APPEND MyList "a" "b" "c")
list(APPEND MyList "d")
ফাইলের নামের তালিকা:
set(MySourcesList "File.name" "File with Space.name")
list(APPEND MySourcesList "File.name" "File with Space.name")
add_excutable(MyExeTarget ${MySourcesList})
set()
কমান্ডstring()
কমান্ডlist()
কমান্ডপ্রথমে সেখানে "নরমাল ভেরিয়েবলস" এবং সেগুলির সুযোগ সম্পর্কে আপনার প্রয়োজনীয় জিনিসগুলি রয়েছে:
CMakeLists.txt
তারা এবং সবকিছু বলা নির্ধারণ করা হয় থেকে সেখানে ( add_subdirectory()
, include()
, macro()
এবং function()
)।add_subdirectory()
এবং function()
কমান্ড, বিশেষ কারণ তারা খুলুন-আপ তাদের নিজস্ব সুযোগ।
set(...)
কেবল সেখানে দৃশ্যমান রয়েছে এবং তারা স্কোপ স্তরের সমস্ত সাধারণ ভেরিয়েবলের একটি অনুলিপি তৈরি করে যা তাদের বলা হয় (প্যারেন্ট স্কোপ নামে পরিচিত)।set(... PARENT_SCOPE)
function(xyz _resultVar)
স্থাপন করা হয়set(${_resultVar} 1 PARENT_SCOPE)
include()
বা macro()
স্ক্রিপ্টগুলি ভেরিয়েবলগুলি সেখান থেকে ডেকে আনা হয়েছে সেই সুযোগে সরাসরি পরিবর্তন করবে।দ্বিতীয়টি "গ্লোবাল ভেরিয়েবল ক্যাশে" রয়েছে। ক্যাশে সম্পর্কে আপনার যে বিষয়গুলি জানতে হবে:
CMakeCache.txt
আপনার বাইনারি আউটপুট ডিরেক্টরিতে ফাইলটিতে সংরক্ষণ করা হয় ।ক্যাশের মানগুলি সিএমকেসের জিইউআই অ্যাপ্লিকেশনটিতে তৈরি হওয়ার আগে তাদের সংশোধন করা যেতে পারে । সুতরাং তারা - সাধারণ ভেরিয়েবলের তুলনায় - এর একটি type
এবং একটি রয়েছে docstring
। আমি সাধারণত জিইউআই ব্যবহার করি না তাই আমি set(... CACHE INTERNAL "")
আমার বৈশ্বিক এবং দৃistant় মানগুলি সেট করতে ব্যবহার করি।
দয়া করে নোট করুন যে INTERNAL
ক্যাশে ভেরিয়েবল টাইপটি বোঝায়FORCE
সিএমকে স্ক্রিপ্টে আপনি কেবলমাত্র বিদ্যমান ক্যাশে এন্ট্রি পরিবর্তন করতে পারবেন যদি আপনি set(... CACHE ... FORCE)
বাক্য গঠন ব্যবহার করেন । এই আচরণটি সিএমকে নিজেই ব্যবহার করে তৈরি করেছেন, কারণ এটি সাধারণত ক্যাশে প্রবেশকে বাধ্য করে না এবং তাই আপনি এটি অন্য কোনও মান দিয়ে প্রাক-সংজ্ঞায়িত করতে পারেন।
cmake -D var:type=value
কেবল cmake -D var=value
বা সাথে সিনট্যাক্সের সাহায্যে ক্যাশে প্রবেশের জন্য কমান্ড লাইনটি ব্যবহার করতে পারেন cmake -C CMakeInitialCache.cmake
।unset(... CACHE)
।ক্যাশেটি বিশ্বব্যাপী এবং আপনি এগুলি আপনার সিএমকে স্ক্রিপ্টগুলিতে কার্যত যে কোনও জায়গায় সেট করতে পারেন। তবে আমি আপনাকে ক্যাশে ভেরিয়েবলগুলি কোথায় ব্যবহার করতে হবে সে সম্পর্কে দুবার চিন্তা করার পরামর্শ দিচ্ছি (সেগুলি বিশ্বব্যাপী এবং তারা দৃ pers় প্রতিরোধী)। আমি সাধারণত পছন্দ করা set_property(GLOBAL PROPERTY ...)
এবং set_property(GLOBAL APPEND PROPERTY ...)
বাক্য গঠন আমার নিজের অ persistant গ্লোবাল ভেরিয়েবল সংজ্ঞায়িত করতে।
সমস্যাগুলি এড়াতে আপনার ভেরিয়েবল সম্পর্কে নিম্নলিখিত বিষয়গুলি জানতে হবে:
find_...
কমান্ড - সফল তাহলে - ক্যাশে ভেরিয়েবল যেমন তাদের ফলাফল লিখতে do "তাই কোনও কল আবার অনুসন্ধান করবে"set(MyVar a b c)
হয় "a;b;c"
এবং set(MyVar "a b c")
হয়"a b c"
list()
তালিকা পরিচালনার জন্য কমান্ডটি পছন্দ করুনfunctions()
পরিবর্তে এটি ব্যবহার করার পরামর্শ দেওয়া হয়েছে macros()
কারণ আপনি চান না যে আপনার স্থানীয় ভেরিয়েবলগুলি প্যারেন্ট স্কোপটিতে প্রদর্শিত হবে।project()
এবং enable_language()
কলগুলির সাথে সেট করা আছে । সুতরাং এই কমান্ডগুলি ব্যবহার করার আগে কিছু ভেরিয়েবল সেট করা গুরুত্বপূর্ণ হয়ে উঠতে পারে।কখনও কখনও কেবল ডিবাগিং ভেরিয়েবলগুলি সহায়তা করে। নিম্নলিখিত আপনাকে সাহায্য করতে পারে:
printf
ব্যবহার করে কেবল পুরানো ডিবাগিং স্টাইলটি ব্যবহার করুন message()
। সিএমকেটে নিজেই প্রেরিত মডিউলগুলি ব্যবহারের জন্য কিছু প্রস্তুত রয়েছে: সিএমকেকপ্রিন্টহেল্পারস.কম , সিএমকেপ্রিন্টসিসটেমি ইনফরমেশন.কমCMakeCache.txt
আপনার বাইনারি আউটপুট ডিরেক্টরিতে ফাইলটি দেখুন । আপনার তৈরি পরিবেশের আসল প্রজন্ম ব্যর্থ হলে এই ফাইলটি উত্পন্নও হয়।cmake --trace ...
সিএমকের সম্পূর্ণ পার্সিং প্রক্রিয়াটি দেখতে কল করুন । এটি শেষ রিজার্ভের ক্রম, কারণ এটি প্রচুর আউটপুট উত্পন্ন করে।$ENV{...}
এবং লিখতে পারেনset(ENV{...} ...)
$<...>
কেবল তখনই মূল্যায়ন করা হয় যখন সিএমকের জেনারেটর মেক এনভায়রনমেন্ট লিখবে (এটি পার্সার দ্বারা "ইন-প্লেস" প্রতিস্থাপিত হওয়া সাধারণ ভেরিয়েবলের সাথে তুলনা করে)${${...}}
আপনি একটি ভেরিয়েবলের পরিবর্তনশীল নাম দিতে পারেন এবং এর সামগ্রীটি উল্লেখ করতে পারেন referenceif()
আদেশ দেখুন)
if(MyVariable)
আপনি সরাসরি সত্য / মিথ্যা জন্য একটি পরিবর্তনশীল (এনক্লোজিং জন্য কোন প্রয়োজন এখানে পরীক্ষা করতে পারবেন ${...}
)1
, ON
, YES
, TRUE
, Y
, অথবা একটি নন-জিরো সংখ্যা।0
, OFF
, NO
, FALSE
, N
, IGNORE
, NOTFOUND
, খালি স্ট্রিং, বা প্রত্যয় প্রান্ত মধ্যে -NOTFOUND
।if(MSVC)
কোনও কিছুর জন্য ব্যবহার করা হয় তবে এই সিনট্যাক্স শর্টকাটটি জানেন না এমন ব্যক্তির পক্ষে এটি বিভ্রান্তিকর হতে পারে।set(CMAKE_${lang}_COMPILER ...)
if()
আদেশগুলিতে মাথা ব্যাথা দিতে পারে । এখানে একটি উদাহরণ কোথায় CMAKE_CXX_COMPILER_ID
হয় "MSVC"
এবং MSVC
হয় "1"
:
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
সত্য, কারণ এটি মূল্যায়ন করে if("1" STREQUAL "1")
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
এটি মিথ্যা, কারণ এটি মূল্যায়ন করে if("MSVC" STREQUAL "1")
if(MSVC)
cmake_policy(SET CMP0054 NEW)
" if()
অনাবৃত হয়ে গেলে কেবল যুক্তিগুলি পরিবর্তনশীল বা কীওয়ার্ড হিসাবে ব্যাখ্যা করতে" সেট করতে পরামর্শ দেব।option()
হুকুম
ON
বা OFF
তারা যেমন মত কিছু বিশেষ হ্যান্ডলিং অনুমতি নির্ভরতাoption
দিয়ে ভুল করবেন না set
। প্রদত্ত মানটি option
সত্যই কেবলমাত্র "প্রাথমিক মান" (প্রথম কনফিগারেশনের ধাপের সময় একবার ক্যাশে স্থানান্তরিত হয়) এবং এর পরে সিএমকের জিইউআইয়ের মাধ্যমে ব্যবহারকারী পরিবর্তিত হতে পারে ।${MyString}
জন্য ত্রুটি একটি গুচ্ছ বিশালাকার "যদি প্রদত্ত আর্গুমেন্ট ..." মত যদি কাছাকাছি CMake ত্রুটি: "দেওয়া আর্গুমেন্ট যদি" parantheses দ্বারা অনুসরণ, "না", "সমান" এবং অনুরূপ ।
MyString
এমন একটি পরিবর্তনশীল নাম রয়েছে যা পরে আবার ডি-রেফারেন্স করা হবে। আমি বিশ্বাস করি যে কেউ আসলেই সেই OLD
আচরণ চায় না । সুতরাং আমার দৃষ্টিকোণ থেকে এটি সম্পূর্ণ সুরক্ষিত এবং পশ্চাদপটে সামঞ্জস্যপূর্ণ কেবল নীতি সেট CMP0054
করতে NEW
( এখানে আলোচনা দেখুন )।
if (MyString ...)
(যদি আপনার কোডটি সতর্কতা দেয় তবে)।
${MyString}
সরিয়ে দিয়ে এটিকে প্রতিস্থাপন করেছি MyString
(বা আমি বিশ্বাস করি যে আমরা সেগুলি সরিয়ে দিয়েছি)। তবুও আনন্দ নেই: 372 তৈরি করুন । এমনকি আমাদের কোড থেকে ক্র্যাপ আসছে না। এটি সিএমকে থেকে আসছে বলে মনে হচ্ছে। লাইন 283 হয় if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
।
দ্রুত এবং নোংরা শুরু করার জন্য এখানে কয়েকটি বুনিয়াদি উদাহরণ রয়েছে।
পরিবর্তনশীল সেট করুন:
SET(INSTALL_ETC_DIR "etc")
পরিবর্তনশীল ব্যবহার করুন:
SET(INSTALL_ETC_CROND_DIR "${INSTALL_ETC_DIR}/cron.d")
পরিবর্তনশীল সেট করুন:
SET(PROGRAM_SRCS
program.c
program_utils.c
a_lib.c
b_lib.c
config.c
)
পরিবর্তনশীল ব্যবহার করুন:
add_executable(program "${PROGRAM_SRCS}")
if ("${MyString}" ...)
আমি এইজন্য সতর্কবার্তা আছি:Policy CMP0054 is not set: Only interpret if() arguments as variables or keywords when unquoted
। উদাহরণস্বরূপ, দেখুন 367 তৈরি করুন । কোন ধারনা?