ভেরিয়েবল সেট এবং ব্যবহার করতে সিএমকে সিনট্যাক্স কী?


168

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

সিএমকেতে ভেরিয়েবল সেট এবং ব্যবহার করার সিনট্যাক্সটি কী?

উত্তর:


281

সিএমকে স্ক্রিপ্টগুলি লেখার সময় আপনাকে সিনট্যাক্স এবং সিএমকে কীভাবে ভেরিয়েবল ব্যবহার করবেন সে সম্পর্কে অনেক কিছু জানতে হবে।

সিনট্যাক্স

স্ট্রিংগুলি ব্যবহার করে 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})

ডকুমেন্টেশন

স্কোপ বা "আমার ভেরিয়েবলের কী মূল্য আছে?"

প্রথমে সেখানে "নরমাল ভেরিয়েবলস" এবং সেগুলির সুযোগ সম্পর্কে আপনার প্রয়োজনীয় জিনিসগুলি রয়েছে:

  • সাধারন ভেরিয়েবল কাছে দৃশ্যমান 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আপনার বাইনারি আউটপুট ডিরেক্টরিতে ফাইলটি দেখুন । আপনার তৈরি পরিবেশের আসল প্রজন্ম ব্যর্থ হলে এই ফাইলটি উত্পন্নও হয়।
  • আপনার ভেরিয়েবলগুলি কোথায় পড়া / লিখিত / সরানো হয়েছে তা দেখতে ভেরিয়েবল_ওয়াচ () ব্যবহার করুন ।
  • ডিরেক্টরি বৈশিষ্ট্য CACHE_VARIABLES এবং VARIABLES দেখুন
  • cmake --trace ...সিএমকের সম্পূর্ণ পার্সিং প্রক্রিয়াটি দেখতে কল করুন । এটি শেষ রিজার্ভের ক্রম, কারণ এটি প্রচুর আউটপুট উত্পন্ন করে।

বিশেষ সিনট্যাক্স

  • পরিবেশের পরিবর্তনশীল
    • আপনি পরিবেশের ভেরিয়েবলগুলি পড়তে $ENV{...}এবং লিখতে পারেনset(ENV{...} ...)
  • জেনারেটর এক্সপ্রেশন
    • জেনারেটর এক্সপ্রেশনগুলি $<...>কেবল তখনই মূল্যায়ন করা হয় যখন সিএমকের জেনারেটর মেক এনভায়রনমেন্ট লিখবে (এটি পার্সার দ্বারা "ইন-প্লেস" প্রতিস্থাপিত হওয়া সাধারণ ভেরিয়েবলের সাথে তুলনা করে)
    • সংকলক / লিঙ্কার কমান্ড লাইন এবং বহু-কনফিগারেশন পরিবেশে খুব সহজ
  • তথ্যসূত্র
    • এর সাহায্যে ${${...}}আপনি একটি ভেরিয়েবলের পরিবর্তনশীল নাম দিতে পারেন এবং এর সামগ্রীটি উল্লেখ করতে পারেন reference
    • ফাংশন / ম্যাক্রো প্যারামিটার হিসাবে পরিবর্তনশীল নাম দেওয়ার সময় প্রায়শই ব্যবহৃত হয়।
  • অবিচ্ছিন্ন মান ( if()আদেশ দেখুন)
    • সঙ্গে 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)
    • সুসংবাদটি হ'ল নীতি সিএমপি 50054 প্রবর্তনের সাথে সিএমকে 3.1 এ এটি স্থির করা হয়েছিল । আমি সর্বদা cmake_policy(SET CMP0054 NEW)" if()অনাবৃত হয়ে গেলে কেবল যুক্তিগুলি পরিবর্তনশীল বা কীওয়ার্ড হিসাবে ব্যাখ্যা করতে" সেট করতে পরামর্শ দেব।
  • option()হুকুম
    • প্রধানত শুধু স্ট্রিং যে শুধুমাত্র হতে পারে ক্যাশে ONবা OFFতারা যেমন মত কিছু বিশেষ হ্যান্ডলিং অনুমতি নির্ভরতা
    • তবে সচেতন হোন , কমান্ড optionদিয়ে ভুল করবেন না set। প্রদত্ত মানটি optionসত্যই কেবলমাত্র "প্রাথমিক মান" (প্রথম কনফিগারেশনের ধাপের সময় একবার ক্যাশে স্থানান্তরিত হয়) এবং এর পরে সিএমকের জিইউআইয়ের মাধ্যমে ব্যবহারকারী পরিবর্তিত হতে পারে ।

তথ্যসূত্র


যখন আমি ব্যবহার if ("${MyString}" ...)আমি এইজন্য সতর্কবার্তা আছি: Policy CMP0054 is not set: Only interpret if() arguments as variables or keywords when unquoted। উদাহরণস্বরূপ, দেখুন 367 তৈরি করুন । কোন ধারনা?
jw

আর unquoting ${MyString}জন্য ত্রুটি একটি গুচ্ছ বিশালাকার "যদি প্রদত্ত আর্গুমেন্ট ..." মত যদি কাছাকাছি CMake ত্রুটি: "দেওয়া আর্গুমেন্ট যদি" parantheses দ্বারা অনুসরণ, "না", "সমান" এবং অনুরূপ
jw

@jww এই সতর্কতার অর্থ হ'ল MyStringএমন একটি পরিবর্তনশীল নাম রয়েছে যা পরে আবার ডি-রেফারেন্স করা হবে। আমি বিশ্বাস করি যে কেউ আসলেই সেই OLDআচরণ চায় না । সুতরাং আমার দৃষ্টিকোণ থেকে এটি সম্পূর্ণ সুরক্ষিত এবং পশ্চাদপটে সামঞ্জস্যপূর্ণ কেবল নীতি সেট CMP0054করতে NEW( এখানে আলোচনা দেখুন )।
ফ্লোরিয়ান

@jww এবং এই সমস্যাগুলি / সতর্কতাগুলি এড়ানোর সবচেয়ে নিরাপদ উপায় হল কেবলমাত্র if (MyString ...)(যদি আপনার কোডটি সতর্কতা দেয় তবে)।
ফ্লোরিয়ান

ধন্যবাদ। আমরা এর সমস্ত উপস্থিতি ${MyString}সরিয়ে দিয়ে এটিকে প্রতিস্থাপন করেছি MyString(বা আমি বিশ্বাস করি যে আমরা সেগুলি সরিয়ে দিয়েছি)। তবুও আনন্দ নেই: 372 তৈরি করুন । এমনকি আমাদের কোড থেকে ক্র্যাপ আসছে না। এটি সিএমকে থেকে আসছে বলে মনে হচ্ছে। লাইন 283 হয় if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
jw

18

দ্রুত এবং নোংরা শুরু করার জন্য এখানে কয়েকটি বুনিয়াদি উদাহরণ রয়েছে।

একটি আইটেম পরিবর্তনশীল

পরিবর্তনশীল সেট করুন:

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}")

ভেরিয়েবলগুলিতে ডকস সিএম করুন


1

$ENV{FOO}ব্যবহারের জন্য, যেখানে FOOপরিবেশ পরিবর্তনশীল থেকে নেওয়া হচ্ছে picked অন্যথায় হিসাবে ব্যবহার করুন ${FOO}, যেখানে FOOকিছু অন্যান্য পরিবর্তনশীল। সেটিংয়ের জন্য, SET(FOO "foo")সিএমকে ব্যবহার করা হবে।

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