একটি সমাধান যা আমি সম্প্রতি খুঁজে পেয়েছি তা হ'ল আউট-অফ-সোর্স বিল্ড ধারণাটি একটি মেকফিলের মোড়কের সাথে একত্রিত করা।
আমার শীর্ষ-স্তরের সিএমকেলিস্ট.টেক্সট ফাইলটিতে ইন-উত্স বিল্ডগুলি রোধ করার জন্য আমি নিম্নলিখিতগুলি অন্তর্ভুক্ত করেছি:
if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} )
message( FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt." )
endif()
তারপরে, আমি একটি শীর্ষ-স্তরের মেকফিল তৈরি করি এবং নিম্নলিখিতগুলি অন্তর্ভুক্ত করি:
# -----------------------------------------------------------------------------
# CMake project wrapper Makefile ----------------------------------------------
# -----------------------------------------------------------------------------
SHELL := /bin/bash
RM := rm -rf
MKDIR := mkdir -p
all: ./build/Makefile
@ $(MAKE) -C build
./build/Makefile:
@ ($(MKDIR) build > /dev/null)
@ (cd build > /dev/null 2>&1 && cmake ..)
distclean:
@ ($(MKDIR) build > /dev/null)
@ (cd build > /dev/null 2>&1 && cmake .. > /dev/null 2>&1)
@- $(MAKE) --silent -C build clean || true
@- $(RM) ./build/Makefile
@- $(RM) ./build/src
@- $(RM) ./build/test
@- $(RM) ./build/CMake*
@- $(RM) ./build/cmake.*
@- $(RM) ./build/*.cmake
@- $(RM) ./build/*.txt
ifeq ($(findstring distclean,$(MAKECMDGOALS)),)
$(MAKECMDGOALS): ./build/Makefile
@ $(MAKE) -C build $(MAKECMDGOALS)
endif
ডিফল্ট লক্ষ্য allটাইপ করে বলা হয় make, এবং লক্ষ্য প্রার্থনা ./build/Makefile।
লক্ষ্যটি প্রথম কাজটি করে ডিরেক্টরিটি ব্যবহার করে ./build/Makefileতৈরি করা যা এর জন্য একটি পরিবর্তনশীল । ডিরেক্টরিটি যেখানে আমরা আমাদের উত্স-বহির্গমন বিল্ড সম্পাদন করব। ইতিমধ্যে উপস্থিত থাকতে পারে এমন একটি ডিরেক্টরি তৈরি করার চেষ্টা করার জন্য আমাদের যাতে আর্তনাদ না হয় তা নিশ্চিত করার জন্য আমরা যুক্তিটি সরবরাহ করি ।build$(MKDIR)mkdir -pbuild-pmkdir
দ্বিতীয়টি লক্ষ্যটি ./build/Makefileহ'ল ডিরেক্টরিকে ডিরেক্টরিতে পরিবর্তন করা buildএবং অনুরোধ করা cmake।
allলক্ষ্য ফিরে , আমরা অনুরোধ $(MAKE) -C build, যেখানে $(MAKE)একটি Makefile পরিবর্তনশীল স্বয়ংক্রিয়ভাবে উত্পাদিত হয় make। make -Cকিছু করার আগে ডিরেক্টরি পরিবর্তন করে। সুতরাং, ব্যবহার $(MAKE) -C buildকরা সমান cd build; make।
সংক্ষিপ্তসার হিসাবে, এই Makefile মোড়কে কল করে make allবা makeকরা সমান:
mkdir build
cd build
cmake ..
make
লক্ষ্য distcleanপূজা cmake .., তারপর make -C build clean, এবং পরিশেষে থেকে সমস্ত সামগ্রী সরিয়ে ফেলা হবে buildডিরেক্টরি। আমি বিশ্বাস করি আপনি নিজের প্রশ্নে ঠিক এটি অনুরোধ করেছেন।
মেকফিলের শেষ অংশটি ব্যবহারকারী-সরবরাহিত লক্ষ্যটি কিনা তা মূল্যায়ন করে distclean। যদি তা না হয় তবে এটি ডিরেক্টরি করার buildআগে এটি পরিবর্তন করতে হবে। এটি খুব শক্তিশালী কারণ ব্যবহারকারী উদাহরণস্বরূপ টাইপ করতে পারেন make cleanএবং মেকফিল এটিকে সমতুল্য রূপান্তরিত করবে cd build; make clean।
উপসংহারে, এই মেকফিল মোড়কে, কোনও বাধ্যতামূলক বাহ্যিক উত্স বিল্ড সিএমকে কনফিগারেশনের সংমিশ্রণে এটি তৈরি করুন যাতে ব্যবহারকারীকে কখনই কমান্ডের সাথে ইন্টারঅ্যাক্ট করতে না হয় cmake। buildডিরেক্টরি থেকে সমস্ত সিএমকে আউটপুট ফাইল সরানোর জন্য এই সমাধানটি একটি মার্জিত পদ্ধতিও সরবরাহ করে ।
PS মেকফাইলে আমরা @শেল কমান্ড থেকে আউটপুট দমন করতে উপসর্গ @-এবং শেল কমান্ড থেকে ত্রুটি উপেক্ষা করার উপসর্গ ব্যবহার করি। টার্গেটের rmঅংশ হিসাবে ব্যবহার করার সময় distclean, ফাইল উপস্থিত না থাকলে কমান্ডটি একটি ত্রুটি ফিরিয়ে দেবে (তারা ইতিমধ্যে কমান্ড লাইন ব্যবহার করে ইতিমধ্যে মুছে ফেলা হতে পারে rm -rf build, বা তারা প্রথম স্থানে তৈরি করা হয়নি)। এই রিটার্ন ত্রুটিটি আমাদের মেকফিলটিকে প্রস্থান করতে বাধ্য করবে। আমরা @-তা আটকাতে উপসর্গটি ব্যবহার করি। যদি কোনও ফাইল ইতিমধ্যে মুছে ফেলা হয় তবে তা গ্রহণযোগ্য; আমরা চাই আমাদের মেকফিলটি চলতে থাকুক এবং বাকিটি সরিয়ে দিন।
নোটটিতে আরেকটা জিনিস: এই Makefile, কাজ নাও করতে পারে যদি আপনি CMake ভেরিয়েবল একটি পরিবর্তনশীল নম্বর ব্যবহার উদাহরণস্বরূপ, আপনার প্রকল্পের নির্মাণ করতে cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar"। এই মেকফিলটি ধরে নিয়েছে যে আপনি সিএমকে অনুরূপ উপায়ে অনুরোধ করেছেন, তা টাইপ করে cmake ..বা cmakeধারাবাহিক সংখ্যক যুক্তি সরবরাহ করে (যা আপনি আপনার মেকফাইলে অন্তর্ভুক্ত করতে পারেন)।
অবশেষে, creditণ যেখানে creditণ প্রদান is এই মেকফিলের মোড়কটি সি ++ অ্যাপ্লিকেশন প্রকল্প টেম্পলেট দ্বারা সরবরাহিত মেকফাইল থেকে গৃহীত হয়েছিল ।