সি ++ প্রকল্প সংগঠন (গেমস্টে, ক্যামেক এবং ডক্সিজেন সহ)


123

আমি সাধারণভাবে প্রোগ্রামিংয়ে নতুন আছি তাই আমি সিদ্ধান্ত নিয়েছি যে আমি সি ++ তে একটি সাধারণ ভেক্টর ক্লাস তৈরি করে শুরু করব। তবে আমি আমার ওয়ার্কফ্লো পরে পরিবর্তিত করার চেয়ে বরং শুরু থেকেই ভাল অভ্যাসে যেতে চাই।

আমার কাছে বর্তমানে কেবল দুটি ফাইল vector3.hppএবং vector3.cpp। এই প্রকল্পটি ধীরে ধীরে বৃদ্ধি পেতে শুরু করবে (এটি একটি সাধারণ লিনিয়ার বীজগণিত গ্রন্থাগারের অনেক বেশি করে তোলে) যেহেতু আমি প্রতিটি কিছুর সাথে আরও পরিচিত হয়ে উঠছি, তাই আমি পরবর্তীকালে জীবনকে আরও সহজ করার জন্য একটি "স্ট্যান্ডার্ড" প্রকল্পের বিন্যাস গ্রহণ করতে চাই। তাই আশেপাশে দেখার পরে আমি এইচপিপি এবং সিপিপি ফাইলগুলি পরিচালনা করার দুটি উপায় খুঁজে পেয়েছি, প্রথমটি হচ্ছে:

project
└── src
    ├── vector3.hpp
    └── vector3.cpp

এবং দ্বিতীয় সত্তা:

project
├── inc
   └── project
       └── vector3.hpp
└── src
    └── vector3.cpp

আপনি কোনটি সুপারিশ করবেন এবং কেন?

দ্বিতীয়ত আমি আমার কোডটি পরীক্ষার জন্য গুগল সি ++ টেস্টিং ফ্রেমওয়ার্কটি ব্যবহার করতে মোটামুটি সহজ বলে মনে করি। আপনি কি আমার কোড দিয়ে এটিকে বান্ডিল করার পরামর্শ দিচ্ছেন, উদাহরণস্বরূপ কোনও inc/gtestবা contrib/gtestফোল্ডারে? যদি বান্ডিল হয়, আপনি fuse_gtest_files.pyসংখ্যা বা ফাইলগুলি হ্রাস করতে স্ক্রিপ্টটি ব্যবহার করার পরামর্শ দিচ্ছেন বা এটি যেমন রেখেছেন? যদি বান্ডিল না হয় তবে এই নির্ভরতা কীভাবে পরিচালনা করা হয়?

যখন লেখার পরীক্ষার কথা আসে, সাধারণত এগুলি কীভাবে সংগঠিত হয়? আমি প্রতিটি ক্লাসের জন্য একটি সিপিপি ফাইল রাখার কথা ভাবছিলাম ( test_vector3.cppউদাহরণস্বরূপ) তবে সমস্তগুলি একটি বাইনারিতে সংকলিত হয়েছে যাতে সেগুলি সহজেই একসাথে চালানো যায়?

যেহেতু গেষ্ট গ্রন্থাগারটি সাধারণত চতুর এবং মেক ব্যবহার করে তৈরি করা হয়, তাই আমি ভাবছিলাম যে আমার প্রকল্পটিও এটির মতো নির্মিত হবে? যদি আমি নিম্নলিখিত প্রকল্পের বিন্যাসটি ব্যবহার করার সিদ্ধান্ত নিয়েছি:

├── CMakeLists.txt
├── contrib
   └── gtest
       ├── gtest-all.cc
       └── gtest.h
├── docs
   └── Doxyfile
├── inc
   └── project
       └── vector3.cpp
├── src
   └── vector3.cpp
└── test
    └── test_vector3.cpp

কীভাবে দেখতে হবে CMakeLists.txtযাতে এটি হয় কেবল গ্রন্থাগার বা গ্রন্থাগার এবং পরীক্ষাগুলি তৈরি করতে পারে? এছাড়াও আমি বেশ কয়েকটি প্রকল্প দেখেছি যার একটি buildএবং একটি binডিরেক্টরি রয়েছে। বিল্ডটি কি বিল্ড ডিরেক্টরিতে ঘটে এবং তারপরে বাইনারিগুলি বিন ডিরেক্টরিতে চলে যায়? পরীক্ষাগুলির জন্য বাইনারিগুলি এবং গ্রন্থাগারটি কি একই জায়গায় থাকবে? অথবা এটি নীচে হিসাবে এটি কাঠামো আরও জ্ঞান করতে হবে:

test
├── bin
├── build
└── src
    └── test_vector3.cpp

আমি আমার কোড ডকুমেন্ট করতে ডক্সিজেন ব্যবহার করতে চাই। এটি কি স্বয়ংক্রিয়ভাবে cmake দিয়ে চালানো এবং তৈরি করা সম্ভব?

অনেক প্রশ্নের জন্য দুঃখিত, তবে আমি সি ++ তে কোনও বই পাইনি যা এই ধরণের প্রশ্নের সন্তোষজনকভাবে উত্তর দেয়।


