সবচেয়ে সহজ তবে সম্পূর্ণ সিএমকে উদাহরণ


117

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

আমি এইভাবে আমার প্রকল্পের কাঠামোটি কল্পনা করি তবে দয়া করে এটি কেবল একটি উদাহরণ। যদি প্রস্তাবিত পদ্ধতিটি পৃথক হয় তবে দয়া করে আমাকে বলুন এবং কীভাবে এটি করবেন তা আমাকে বলুন।

myProject
    src/
        module1/
            module1.h
            module1.cpp
        module2/
            [...]
        main.cpp
    test/
        test1.cpp
    resources/
        file.png
    bin
        [execute cmake ..]

যাইহোক, এটি গুরুত্বপূর্ণ যে আমার প্রোগ্রামটি জানে যে সংস্থানগুলি। আমি সম্পদ পরিচালনার প্রস্তাবিত উপায়টি জানতে চাই। আমি "../resources/file.png" দিয়ে আমার সংস্থানগুলি অ্যাক্সেস করতে চাই না


1
For example I don't want to update my CMakeList.txt when I am adding a new folder in my src treeআপনি IDE এর উদাহরণ দিতে পারেন যা উত্সগুলি স্বয়ংক্রিয়ভাবে সংগ্রহ করে?

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

4
আমি যদি সেই লিঙ্কটি দেখতে পাই তবে আমার ধারণা আছে যে সিএমকে যে সমাধান করতে চেয়েছিলেন সবচেয়ে গুরুত্বপূর্ণ কাজটিতে এটি ব্যর্থ হয়েছিল: একটি ক্রস প্ল্যাটফর্ম বিল্ড সিস্টেমকে সহজ করে তোলা।
আর্ন

উত্তর:


94

কিছু গবেষণার পরে আমার কাছে এখন সর্বাধিক সহজ তবে সম্পূর্ণ চটকের উদাহরণটির নিজস্ব সংস্করণ। এটি এখানে রয়েছে এবং এটি সংস্থান এবং প্যাকেজিং সহ বেশিরভাগ বেসিকটি কভার করার চেষ্টা করে।

এটি অ-মানক করে এমন একটি জিনিস হ'ল সংস্থান হ্যান্ডলিং। ডিফল্টরূপে cmake এগুলিকে / usr / share /, / usr / স্থানীয় / ভাগ / এবং উইন্ডোতে সমমানের কিছু রাখতে চাইছে wants আমি একটি সাধারণ জিপ / টার.gz রাখতে চেয়েছিলাম যা আপনি যে কোনও জায়গায় বের করে চালাতে পারেন। সুতরাং এক্সিকিউটেবলের তুলনায় রিসোর্সগুলি লোড হয়।

cmake কমান্ডগুলি বোঝার প্রাথমিক নিয়মটি হ'ল নিম্নলিখিত সিনট্যাক্স: <function-name>(<arg1> [<arg2> ...])কমা বা অর্ধবৃত্ত ছাড়াই। প্রতিটি যুক্তি একটি স্ট্রিং হয়। foobar(3.0)এবং foobar("3.0")একই। আপনি তালিকা / ভেরিয়েবল এর সাথে সেট করতে পারেন set(args arg1 arg2)। এই পরিবর্তনশীল সেট সহ foobar(${args}) এবং foobar(arg1 arg2)কার্যকরভাবে একই। একটি অস্তিত্বশীল ভেরিয়েবল একটি খালি তালিকার সমান। একটি তালিকা অভ্যন্তরীণভাবে উপাদানগুলি পৃথক করতে সেমিকোলনগুলির সাথে একটি স্ট্রিং। সুতরাং কেবলমাত্র একটি উপাদান সহ একটি তালিকা কেবল সেই উপাদানটির সংজ্ঞা অনুসারে, কোনও বক্সিং স্থান নেয় না। চলকগুলি বিশ্বব্যাপী। বিল্টিন ফাংশনগুলি নাম প্রকাশিত যুক্তিগুলির কিছু ফর্ম প্রস্তাব দেয় যে তারা কিছু আইডির মতো PUBLICবা পছন্দ করেDESTINATIONতাদের যুক্তি তালিকায়, যুক্তিগুলিকে গ্রুপ করার জন্য। তবে এটি কোনও ভাষার বৈশিষ্ট্য নয়, এই আইডিগুলি কেবল স্ট্রিং এবং ফাংশন বাস্তবায়নের মাধ্যমে পার্স করা হয়।

