চ্যামেক বনাম নমুনা কোড তৈরি করুন?


118

আমি ভাবছিলাম যে Makefileএস ( make) এবং CMakeLists.txt( cmake) এর জন্য কোনও নমুনা কোড ছিল কিনা যে উভয়ই একই জিনিস করে (একমাত্র পার্থক্য হ'ল একটিতে লিখিত আছে makeএবং অন্যটিতে cmake)।

আমি 'cmake বনাম মেক' সন্ধান করার চেষ্টা করেছি, কিন্তু আমি কোনও কোডের তুলনা পাই নি। এটি কেবলমাত্র একটি সাধারণ ক্ষেত্রে হলেও পার্থক্যগুলি বোঝার পক্ষে সহায়ক হবে।


20
+1 এটি একটি ভাল প্রশ্ন; যখন আমি শুরু করছিলাম তখন আমি cmakeএটিও চেয়েছিলাম। তবে আমি সন্দেহ করি আপনি এটি পাবেন কারণ ক্ষমতাগুলি কেবল সেইরকম একটির সাথে অন্যের কাছে মানচিত্র তৈরি করে না। আপনি যদি এ জাতীয় cmakeআচরণ করার চেষ্টা করেন make, আপনি নিজেকে বাদাম চালিয়ে যাবেন, গুরুত্ব সহকারে। স্ক্র্যাচ থেকে শুরু করা সেরা। যে বিষয়গুলিতে তুচ্ছ makeতা বেশ জড়িত এবং cmakeতদ্বিপরীত।
আর্নেস্ট ফ্রাইডম্যান-হিল

1
@ আর্নেস্টফ্রেডম্যান-হিলের কি আপনার আরও বিশদ আছে? সুতরাং makeএবং cmakeএতটা স্বতন্ত্র যে তাদের প্রতিযোগিতামূলক সরঞ্জামগুলির পরিবর্তে পরিপূরক হিসাবে আরও বেশি দেখা উচিত?
এহতেশ চৌধুরী

2
@ শুরান - কমক নিজেই কিছু তৈরি করে না; এটি Makefiles (এবং অন্যান্য, অনুরূপ বিল্ড স্ক্রিপ্ট) তৈরি করে, যা আপনি তারপরে চালান। অতএব আপনি যখনই ক্যামকে ফাইল লিখছেন, তখন আপনাকে ভাবতে হবে যে প্রজন্মের সময় বা বিল্ড টাইম চলাকালীন কোনও কমান্ড প্রয়োগ করা উচিত। কিছু ক্রিয়া - বিল্ড টাইমের সময় ফাইলগুলির একটি ওয়াইল্ডকার্ডযুক্ত সেটটি অনুলিপি করুন - উদাহরণস্বরূপ - cp *.x $(OUTDIR)আপনি একটি মেকফাইলে " " লিখতে চাইলে তার তুলনায় বেশ জটিল । আমার জন্য সম্ভবত সবচেয়ে বিরক্তিকর অংশটি হ'ল উত্পাদিত মেকফিলগুলি হ'ল সম্পূর্ণ ননপোর্টেবল এবং ইনফ্লেসিটেবল (অব্যাহত) ডিজাইন দ্বারা
আর্নেস্ট ফ্রেডম্যান-হিল

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

1
একটি দুর্দান্ত প্রশ্ন, তবে কোনও নির্দিষ্ট উত্তর নেই, উভয় সরঞ্জামই একটি ভিন্ন সমস্যা সমাধান করার চেষ্টা করে। সিএমকে প্রোগ্রামগুলি কীভাবে প্রোগ্রাম তৈরি করতে পারে সে সম্পর্কিত তথ্য গ্রহণ করে যা প্রোগ্রাম তৈরি করে। সুতরাং cmake অ্যাবস্ট্র্যাক্ট বিল্ড বিধি সহ একটি ভাষা এবং gnu মেক একটি নির্ভরতা সমাধান করে যা একটি নির্দেশিত অ্যাসাইক্লিক গ্রাফ ট্র্যাভারসাল এ প্রোগ্রামগুলি কার্যকর করে।
অ্যালেক্স

উত্তর:


118

নিম্নলিখিত মেকফাইল progউত্স থেকে নাম নির্বাহযোগ্য তৈরি করে prog1.c, prog2.c, prog3.c and main.cprogএর সাথে লিঙ্কযুক্ত libmystatlib.a এবং libmydynlib.soযা উভয়ই উত্স থেকে নির্মিত। অতিরিক্তভাবে, progলাইব্রেরিটি এর libstuff.aমধ্যে stuff/libএবং এর শিরোলেখ ব্যবহার করে stuff/include। মেকফাইল ডিফল্টরূপে একটি মুক্তির লক্ষ্য তৈরি করে, তবে একটি ডিবাগ লক্ষ্যও সরবরাহ করে:

#Makefile    
CC = gcc
CPP = g++
RANLIB = ar rcs
RELEASE = -c -O3 
DEBUG = -c -g -D_DEBUG
INCDIR = -I./stuff/include
LIBDIR = -L./stuff/lib -L.
LIBS = -lstuff -lmystatlib -lmydynlib
CFLAGS = $(RELEASE)

PROGOBJS = prog1.o prog2.o prog3.o

prog: main.o $(PROGOBJS) mystatlib mydynlib
    $(CC) main.o $(PROGOBJS) $(LIBDIR) $(LIBS) -o prog 
debug: CFLAGS=$(DEBUG)
debug: prog

mystatlib: mystatlib.o
    $(RANLIB) libmystatlib.a mystatlib.o
mydynlib: mydynlib.o
    $(CPP) -shared mydynlib.o -o libmydynlib.so

%.o: %.c
    $(CC) $(CFLAGS) $(INCDIR) $< -o $@ 
%.o: %.cpp
    $(CPP) $(CFLAGS) $(INCDIR) -fPIC  $< -o $@ 

এখানে একটি CMakeLists.txtযা প্রায় (প্রায়) হুবহু একই রকম হয়, কিছু মন্তব্য সহ মেকফিলের সাথে মিলগুলি লক্ষ করে:

#CMakeLists.txt     
cmake_minimum_required(VERSION 2.8)                    # stuff not directly
project(example)                                       # related to building

include_directories(${CMAKE_SOURCE_DIR}/stuff/include) # -I flags for compiler
link_directories(${CMAKE_SOURCE_DIR}/stuff/lib)        # -L flags for linker

set(PROGSRC prog1.c prog2.c prog3.c)                   # define variable 

add_executable(prog main.c ${PROGSRC})                 # define executable target prog, specify sources
target_link_libraries(prog mystatlib mydynlib stuff)   # -l flags for linking prog target

add_library(mystatlib STATIC mystatlib.c)              # define static library target mystatlib, specify sources

add_library(mydynlib SHARED mydynlib.cpp)              # define shared library target mydynlib, specify sources
#extra flags for linking mydynlib
set_target_properties(mydynlib PROPERTIES POSITION_INDEPENDENT_CODE TRUE) 
#alternatively:
#set_target_properties(mydynlib PROPERTIES COMPILE_FLAGS "-fPIC")

এই সাধারণ উদাহরণে, সবচেয়ে গুরুত্বপূর্ণ পার্থক্যগুলি হ'ল:

  • কোন ধরণের উত্সের জন্য কোন সংকলকগুলি ব্যবহার করতে হবে তা সিএমকে স্বীকৃতি দেয়। এছাড়াও, এটি প্রতিটি ধরণের টার্গেটের জন্য কমান্ডের সঠিক ক্রমটি আহ্বান করে। অতএব, মত কমান্ড কোন স্পষ্ট স্পেসিফিকেশন হয় $(CC) ..., $(RANLIB) ...ইত্যাদি।

  • সমস্ত সাধারণ সংকলক / লিঙ্কার পতাকাগুলি হেডার ফাইল, গ্রন্থাগার ইত্যাদির অন্তর্ভুক্তির সাথে সম্পর্কিত হয় প্ল্যাটফর্ম ইন্ডিপেন্ডেন্ট / বিল্ড সিস্টেম স্বাধীন কমান্ড দ্বারা প্রতিস্থাপিত হয়।

  • ডিবাগ পতাকা অন্তর্ভুক্ত করা হয় পারেন পরিবর্তনশীল সেটিং দ্বারা CMAKE_BUILD_TYPE"ডিবাগ", অথবা এটি CMake ক্ষণস্থায়ী যখন প্রোগ্রাম invoking দ্বারা: cmake -DCMAKE_BUILD_TYPE:STRING=Debug

  • সিএমকে প্ল্যাটফর্মটিকে '-fPIC' পতাকাটি ( POSITION_INDEPENDENT_CODEসম্পত্তির মাধ্যমে ) এবং আরও অনেককে স্বতন্ত্র অন্তর্ভুক্তির প্রস্তাব দেয়। তবুও, আরও অস্পষ্ট সেটিংস হস্তক্ষেপে সিএমকে পাশাপাশি একটি মেকফাইলে (ব্যবহার করে COMPILE_FLAGS এবং অনুরূপ বৈশিষ্ট্য দ্বারা) প্রয়োগ করা যেতে পারে । অবশ্যই তৃতীয় পক্ষের লাইব্রেরিগুলি (ওপেনজিএল) কোনও পোর্টেবল পদ্ধতিতে অন্তর্ভুক্ত করা হলে অবশ্যই সিএমকে সত্যই জ্বলতে শুরু করে।

  • makeকমান্ড লাইনে টাইপ করে আপনি যদি মেকফিল ব্যবহার করেন তবে বিল্ড প্রক্রিয়াটির একটি পদক্ষেপ রয়েছে । সিএমকেকের জন্য দুটি পদক্ষেপ রয়েছে: প্রথমত, আপনাকে আপনার বিল্ড এনভায়রনমেন্ট সেটআপ করতে হবে (হয় cmake <source_dir>আপনার বিল্ড ডিরেক্টরিতে টাইপ করে বা কিছু জিইআইআই ক্লায়েন্ট চালিয়ে)। এটি আপনার পছন্দসই বিল্ড সিস্টেমের উপর নির্ভর করে একটি মেকফাইল বা সমতুল্য কিছু তৈরি করে (যেমন উইন্ডোজটিতে ইউনিক্স বা ভিসি ++ বা মিনজিডাব্লু + মাইসিস তৈরি করুন)। বিল্ড সিস্টেমটি প্যারামিটার হিসাবে সিএমকে দেওয়া যেতে পারে; তবে সিএমকে আপনার সিস্টেম কনফিগারেশনের উপর নির্ভর করে যুক্তিসঙ্গত ডিফল্ট পছন্দগুলি করে। দ্বিতীয়ত, আপনি নির্বাচিত বিল্ড সিস্টেমে প্রকৃত বিল্ড সম্পাদন করেন।

উত্স এবং বিল্ড নির্দেশাবলী https://github.com/rhoelzel/make_cmake এ উপলব্ধ ।


3
মেকফিল কি অতিরিক্ত জটিল নয়? ব্যবহারের CPPFLAGSপরিবর্তে INCDIRএক বিল্ট-ইন নিয়ম এবং কম্পাইলার স্পষ্ট আবাহন চলেছি হবে অপ্রয়োজনীয় ব্যবহার করেছি পারে। একইভাবে আর পরিচালনা করার জন্য, অন্তর্নির্মিত বিধিগুলিও এটি কভার করতে পারে। এছাড়াও, কেন CPPএবং CCসুস্পষ্টভাবে সেট ? এগুলি ইতিমধ্যে ভাল মানগুলিতে সেট করা আছে make, তারা পূর্বনির্ধারিত পরিবর্তনশীল vari makeকোন ধরণের উত্সের জন্য কোন সংকলকটি ব্যবহার করতে হবে তাও স্বীকৃত, অন্তর্নির্মিত নিয়মগুলি অনেকগুলি।
ক্রিশ্চিয়ান হুজার

1
এবং এর :=পরিবর্তে এর সাথে অনেকগুলি ভেরিয়েবল বরাদ্দ করা উচিত =
খ্রিস্টান হুজার

1
বর্ণনাটি cmakeদেখতে automakeচেয়ে তুলনামূলক বেশি make
ivan_pozdeev

প্রদত্ত Makefile 3/4 লাইনে হ্রাস করা যেতে পারে। আপনি INCLUDESপরিবর্তে নির্দিষ্ট করা উচিত INCDIR। আপনার% .o:%। C বিধি প্রয়োজন নেই।
শুভা

6

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

একটি জিনিস মনে রাখতে হবে যে সেই সরঞ্জামগুলি একের সাথে মানচিত্র তৈরি করে না। সর্বাধিক সুস্পষ্ট পার্থক্য হ'ল সিএমকে বিভিন্ন ফাইলের মধ্যে নির্ভরতার জন্য স্ক্যান করে (উদাহরণস্বরূপ সি শিরোনাম এবং উত্স ফাইল), অন্যদিকে পাতাটি মেকফিল লেখকদের তৈরি করে।


4

যদি এই প্রশ্নটি ফাইলটির একটি নমুনা Makefileআউটপুট সম্পর্কে হয় CMakeList.txtতবে দয়া করে চ্যাট করুন-ব্যাকএন্ড উত্সগুলি পরীক্ষা করুন এবং এরকম একটি তৈরি করুন Makefile। যদি তা না হয় তবে @ রবার্তো এর জবাবটিতে যুক্ত করে আমি বিশদটি গোপন করে এটি সহজ করার চেষ্টা করছি।

সিএমকে অনুষ্ঠান

যদিও Makeনিয়ম এবং রেসিপিটির জন্য নমনীয় সরঞ্জাম, CMakeএটি বিমূর্ততার একটি স্তর যা কনফিগারেশন বৈশিষ্ট্যকে যুক্ত করে।

আমার সমতলটি CMakeLists.txtনীচের মত দেখাবে,

cmake_minimum_required(VERSION 2.8)
project(example)
file(GLOB testapp_SOURCES *.cc)
add_executable(testapp ${testapp_SOURCES})

দ্রষ্টব্য, যে বিল্ডটি CMakeলুকিয়ে রাখে howতা করা যায়। আমরা কেবল whatইনপুট এবং আউটপুট নির্দিষ্ট করেছি ।

দ্বারা CMakeLists.txtসংজ্ঞায়িত ফাংশন-কলগুলির তালিকা রয়েছে cmake

(সিএমকে ফাংশন) বনাম বিধি তৈরি করুন

ইন পরিবর্তে ব্যবহার করা হয় । মত বৈশিষ্ট্য ছাড়াও , শৃঙ্খলা সরবরাহ। আমার নমনীয়তা নীচের মত দেখতে হবে,Makefilerules and recipesfunctionsfunctionrules and recipesMakefile

-include "executable.mk"
TARGETS=testapp.bin
all:${TARGETS}

যদিও executable.mkনীচের মত দেখতে হবে,

SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
DEPS=$(SOURCES:.cpp=.d)

%.bin:$(OBJECTS)
    $(CC) $(CFLAGS) -o $@ $^ $(LFLAGS) $(LIBS)

.PHONY: all clean

clean:
    $(RM) $(OBJECTS) $(DEPS) $(TARGETS)

-include $(DEPS)

স্ক্র্যাচ থেকে শুরু করে আমি Makefileনিম্নলিখিতগুলির মতো শুরু করব ,

all: testapp.bin

testapp.bin:sourcea.o sourcb.o
    $(CC) $(CFLAGS) -o $@ $^ $(LFLAGS) $(LIBS)

.PHONY: all clean

clean:
    $(RM) $(OBJECTS) testapp.bin

আমি থেকে এই স্নিপেট পেয়েছিলাম এখানে এবং এটি রুপান্তরিত করা হয়েছে। নোট করুন যে এই ফাইলটিতে কিছু অন্তর্নিহিত-বিধি যুক্ত করা হয়েছে যা মেকফিল-ডকুমেন্টেশনে পাওয়া যায়। কিছু অন্তর্নিহিত ভেরিয়েবলগুলি এখানে প্রাসঙ্গিক।

মনে রাখবেন, যে Makefileবিস্তারিত উপলব্ধ recipeদেখাচ্ছে howবিল্ড করা যাবে। executable.mkবিশদটি একটি ফাইলে সংজ্ঞায়িত করার জন্য এটি লেখা সম্ভব । সেই পদ্ধতিতে মেকফাইলটি হ্রাস করা যেতে পারে যেমন আমি আগে দেখিয়েছি।

অভ্যন্তরীণ চলকগুলি CMakeএবং এর মধ্যেMake

এখন সামান্য উন্নত হয়ে CMakeআমরা নিম্নলিখিতগুলির মতো একটি সংকলক পতাকা সেট করতে পারি,

set(CMAKE_C_FLAGS "-Wall")

ফাইলে CMakeডিফল্ট ভেরিয়েবল সম্পর্কে আরও জানুন CMakeCache.txtCMakeউপরের কোড সমতূল্য হতে হবে Makeনিচের কোড,

CFLAGS = -Wall

নোট যেটি CFLAGSএকটি অভ্যন্তরীণ পরিবর্তনশীল Make, একইভাবে, CMAKE_C_FLAGSঅভ্যন্তরীণ পরিবর্তনশীল CMake

সিএমকে অন্তর্ভুক্ত এবং লাইব্রেরি পাথ যোগ করুন

আমরা এটি cmakeফাংশন ব্যবহার করে করতে পারি ।

target_include_directories(testapp PRIVATE "myincludes")
list(APPEND testapp_LIBRARIES
    mytest mylibrarypath
)
target_link_libraries(testapp ${testapp_LIBRARIES})

বনাম যুক্তগুলি মেকের মধ্যে অন্তর্ভুক্ত এবং লাইব্রেরির পাথ

নিম্নলিখিতগুলির মতো লাইন যুক্ত করে আমরা অন্তর্ভুক্ত এবং লাইব্রেরি যুক্ত করতে পারি,

INCLUDES += -Imyincludes
LIBS += -Lmylibrarypath -lmytest

নোট করুন উপরের এই লাইনগুলি অটো-জেন সরঞ্জাম বা পিকেজি-কনফিগার থেকে উত্পন্ন করা যেতে পারে। (যদিও মেকফাইল স্বয়ং-কনফিগার সরঞ্জামগুলির উপর নির্ভরশীল নয়)

সিএমকে কনফিগার / টুইট করুন

সাধারণত ফাংশন ব্যবহার করে সরঞ্জামগুলির config.hমতো কিছু ফাইল উত্পন্ন করা সম্ভব । কাস্টম ফাংশন লেখার জন্য আরও কৌশল করা সম্ভব। এবং পরিশেষে আমরা নিম্নলিখিতগুলির মতো একটি কনফিগার নির্বাচন করতে পারি,auto-configconfigure_file

cmake --build . --config "Release"

optionফাংশনটি ব্যবহার করে কিছু কনফিগারযোগ্য বিকল্প যুক্ত করা সম্ভব ।

মেকফিল কনফিগার / টুইক করুন

যদি কোনওভাবে আমাদের কিছু ডিবাগ পতাকা দিয়ে সংকলন করা দরকার হয় তবে আমরা এই জাতীয় অনুরোধ করতে পারি make,

make CXXFLAGS=NDEBUG

আমি অভ্যন্তরীণ ভেরিয়েবলগুলি মনে করি Makefile-rulesএবং CMake-functionsতুলনা করার জন্য এটি ভাল সূচনা, আরও খননকারীর জন্য শুভকামনা।

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