6
দুর্দান্ত প্রশ্ন, তবে আমি মনে করি না এটি স্ট্যাক ওভারফ্লোর প্রশ্নোত্তর বিন্যাসের জন্য উপযুক্ত। যদিও আমি একটি উত্তর খুব আগ্রহী। +1 এবং ফেভ
লুচিয়ান গ্রিগোর

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

উত্তর:


84

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

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

└── prj
    ├── include
       └── prj
           ├── header2.h
           └── header.h
    └── src
        └── x.cpp

ভাল কাজ করে, কারণ অন্তর্ভুক্ত পাথগুলি কার্যকর হয় এবং আপনি লক্ষ্যগুলি ইনস্টল করার জন্য সহজে গ্লোব্বিং ব্যবহার করতে পারেন।

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

কীভাবে তৈরি করবেন: ইন-সোর্স বিল্ডগুলি এড়িয়ে চলুন। সিএমকে উত্স-বিল্ডগুলি সহজ করে তোলে এবং এটি জীবনকে অনেক সহজ করে তোলে।

আমি মনে করি আপনিও আপনার সিস্টেমে পরীক্ষা চালানোর জন্য সিটিস্টেস্ট ব্যবহার করতে চান (এটি জিটিস্টের জন্য বিল্ট-ইন সাপোর্ট সহ আসে)। ডিরেক্টরি বিন্যাস এবং পরীক্ষা সংস্থার জন্য একটি গুরুত্বপূর্ণ সিদ্ধান্ত হবে: আপনি কি সাবপ্রজেক্টগুলি দিয়ে শেষ করেন? যদি তা হয়, সিএমকেলিস্টস সেট আপ করার সময় আপনার আরও কিছু কাজ প্রয়োজন এবং আপনার সাব-প্রকল্পগুলি উপ-ডিরেক্টরিতে বিভক্ত করা উচিত, যার প্রতিটি তার নিজস্ব includeএবং srcফাইল সহ। এমনকি তাদের নিজস্ব ডক্সিজেন রান এবং আউটপুটগুলি (একাধিক ডক্সিজেন প্রকল্পের সংমিশ্রণ সম্ভব, তবে সহজ বা সুন্দর নয়)।

আপনি এরকম কিছু দিয়ে শেষ করবেন:

└── prj
    ├── CMakeLists.txt <-- (1)
    ├── include
       └── prj
           ├── header2.hpp
           └── header.hpp
    ├── src
       ├── CMakeLists.txt <-- (2)
       └── x.cpp
    └── test
        ├── CMakeLists.txt <-- (3)
        ├── data
           └── testdata.yyy
        └── testcase.cpp

কোথায়

  • (1) নির্ভরতা, প্ল্যাটফর্মের বিশদ এবং আউটপুট পাথগুলি কনফিগার করে
  • (২) আপনি যে লাইব্রেরিটি তৈরি করতে যাচ্ছেন তা কনফিগার করে
  • (3) পরীক্ষা এক্সিকিউটেবল এবং টেস্ট-কেসগুলি কনফিগার করে

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

ডক্সিজেন: আপনি ডক্সিজেনের কনফিগারেশন নৃত্যটি পরিচালনা করার পরে, add_custom_commandডক লক্ষ্য যুক্ত করতে সিএমকে ব্যবহার করা তুচ্ছ ।

এইভাবে আমার প্রকল্পগুলি শেষ হয়ে গিয়েছিল এবং আমি বেশ কিছু অনুরূপ প্রকল্প দেখেছি, তবে অবশ্যই এটি কোনও নিরাময় নয়।

সংযোজন কিছু সময় আপনি config.hpp একটি সংস্করণ সংজ্ঞায়িত এবং সম্ভবত কিছু সংস্করণ নিয়ন্ত্রণ শনাক্তকারী (একটি গিট হ্যাশ বা এসভিএন পুনর্বিবেচনা নম্বর) একটি সংজ্ঞায়িত একটি ফাইল তৈরি করতে চান । সিএমকে এই তথ্যটি সন্ধান করতে এবং ফাইলগুলি তৈরি করতে স্বয়ংক্রিয় করার মডিউল রয়েছে। আপনি এর configure_fileভিতরে সংজ্ঞায়িত ভেরিয়েবলগুলির সাথে টেমপ্লেট ফাইলে ভেরিয়েবলগুলি প্রতিস্থাপন করতে সিএমকে ব্যবহার করতে পারেন CMakeLists.txt

আপনি যদি লাইব্রেরি তৈরি করে থাকেন তবে কমপাইলারগুলির মধ্যে পার্থক্য ডান যেমন আপনার __declspecএমএসভিসি এবং visibilityজিসিসি / ক্ল্যাংয়ের বৈশিষ্ট্যগুলির মধ্যে পার্থক্য পেতে আপনার একটি রফতানি সংজ্ঞাও প্রয়োজন ।


2
উত্তম উত্তর, তবে আপনাকে কেন নিজের হেডার ফাইলগুলিকে একটি অতিরিক্ত প্রকল্প-নামের সাব-ডাইরেক্টরি: "/prj/incolve/prj/foo.hpp" রাখতে হবে তা আমার কাছে এখনও অস্পষ্ট, যা আমার কাছে অপ্রয়োজনীয় বলে মনে হয়। কেন কেবল "/prj/incolve/foo.hpp" নয়? আমি ধরে নিচ্ছি যে ইনস্টলেশনের সময় আপনার কাছে ইনস্টলেশন ডিরেক্টরিগুলি পুনরায় জিগ করার সুযোগ থাকবে, সুতরাং আপনি ইনস্টল করার সময় <INSTALL_DIR> /incolve/prj/foo.hpp পাবেন, বা সিএমকেকের অধীনে কি এটি কঠিন?
উইলিয়াম পায়েেন