আপনি গিথুব থেকে সমস্ত কিছু ক্লোন করতে পারেন

cmake_minimum_required(VERSION 3.0)
project(example_project)

###############################################################################
## file globbing ##############################################################
###############################################################################

# these instructions search the directory tree when cmake is
# invoked and put all files that match the pattern in the variables 
# `sources` and `data`
file(GLOB_RECURSE sources      src/main/*.cpp src/main/*.h)
file(GLOB_RECURSE sources_test src/test/*.cpp)
file(GLOB_RECURSE data resources/*)
# you can use set(sources src/main.cpp) etc if you don't want to
# use globing to find files automatically

###############################################################################
## target definitions #########################################################
###############################################################################

# add the data to the target, so it becomes visible in some IDE
add_executable(example ${sources} ${data})

# just for example add some compiler flags
target_compile_options(example PUBLIC -std=c++1y -Wall -Wfloat-conversion)

# this lets me include files relative to the root src dir with a <> pair
target_include_directories(example PUBLIC src/main)

# this copies all resource files in the build directory
# we need this, because we want to work with paths relative to the executable
file(COPY ${data} DESTINATION resources)

###############################################################################
## dependencies ###############################################################
###############################################################################

# this defines the variables Boost_LIBRARIES that contain all library names
# that we need to link to
find_package(Boost 1.36.0 COMPONENTS filesystem system REQUIRED)

target_link_libraries(example PUBLIC
  ${Boost_LIBRARIES}
  # here you can add any library dependencies
)

###############################################################################
## testing ####################################################################
###############################################################################

# this is for our testing framework
# we don't add REQUIRED because it's just for testing
find_package(GTest)

if(GTEST_FOUND)
  add_executable(unit_tests ${sources_test} ${sources})

  # we add this define to prevent collision with the main
  # this might be better solved by not adding the source with the main to the
  # testing target
  target_compile_definitions(unit_tests PUBLIC UNIT_TESTS)

  # this allows us to use our executable as a link library
  # therefore we can inherit all compiler options and library dependencies
  set_target_properties(example PROPERTIES ENABLE_EXPORTS on)

  target_link_libraries(unit_tests PUBLIC
    ${GTEST_BOTH_LIBRARIES}
    example
  )

  target_include_directories(unit_tests PUBLIC
    ${GTEST_INCLUDE_DIRS} # doesn't do anything on Linux
  )
endif()

###############################################################################
## packaging ##################################################################
###############################################################################

# all install commands get the same destination. this allows us to use paths
# relative to the executable.
install(TARGETS example DESTINATION example_destination)
# this is basically a repeat of the file copy instruction that copies the
# resources in the build directory, but here we tell cmake that we want it
# in the package
install(DIRECTORY resources DESTINATION example_destination)

# now comes everything we need, to create a package
# there are a lot more variables you can set, and some
# you need to set for some package types, but we want to
# be minimal here
set(CPACK_PACKAGE_NAME "MyExample")
set(CPACK_PACKAGE_VERSION "1.0.0")

# we don't want to split our program up into several things
set(CPACK_MONOLITHIC_INSTALL 1)

# This must be last
include(CPack)

8
@ স্টিভলরিমার আমি কেবল একমত নই, এই ফাইলটি গ্লোব্বিং একটি খারাপ শৈলী, আমি নিজেই সিএমকেলিস্টে ফাইল ট্রি টি অনুলিপি করা বলে মনে করি xt txt এটি একটি বাজে স্টাইল কারণ এটি অপ্রয়োজনীয়। তবে আমি জানি যে লোকেরা এই বিষয়ে দ্বিমত পোষণ করে না, তাই আমি কোডে একটি মন্তব্য রেখেছি, যেখানে আপনি সমস্ত উত্স ফাইলগুলি সুস্পষ্টভাবে অন্তর্ভুক্ত এমন একটি তালিকা দিয়ে গ্লোব্বিংকে প্রতিস্থাপন করতে পারেন। জন্য অনুসন্ধান করুন set(sources src/main.cpp)
আর্ন

3
@ স্টিভলরিমার হ্যাঁ প্রায়শই আমাকে আবার চটকে চাওয়া হত। আমি যখনই ডিরেক্টরি ট্রিটিতে কিছু যুক্ত করি, তখন আমাকে ম্যানুয়ালি cmake পুনরায় চালানো দরকার, যাতে গ্লোবিংয়ের পুনরায় মূল্যায়ন হয়। আপনি যদি ফাইলগুলিতে রাখেন CMakeLists.txtতবে একটি সাধারণ মেক (বা নিনজা) চক্রের পুনর্বাসনকে ট্রিগার করবে, তাই আপনি এটি ভুলতে পারবেন না। এটি কিছুটা টিম বন্ধুবান্ধব, কারণ এরপরে টিম মেম্বাররাও চক্রকে কার্যকর করতে ভুলতে পারে না। তবে আমি মনে করি যে কোনও মেকফিলটি স্পর্শ করা উচিত নয়, কারণ কেউ ফাইল যুক্ত করেছেন। এটি একবার লিখুন, আর কারও আর এটি নিয়ে আর ভাবার দরকার নেই।
আর্ন

3
@ স্টিভলরিমার আমি প্রকল্পগুলির প্রতিটি ডিরেক্টরিতে একটি করে সিএমকেলিস্ট.টিএসটিএস্ট রাখার ধরণটির সাথেও একমত নই, এটি কেবলমাত্র প্রকল্পের কনফিগারেশনটি সর্বত্র ছড়িয়ে দেয়, আমি মনে করি এটি করার জন্য একটি ফাইল যথেষ্ট হওয়া উচিত, অন্যথায় আপনি কীভাবে ওভারভিউটি আলগা করেছেন? প্রকৃতপক্ষে বিল্ড প্রক্রিয়াতে সম্পন্ন হয়। এর অর্থ এই নয় যে তাদের নিজস্ব সিএমকেলিস্টস টেক্সট সহ উপ-ডিরেক্টরি থাকতে পারে না, আমি কেবল এটির ব্যতিক্রম হওয়া উচিত বলে মনে করি।
আর্ন

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

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

39

সর্বাধিক প্রাথমিক কিন্তু সম্পূর্ণ উদাহরণ সিএমকে টিউটোরিয়ালে পাওয়া যাবে :

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
add_executable(Tutorial tutorial.cxx)

আপনার প্রকল্প উদাহরণের জন্য আপনার কাছে থাকতে পারে:

cmake_minimum_required (VERSION 2.6)
project (MyProject)
add_executable(myexec src/module1/module1.cpp src/module2/module2.cpp src/main.cpp)
add_executable(mytest test1.cpp)

আপনার অতিরিক্ত প্রশ্নের জন্য, যাওয়ার একটি উপায় আবার টিউটোরিয়ালে রয়েছে: একটি কনফিগারযোগ্য শিরোনাম ফাইল তৈরি করুন যা আপনি নিজের কোডে অন্তর্ভুক্ত করেছেন। এর জন্য, configuration.h.inনিম্নলিখিত বিষয়বস্তু সহ একটি ফাইল তৈরি করুন :

#define RESOURCES_PATH "@RESOURCES_PATH@"

তারপরে আপনার CMakeLists.txtঅ্যাডে:

set(RESOURCES_PATH "${PROJECT_SOURCE_DIR}/resources/"
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/configuration.h.in"
  "${PROJECT_BINARY_DIR}/configuration.h"
)

# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}")

অবশেষে, যেখানে আপনার কোডে আপনার প্রয়োজন পথ, আপনি এটি করতে পারেন:

#include "configuration.h"

...

string resourcePath = string(RESOURCE_PATH) + "file.png";

আপনাকে অনেক ধন্যবাদ, বিশেষত RESOURCE_PATH এর জন্য, কোনওভাবেই আমি পাইনি যে কনফিগার_ফাইলটি আমি যা খুঁজছিলাম। তবে আপনি প্রকল্প থেকে সমস্ত ফাইল ম্যানুয়ালি যুক্ত করেছেন, কেবলমাত্র একটি প্যাটার্ন সংজ্ঞায়নের জন্য আরও ভাল কোনও উপায় আছে যেখানে এসআরসি ট্রি থেকে সমস্ত ফাইল যুক্ত করা যায়?
আরনে

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

3
@ এসজিভিডি string resourcePath = string(RESOURCE_PATH) + "file.png"আইএমএইচও উত্স ডিরেক্টরিতে পরম পথ হার্ডকোড করা একটি খারাপ ধারণা । আপনি যদি আপনার প্রকল্পটি ইনস্টল করতে চান?

2
আমি জানি যে উত্সগুলি স্বয়ংক্রিয়ভাবে সংগ্রহ করা খুব ভাল লাগে তবে এটি সমস্ত ধরণের জটিলতার কারণ হতে পারে। একটি সংক্ষিপ্ত আলোচনার জন্য এই প্রশ্নটি কিছুক্ষণ আগে দেখুন: stackoverflow.com/q/10914607/1401351
পিটার

2
আপনি চটকে না চালালে আপনি ঠিক একই ত্রুটি পান; হাতে হাতে ফাইল যুক্ত করতে এক সেকেন্ড সময় লাগে, প্রতিটি সংকলনে cmake চালানো প্রতিবার এক সেকেন্ড সময় নেয়; আপনি আসলে cmake একটি বৈশিষ্ট্য বিরতি; একই প্রকল্পে কাজ করে এমন কেউ আপনার পরিবর্তনগুলি টেনে আনবে: রান করুন -> অপরিবর্তিত রেফারেন্স পাবেন -> আশা করি আপনার পুনরায় চালু করা স্মরণ করা উচিত, অথবা আপনার সাথে ফাইলগুলি বাগ -> রান চালায় cmake -> রান সফলভাবে তৈরি করুন, আপনি যদি ফাইল যুক্ত করেন তবে হাতে হাতে তিনি করেন: রান সাফল্য -> পরিবারের সাথে সময় কাটায়। সামনের দিকে, অলসতা বোধ করবেন না এবং ভবিষ্যতে নিজেকে এবং অন্যকে মাথা ব্যথা থেকে রেহাই দিন।
স্যাজিভিডি

2

এখানে আমি একটি সর্বাধিক সহজ তবে সম্পূর্ণ সিএমকেলিস্ট.টেক্সট ফাইলের নমুনা লিখি।

সোর্স কোড

  1. প্ল্যাটফর্ম অ্যান্ড্রয়েড / আইওএস / ওয়েব / ডেস্কটপ থেকে হ্যালো ওয়ার্ল্ড থেকে টিউটোরিয়াল।
  2. প্রতিটি প্ল্যাটফর্ম আমি একটি নমুনা অ্যাপ্লিকেশন প্রকাশ করি।
  3. 08-ক্রস_প্ল্যাটফর্ম ফাইল স্ট্রাকটি আমার কাজ দ্বারা যাচাই করা হয়েছে
  4. এটি নিজের পক্ষে কোনও দলের জন্য নিখুঁত তবে দরকারী ও সেরা অনুশীলন নাও হতে পারে

তারপরে, আমি বিশদগুলির জন্য ডকুমেন্ট অফার করেছি।

আপনার যদি কোনও প্রশ্ন থাকে তবে আপনি আমার সাথে যোগাযোগ করতে পারেন এবং আমি এটি ব্যাখ্যা করতে চাই।

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