6
@ উইলিয়াম সিপ্যাকটি করা আসলেই কঠিন। এছাড়াও, আপনার অভ্যন্তরীণ উত্স ফাইলগুলি কীভাবে অন্তর্ভুক্ত থাকবে? যদি তারা ইনস্টল করা সংস্করণ "/ usr / অন্তর্ভুক্ত / prj /" এ কেবল "শিরোনাম hpp" থাকে তবে কেবল "/ usr / অন্তর্ভুক্ত" এর বিপরীতে অন্তর্ভুক্ত পথে থাকা দরকার।
বিকাল

37

স্টার্টার হিসাবে, ডিরেক্টরিগুলির জন্য কিছু প্রচলিত নাম রয়েছে যা আপনি উপেক্ষা করতে পারবেন না, এটি ইউনিক্স ফাইল সিস্টেমের সাথে দীর্ঘ traditionতিহ্যের উপর ভিত্তি করে। এইগুলো:

trunk
├── bin     : for all executables (applications)
├── lib     : for all other binaries (static and shared libraries (.so or .dll))
├── include : for all header files
├── src     : for source files
└── doc     : for documentation

কমপক্ষে শীর্ষ-স্তরে এই বেসিক লেআউটটিতে লেগে থাকা সম্ভবত একটি ভাল ধারণা।

শিরোনাম ফাইল এবং উত্স ফাইল (সিপিপি) বিভক্ত সম্পর্কে, উভয় স্কিমই মোটামুটি সাধারণ। যাইহোক, আমি তাদের একসাথে রাখা পছন্দ করি, ফাইলগুলি একসাথে রাখাই প্রতিদিন কাজকর্মের জন্য আরও বেশি ব্যবহারিক। এছাড়াও, যখন সমস্ত কোড এক শীর্ষ-স্তরের ফোল্ডারের অধীনে থাকে, অর্থাৎ, trunk/src/ফোল্ডারটি, আপনি লক্ষ্য করতে পারেন যে অন্যান্য সমস্ত ফোল্ডার (বিন, লিব, অন্তর্ভুক্ত, ডক এবং সম্ভবত কিছু পরীক্ষার ফোল্ডার) শীর্ষ স্তরে রয়েছে, পাশাপাশি কোনও উত্স-নির্মানের জন্য "বিল্ড" ডিরেক্টরিটি হ'ল সমস্ত ফোল্ডার যা বিল্ড প্রক্রিয়াতে উত্পন্ন ফাইলগুলি ছাড়া আর কিছুই থাকে না। এবং এইভাবে, কেবলমাত্র এসআরসি ফোল্ডারটির একটি সংস্করণ নিয়ন্ত্রণ সিস্টেম / সার্ভারের (গিট বা এসভিএন এর মতো) অধীনে রাখা বা আরও অনেক ভাল হওয়া দরকার up

এবং যখন গন্তব্য সিস্টেমে আপনার শিরোলেখ ফাইলগুলি ইনস্টল করার বিষয়টি আসে (আপনি যদি শেষ পর্যন্ত আপনার লাইব্রেরিটি বিতরণ করতে চান) তবে ভাল, সিএমকে ফাইলগুলি ইনস্টল করার জন্য একটি কমান্ড রয়েছে (স্পষ্টতই "ইনস্টল করুন" লক্ষ্য তৈরি করে "" ইনস্টল করুন "করতে") যা আপনি /usr/include/ডিরেক্টরিতে সমস্ত শিরোলেখ ব্যবহার করতে পারেন । আমি এই উদ্দেশ্যে নিম্নলিখিত cmake ম্যাক্রো ব্যবহার করি:

# custom macro to register some headers as target for installation:
#  setup_headers("/path/to/header/something.h" "/relative/install/path")
macro(setup_headers HEADER_FILES HEADER_PATH)
  foreach(CURRENT_HEADER_FILE ${HEADER_FILES})
    install(FILES "${SRCROOT}${CURRENT_HEADER_FILE}" DESTINATION "${INCLUDEROOT}${HEADER_PATH}")
  endforeach(CURRENT_HEADER_FILE)
endmacro(setup_headers)

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

উক্তি: দ্বিতীয়ত আমি আমার কোডটি একক পরীক্ষার জন্য গুগল সি ++ টেস্টিং ফ্রেমওয়ার্কটি ব্যবহার করা মোটামুটি সহজ বলে মনে করি। আপনি কি আমার কোড দিয়ে এটিকে বান্ডিল করার পরামর্শ দিচ্ছেন, উদাহরণস্বরূপ "ইনক / গেস্ট" বা "অবদান / গেস্ট" ফোল্ডারে? যদি বান্ডিল হয়, আপনি সংখ্যা বা ফাইলগুলি হ্রাস করতে fuse_gtest_files.py স্ক্রিপ্টটি ব্যবহার করার বা এটি যেমন রেখে দেওয়ার পরামর্শ দিচ্ছেন? যদি বান্ডিল না হয় তবে এই নির্ভরতা কীভাবে পরিচালনা করা হয়?

আপনার লাইব্রেরির সাথে নির্ভরতা বান্ডিল করবেন না। এটি সাধারণত একটি দুর্দান্ত ভয়ঙ্কর ধারণা এবং যখন আমি একটি লাইব্রেরি তৈরির চেষ্টা করতে গিয়ে আটকে যাই তখন আমি সর্বদা এটি ঘৃণা করি। এটি আপনার শেষ অবলম্বন হওয়া উচিত এবং সমস্যাগুলি থেকে সাবধান থাকুন। প্রায়শই লোকেরা তাদের লাইব্রেরির সাথে নির্ভরতা বান্ডিল করে কারণ তারা একটি ভয়াবহ বিকাশ পরিবেশ (যেমন উইন্ডোজ) টার্গেট করে, বা কারণ তারা কেবল প্রশ্নে গ্রন্থাগারের (নির্ভরতা) এর একটি পুরানো (অবচয়) সংস্করণ সমর্থন করে। মূল ক্ষতিটি হ'ল আপনার বান্ডেলড নির্ভরতা একই গ্রন্থাগার / অ্যাপ্লিকেশনটির ইতিমধ্যে ইনস্টল করা সংস্করণগুলির সাথে সংঘর্ষ হতে পারে (উদাহরণস্বরূপ, আপনি ব্রেস্টেল গেস্ট করেছেন, তবে আপনার লাইব্রেরিটি তৈরির চেষ্টা করা ব্যক্তি ইতিমধ্যে ইনস্টল হওয়া জাস্টের নতুন (বা পুরানো) সংস্করণ রয়েছে, তারপরে দু'জনে সংঘর্ষ হয় এবং সেই ব্যক্তিকে খুব বাজে মাথা ব্যথা দেয়)) সুতরাং, যেমনটি আমি বলেছি, নিজের ঝুঁকিতে এটি করুন, এবং আমি কেবলমাত্র সর্বশেষ উপায় হিসাবে বলব say আপনার গ্রন্থাগারটি সংকলন করতে সক্ষম হওয়ার আগে লোককে কয়েকটি নির্ভরতা ইনস্টল করার জন্য অনুরোধ করা আপনার বান্ডিলযুক্ত নির্ভরতা এবং বিদ্যমান স্থাপনাগুলির মধ্যে সংঘর্ষের সমাধানের চেষ্টা করার চেয়ে অনেক কম মন্দ।

উক্তি: পরীক্ষাগুলি লেখার বিষয়টি যখন আসে তখন এগুলি সাধারণত কীভাবে সংগঠিত হয়? আমি প্রতিটি ক্লাসের জন্য একটি সিপিপি ফাইল রাখার কথা ভাবছিলাম (উদাহরণস্বরূপ test_vector3.cpp) তবে সমস্তগুলি একটি বাইনারিতে সংকলিত হয়েছে যাতে সেগুলি সহজেই একসাথে চালানো যায়?

ক্লাস প্রতি এক সিপিপি ফাইল (বা ক্লাস এবং ফাংশনগুলির একটি ছোট সমন্বিত গ্রুপ) আমার মতে আরও স্বাভাবিক এবং ব্যবহারিক। তবে, অবশ্যই, এগুলি সমস্তগুলিকে একটি বাইনারি হিসাবে সংকলন করবেন না যাতে "তারা সবাই একসাথে চালানো যেতে পারে"। এটা সত্যিই খারাপ ধারণা। সাধারণত, যখন কোডিংয়ের কথা আসে, আপনি জিনিসগুলি যতটা করা যুক্তিসঙ্গত তত বেশি বিভক্ত করতে চান। ইউনিট-পরীক্ষাগুলির ক্ষেত্রে, আপনি সমস্ত পরীক্ষা চালানোর জন্য একটি বাইনারি চান না, কারণ এর অর্থ হল যে আপনি আপনার লাইব্রেরিতে যে কোনও কিছু পরিবর্তন করেন যা সেই ইউনিট-পরীক্ষা প্রোগ্রামটির প্রায় সম্পূর্ণ পুনঃনির্মাণের কারণ হতে পারে , এবং এটি পুনরায় সংশোধনের জন্য অপেক্ষা করতে কয়েক মিনিট / ঘন্টা হারিয়েছে। কেবল একটি সাধারণ স্কিমের সাথে আঁকুন: 1 ইউনিট = 1 ইউনিট-পরীক্ষা প্রোগ্রাম। তারপর,

উক্তি: যেহেতু গেষ্ট গ্রন্থাগারটি সাধারণত চতুর এবং মেক ব্যবহার করে নির্মিত হয়, তাই আমি ভাবছিলাম যে আমার প্রকল্পটিও এটির মতো নির্মিত হবে? যদি আমি নিম্নলিখিত প্রকল্পের বিন্যাসটি ব্যবহার করার সিদ্ধান্ত নিয়েছি:

আমি বরং এই বিন্যাসটি পরামর্শ দেব:

trunk
├── bin
├── lib
   └── project
       └── libvector3.so
       └── libvector3.a        products of installation / building
├── docs
   └── Doxyfile
├── include
   └── project
       └── vector3.hpp
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

├── src
   └── CMakeLists.txt
   └── Doxyfile.in
   └── project                 part of version-control / source-distribution
       └── CMakeLists.txt
       └── vector3.hpp
       └── vector3.cpp
       └── test
           └── test_vector3.cpp
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

├── build
└── test                        working directories for building / testing
    └── test_vector3

এখানে কয়েকটি বিষয় লক্ষণীয়। প্রথমত, আপনার এসআরসি ডিরেক্টরিতে সাব-ডিরেক্টরিতে আপনার অন্তর্ভুক্ত ডিরেক্টরিটির উপ ডিরেক্টরিগুলি আয়না করা উচিত, এটি কেবল বিষয়গুলি স্বজ্ঞাত রাখার জন্য (এছাড়াও, আপনার উপ-ডিরেক্টরি কাঠামোকে যথাযথভাবে সমতল (অগভীর) রাখার চেষ্টা করুন, কারণ ফোল্ডারগুলির গভীর নীড় অন্য যে কোনও কিছুর চেয়ে প্রায়শই ঝামেলা বেশি)। দ্বিতীয়ত, "অন্তর্ভুক্ত" ডিরেক্টরিটি কেবল একটি ইনস্টলেশন ডিরেক্টরি, এর বিষয়বস্তুগুলি এসআরসি ডিরেক্টরি থেকে যা কিছু শিরোনামই বেছে নেওয়া হয় are

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

উদ্ধৃতি: সিএমকেলিস্ট.টেক্সটকে কীভাবে দেখতে হবে যাতে এটি কেবল গ্রন্থাগার বা গ্রন্থাগার এবং পরীক্ষাগুলি তৈরি করতে পারে?

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

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

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

উদ্ধৃতি: আমি আমার কোড নথিতে ডক্সিজেন ব্যবহার করতে চাই। এটি কি স্বয়ংক্রিয়ভাবে cmake দিয়ে চালানো এবং তৈরি করা সম্ভব?

হ্যাঁ. এটি সম্ভবের চেয়ে বেশি, এটি দুর্দান্ত। আপনি কীভাবে অভিনবতা পেতে চান তার উপর নির্ভর করে বিভিন্ন সম্ভাবনা রয়েছে। সিএমকে ডক্সিজেনের (যেমন, find_package(Doxygen)) জন্য একটি মডিউল রয়েছে যা আপনাকে কয়েকটি লক্ষ্যবস্তুতে অক্সিজেন চালাবে এমন লক্ষ্যগুলি নিবন্ধ করার অনুমতি দেয়। আপনি যদি আরও অভিনব জিনিসগুলি করতে চান, যেমন ডক্সিফাইলে সংস্করণ নম্বর আপডেট করা, অথবা স্বয়ংক্রিয়ভাবে কোনও তারিখ / লেখক স্ট্যাম্পগুলি উত্স ফাইলগুলির জন্য প্রবেশ করানো এবং এ জাতীয় কিছু, কিছুটা সিএমকে কুং-ফু দিয়ে এটি সম্ভব। সাধারণত এটি করার সাথে আপনি জড়িত থাকবেন যে আপনি সোর্স ডোক্সিফাইল রেখেছেন (যেমন, "ডক্সিফিল.ইন" যা আমি উপরের ফোল্ডারের বিন্যাসে রেখেছি) যা টোকেনগুলি খুঁজে পাওয়ার জন্য এবং সিএমেকের পার্সিং কমান্ড দ্বারা প্রতিস্থাপন করা হয়েছে। ইন আমার টপ লেভেল CMakeLists ফাইল , আপনি CMake কুং-Fu যে cmake-doxygen একসঙ্গে সঙ্গে কয়েক অভিনব জিনিস আছে এক ধরনের টুকরা পাবেন।


তাহলে main.cppকি যাওয়া উচিত trunk/bin?
ইউগিনিয়াস মালেকাস

17

প্রকল্পের কাঠামো

আমি সাধারণত নিম্নলিখিতগুলির পক্ষে থাকি:

├── CMakeLists.txt
|
├── docs/
│   └── Doxyfile
|
├── include/
│   └── project/
│       └── vector3.hpp
|
├── src/
    └── project/
        └── vector3.cpp
        └── test/
            └── test_vector3.cpp

এর অর্থ হল আপনার লাইব্রেরির জন্য আপনার কাছে খুব স্পষ্টভাবে সংজ্ঞায়িত API ফাইল রয়েছে এবং কাঠামোর অর্থ আপনার গ্রন্থাগারের ক্লায়েন্টরা তা করবে

#include "project/vector3.hpp"

বরং স্বচ্ছতার চেয়ে কম

#include "vector3.hpp"


আমি / এসআরসি গাছের কাঠামোটিকে / অন্তর্ভুক্ত গাছের সাথে মেলে দেখতে পছন্দ করি তবে এটি ব্যক্তিগত পছন্দটি সত্যই। তবে, যদি আপনার প্রকল্পটি / অন্তর্ভুক্ত / প্রকল্পের মধ্যে উপ-ডিরেক্টরি অন্তর্ভুক্ত করতে প্রসারিত হয়, তবে এটি সাধারণত / এসআরসি গাছের অভ্যন্তরের সাথে মিলে যায় help

পরীক্ষাগুলির জন্য, আমি তাদের পরীক্ষিত ফাইলগুলির কাছে তাদের "কাছাকাছি রাখার পক্ষে" এবং আপনি যদি / src এর মধ্যে সাব-ডিরেক্টরিতে শেষ করেন তবে অন্যরা যদি কোনও প্রদত্ত ফাইলের পরীক্ষার কোড খুঁজতে চান তবে অনুসরণ করা এটির পক্ষে একটি খুব সহজ দৃষ্টান্ত।


পরীক্ষামূলক

দ্বিতীয়ত আমি আমার কোডটি পরীক্ষার জন্য গুগল সি ++ টেস্টিং ফ্রেমওয়ার্কটি ব্যবহার করতে মোটামুটি সহজ বলে মনে করি।

গেষ্টটি ব্যবহার করা সত্যই সহজ এবং এর ক্ষমতার দিক থেকে মোটামুটি বিস্তৃত। এটি এর ক্ষমতাগুলি বাড়ানোর জন্য খুব সহজেই জিএমকের পাশাপাশি ব্যবহার করা যেতে পারে তবে জিএমকের সাথে আমার নিজের অভিজ্ঞতা কম অনুকূল ছিল। আমি এটি মানতে বেশ প্রস্তুত যে এটি আমার নিজের ত্রুটিগুলি ভালভাবেই চলে যেতে পারে তবে জিএমক পরীক্ষাগুলি তৈরি করা আরও কঠিন এবং আরও ভঙ্গুর / বজায় রাখা কঠিন। জিএমক কফিনের একটি বড় পেরেকটি এটি স্মার্ট পয়েন্টারগুলির সাথে সত্যিই দুর্দান্ত খেলেনি doesn't

এটি একটি বিশাল প্রশ্নের (যা সম্ভবত এসও এর অন্তর্ভুক্ত নয়) একটি খুব তুচ্ছ এবং বিষয়গত উত্তর

আপনি কি আমার কোড দিয়ে এটিকে বান্ডিল করার পরামর্শ দিচ্ছেন, উদাহরণস্বরূপ "ইনক / গেস্ট" বা "অবদান / গেস্ট" ফোল্ডারে? যদি বান্ডিল হয়, আপনি সংখ্যা বা ফাইলগুলি হ্রাস করতে fuse_gtest_files.py স্ক্রিপ্টটি ব্যবহার করার বা এটি যেমন রেখে দেওয়ার পরামর্শ দিচ্ছেন? যদি বান্ডিল না হয় তবে এই নির্ভরতা কীভাবে পরিচালনা করা হয়?

আমি সিএমকের ExternalProject_Addমডিউল ব্যবহার পছন্দ করি । এটি আপনাকে আপনার সংগ্রহস্থলে জাস্টেস্ট সোর্স কোড রাখতে বা এটিকে যে কোনও জায়গায় ইনস্টল করা এড়িয়ে চলে। এটি আপনার বিল্ড ট্রিতে স্বয়ংক্রিয়ভাবে ডাউনলোড এবং বিল্ট হয়।

আমার উত্তর এখানে সুনির্দিষ্ট সঙ্গে ডিল দেখুন ।

যখন লেখার পরীক্ষার কথা আসে, সাধারণত এগুলি কীভাবে সংগঠিত হয়? আমি প্রতিটি ক্লাসের জন্য একটি সিপিপি ফাইল রাখার কথা ভাবছিলাম (উদাহরণস্বরূপ test_vector3.cpp) তবে সমস্তগুলি একটি বাইনারিতে সংকলিত হয়েছে যাতে সেগুলি সহজেই একসাথে চালানো যায়?

ভাল পরিকল্পনা.


ভবন

আমি সিএমকের ভক্ত, তবে আপনার পরীক্ষা-সংক্রান্ত প্রশ্নগুলির মতো, এই জাতীয় বিষয় সম্পর্কিত বিষয়ে মতামত জিজ্ঞাসা করার জন্য এসও সম্ভবত সেরা জায়গা নয়।

সিএমকেলিস্ট.টেক্সটকে কীভাবে দেখতে হবে যাতে এটি কেবল গ্রন্থাগার বা লাইব্রেরি এবং পরীক্ষাগুলি তৈরি করতে পারে?

add_library(ProjectLibrary <All library sources and headers>)
add_executable(ProjectTest <All test files>)
target_link_libraries(ProjectTest ProjectLibrary)

লাইব্রেরিটি একটি লক্ষ্য "প্রজেক্টলিবারি" হিসাবে উপস্থিত হবে, এবং পরীক্ষার স্যুটটি একটি "প্রকল্পের টেস্ট" হিসাবে লক্ষ্য হিসাবে উপস্থিত হবে। পাঠ্যক্রমের পরীক্ষার নির্ভরতা হিসাবে লাইব্রেরিটি উল্লেখ করে, পরীক্ষা এক্স তৈরি করা লাইব্রেরিটি পুরানো হয়ে থাকলে স্বয়ংক্রিয়ভাবে পুনরায় তৈরির কারণ হবে।

এছাড়াও আমি বেশ কয়েকটি প্রকল্প দেখেছি যা একটি বিল ডিরেক্টরিতে একটি বিল ডিরেক্টরি রয়েছে। বিল্ডটি কি বিল্ড ডিরেক্টরিতে ঘটে এবং তারপরে বাইনারিগুলি বিন ডিরেক্টরিতে চলে যায়? পরীক্ষাগুলির জন্য বাইনারিগুলি এবং গ্রন্থাগারটি কি একই জায়গায় থাকবে?

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

আপনি উল্লেখ করতে পারেন যে বাইনারিগুলি একবার নির্মিত বা অন্য কোনও ডিরেক্টরিতে অনুলিপি করা হয়েছে বা অন্য কোনও ডিরেক্টরিতে এটি ডিফল্টরূপে তৈরি করা হয়েছে তবে সাধারণত কোনও প্রয়োজন নেই। সিএমকে আপনার পছন্দসই হলে আপনার প্রকল্পটি ইনস্টল করার বিস্তৃত উপায় প্রদান করে বা অন্যান্য সিএমকে প্রকল্পগুলির জন্য আপনার প্রকল্পের প্রাসঙ্গিক ফাইলগুলি "সন্ধান" করা সহজ করে তোলে।

গেস্ট টেস্টগুলি সন্ধান এবং সম্পাদন করার জন্য সিএমকের নিজস্ব সহায়তার জন্য , আপনি যদি আপনার প্রকল্পের অংশ হিসাবে গেস্ট তৈরি করেন তবে এটি মূলত অনুপযুক্ত হবে। FindGtestমডিউল সত্যিই কেস যেখানে gtest আলাদাভাবে আপনার প্রকল্পের বাইরে গড়ে উঠেছে ব্যবহার করা ডিজাইন করা হয়েছে।

সিএমকে তার নিজস্ব টেস্ট ফ্রেমওয়ার্ক (সিস্টেস্ট) সরবরাহ করে, এবং আদর্শভাবে, প্রতিটি জ্যেষ্ঠ কেসকে সিটিস্টের কেস হিসাবে যুক্ত করা হবে।

যাইহোক, GTEST_ADD_TESTSদ্বারা উপলব্ধ ম্যাক্রো FindGtestকিছুটা উদাসীন হয় এটি gtest ছাড়া অন্যের ম্যাক্রো জন্য কাজ করে না পৃথক ctest ক্ষেত্রে যেমন gtest মামলার সহজ উপরন্তু করার অনুমতি TESTএবং TEST_FValue- বা প্রকার-parameterised পরীক্ষার ব্যবহার TEST_P, TYPED_TEST_Pইত্যাদি এ সব ঘাঁটা নেই।

সমস্যাটির এমন সহজ সমাধান নেই যা আমি জানি। সর্বাধিক মামলার তালিকা পাওয়ার সবচেয়ে শক্তিশালী উপায় হ'ল পতাকা সহ পরীক্ষাটি এক্সিকিউট করা --gtest_list_tests। যাইহোক, কেবলমাত্র এআইপি তৈরি হওয়ার পরে এটি করা যেতে পারে, তাই সিএমেক এটি ব্যবহার করতে পারে না। যা আপনাকে দুটি পছন্দ সহ ছেড়ে যায়; সিএমকে পরীক্ষার নামগুলি কমাতে সি ++ কোডটি পার্স করার চেষ্টা করতে হবে (যদি আপনি সমস্ত জাস্ট ম্যাক্রোস, কমেন্ট-আউট টেস্ট, অক্ষম পরীক্ষাগুলি গ্রহণ করতে চান তবে) বা পরীক্ষার কেসগুলি হাতে হাতে যুক্ত করা হয় CMakeLists.txt ফাইল।

আমি আমার কোড ডকুমেন্ট করতে ডক্সিজেন ব্যবহার করতে চাই। এটি কি স্বয়ংক্রিয়ভাবে cmake দিয়ে চালানো এবং তৈরি করা সম্ভব?

হ্যাঁ - যদিও এই ফ্রন্টে আমার কোনও অভিজ্ঞতা নেই। সিএমকে FindDoxygenএই উদ্দেশ্যে সরবরাহ করে।


6

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


যুক্তিসহ ব্যাখ্যা

পরিমিতি এবং রক্ষণাবেক্ষণের জন্য, প্রকল্পটি ছোট ইউনিটের একটি সেট হিসাবে সংগঠিত হয়। স্পষ্টতার জন্য, আসুন তাদের নাম দিন ইউনিটএক্স, এক্স = এ, বি, সি, ... (তবে তাদের কোনও সাধারণ নাম থাকতে পারে)। ডিরেক্টরি কাঠামোটি পরে এই পছন্দটি প্রতিফলিত করার জন্য সংগঠিত করা হয়, প্রয়োজনে গ্রুপ ইউনিটগুলির সম্ভাবনা।

সমাধান

বুনিয়াদি ডিরেক্টরি বিন্যাসটি নিম্নলিখিত (ইউনিটগুলির বিষয়বস্তু পরে বিস্তারিতভাবে বর্ণিত):

project
├── CMakeLists.txt
├── UnitA
├── UnitB
├── GroupA
   └── CMakeLists.txt
   └── GroupB
       └── CMakeLists.txt
       └── UnitC
       └── UnitD
   └── UnitE

project/CMakeLists.txt নিম্নলিখিত থাকতে পারে:

cmake_minimum_required(VERSION 3.0.2)
project(project)
enable_testing() # This will be necessary for testing (details below)

add_subdirectory(UnitA)
add_subdirectory(UnitB)
add_subdirectory(GroupA)

এবং project/GroupA/CMakeLists.txt:

add_subdirectory(GroupB)
add_subdirectory(UnitE)

এবং project/GroupB/CMakeLists.txt:

add_subdirectory(UnitC)
add_subdirectory(UnitD)

এখন বিভিন্ন ইউনিটের কাঠামোর দিকে (আসুন, ইউনিটডি উদাহরণ হিসাবে নেওয়া যাক)

project/GroupA/GroupB/UnitD
├── README.md
├── CMakeLists.txt
├── lib
   └── CMakeLists.txt
   └── UnitD
       └── ClassA.h
       └── ClassA.cpp
       └── ClassB.h
       └── ClassB.cpp
├── test
   └── CMakeLists.txt
   └── ClassATest.cpp
   └── ClassBTest.cpp
   └── [main.cpp]

বিভিন্ন উপাদান:

  • আমি একই ফোল্ডারে উত্স ( .cpp) এবং শিরোনাম ( .h) থাকা পছন্দ করি। এটি একটি সদৃশ ডিরেক্টরি স্তরক্রম এড়ানো, রক্ষণাবেক্ষণকে সহজ করে তোলে। ইনস্টলেশনের জন্য, কেবল শিরোনামের ফাইলগুলি ফিল্টার করা কোনও সমস্যা নয় (বিশেষত সিএমকে সাথে)।
  • ডিরেক্টরিটির ভূমিকা UnitDপরে ফাইল সহ অন্তর্ভুক্ত করার অনুমতি দেওয়া হয় #include <UnitD/ClassA.h>। এছাড়াও, এই ইউনিটটি ইনস্টল করার সময় আপনি কেবল ডিরেক্টরি কাঠামোটি অনুলিপি করতে পারেন। মনে রাখবেন যে আপনি আপনার উত্স ফাইলগুলি উপ-ডিরেক্টরিতেও সংগঠিত করতে পারেন।
  • READMEইউনিটটি কী কী তা সংক্ষিপ্ত করতে এবং এটি সম্পর্কে দরকারী তথ্য নির্দিষ্ট করতে আমি একটি ফাইল পছন্দ করি।
  • CMakeLists.txt সহজেই থাকতে পারে:

    add_subdirectory(lib)
    add_subdirectory(test)
  • lib/CMakeLists.txt:

    project(UnitD)
    
    set(headers
        UnitD/ClassA.h
        UnitD/ClassB.h
        )
    
    set(sources
        UnitD/ClassA.cpp
        UnitD/ClassB.cpp    
        )
    
    add_library(${TARGET_NAME} STATIC ${headers} ${sources})
    
    # INSTALL_INTERFACE: folder to which you will install a directory UnitD containing the headers
    target_include_directories(UnitD
                               PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
                               PUBLIC $<INSTALL_INTERFACE:include/SomeDir>
                               )
    
    target_link_libraries(UnitD
                          PUBLIC UnitA
                          PRIVATE UnitC
                          )

    এখানে নোট করুন যে সিএমকে জানানোর প্রয়োজন নেই যে আমরা এর জন্য অন্তর্ভুক্ত ডিরেক্টরিগুলি চাই UnitAএবং UnitCযেহেতু এই ইউনিটগুলি কনফিগার করার সময় এটি ইতিমধ্যে নির্দিষ্ট করা হয়েছিল। এছাড়াও, PUBLICসমস্ত লক্ষ্যবস্তুগুলিকে বলবে যা তার উপর নির্ভর করে UnitDযে তাদের স্বয়ংক্রিয়ভাবে UnitAনির্ভরতা অন্তর্ভুক্ত করা উচিত , যখন UnitCতখন প্রয়োজন হবে না ( PRIVATE)।

  • test/CMakeLists.txt (আপনি যদি এর জন্য জিটিস্ট ব্যবহার করতে চান তবে নীচে আরও দেখুন):

    project(UnitDTests)
    
    add_executable(UnitDTests
                   ClassATest.cpp
                   ClassBTest.cpp
                   [main.cpp]
                   )
    
    target_link_libraries(UnitDTests
                          PUBLIC UnitD
    )
    
    add_test(
            NAME UnitDTests
            COMMAND UnitDTests
    )

গুগল টেস্ট ব্যবহার করা

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

এই সিএমকে ফাংশনটি নিম্নলিখিত:

function(import_gtest)
  include (DownloadProject)
  if (NOT TARGET gmock_main)
    include(DownloadProject)
    download_project(PROJ                googletest
                     GIT_REPOSITORY      https://github.com/google/googletest.git
                     GIT_TAG             release-1.8.0
                     UPDATE_DISCONNECTED 1
                     )
    set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # Prevent GoogleTest from overriding our compiler/linker options when building with Visual Studio
    add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL)
  endif()
endfunction()

এবং তারপরে, যখন আমি এটি আমার পরীক্ষার লক্ষ্যগুলির মধ্যে একটিতে ব্যবহার করতে চাই, আমি নীচের লাইনগুলিতে যুক্ত করব CMakeLists.txt(এটি উপরের উদাহরণের জন্য, test/CMakeLists.txt):

import_gtest()
target_link_libraries(UnitDTests gtest_main gmock_main)

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