সিএফএলএগএস বনাম সিপিপিএফএলএজিএস


103

আমি বুঝতে পারি যে সিএফএলএগএস (বা সি ++ এর জন্য সিএক্সএক্সএফএলএগএস) কম্পাইলারের জন্য, যেখানে সিপিপিএফএলএজিএস প্রিপ্রসেসর ব্যবহার করে।

তবে আমি এখনও পার্থক্য বুঝতে পারি না।

আমাকে একটি শিরোনামের ফাইলের জন্য একটি অন্তর্ভুক্তের পথটি নির্দিষ্ট করতে হবে যা # অন্তর্ভুক্তের সাথে অন্তর্ভুক্ত রয়েছে - কারণ # অন্তর্ভুক্তি একটি প্রিপ্রোসেসর নির্দেশিকা, প্রিপ্রসেসর (সিপিপিএফএলএজিএস) কেবলমাত্র আমিই যত্ন করি?

কোন পরিস্থিতিতে আমার সংকলকটির একটি অতিরিক্ত অন্তর্ভুক্ত পথ দেওয়ার প্রয়োজন?

সাধারণভাবে, যদি প্রিপ্রোসেসর প্রয়োজনীয় হেডার ফাইলগুলি সন্ধান করে এবং এর অন্তর্ভুক্ত করে তবে অতিরিক্ত ডিরেক্টরি অন্তর্ভুক্ত ডিরেক্টরি সম্পর্কে কেন এটি কেন কখনও বলা প্রয়োজন? সিএফএলএজিএস এ কিসের ব্যবহার?

(আমার ক্ষেত্রে, আমি দেখতে পেয়েছি যে এর মধ্যে দু'টিই আমাকে আমার প্রোগ্রামটি সংকলন করতে দেয় যা বিভ্রান্তি আরও বাড়িয়ে দেয় ... আমি আমার লক্ষ্য অর্জনের জন্য সিএফএলএগ্রস বা সিপিপিএফএলএগএস ব্যবহার করতে পারি (কমপক্ষে স্বতন্ত্র প্রতিবেদনে) কী দেয়?)


2
সম্ভাব্য সদৃশ stackoverflow.com/questions/495598/...
মাইকেল Mrozek

উত্তর:


153

একটি সি প্রোগ্রাম সংকলনের জন্য অন্তর্নিহিত মেক বিধিটি হ'ল

%.o:%.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

যেখানে $()সিনট্যাক্সটি ভেরিয়েবলগুলি প্রসারিত করে। উভয় হিসাবে CPPFLAGSএবং CFLAGSসংকলক কলটিতে ব্যবহৃত হয়, যা আপনি অন্তর্ভুক্ত পাথগুলি সংজ্ঞায়িত করতে ব্যবহার করেন ব্যক্তিগত স্বাদের বিষয়। উদাহরণস্বরূপ যদি foo.cবর্তমান ডিরেক্টরিতে কোনও ফাইল থাকে

make foo.o CPPFLAGS="-I/usr/include"
make foo.o CFLAGS="-I/usr/include"

উভয়ই আপনার সংকলকটিকে ঠিক একইভাবে কল করবে, যথা

gcc -I/usr/include -c -o foo.o foo.c

দু'জনের মধ্যে পার্থক্যটি কার্যকর হয় যখন আপনার একাধিক ভাষাগুলি একই থাকে যার জন্য একই পথের প্রয়োজন হয়, উদাহরণস্বরূপ যদি আপনি bar.cppচেষ্টা করেন তবে

make bar.o CPPFLAGS="-I/usr/include"
make bar.o CFLAGS="-I/usr/include"

সংকলনগুলি হবে

g++ -I/usr/include -c -o bar.o bar.cpp
g++ -c -o bar.o bar.cpp

সি ++ অন্তর্নিহিত নিয়ম হিসাবে চলকটিও ব্যবহার করে CPPFLAGS

এই পার্থক্যটি আপনাকে একটি ভাল গাইড প্রদান করবে যার জন্য আপনি ব্যবহার করতে চান - আপনি যদি পতাকাটি সমস্ত ভাষার জন্য ব্যবহার করতে চান CPPFLAGSতবে এটি কোনও নির্দিষ্ট ভাষার জন্য রাখা হয় CFLAGS, CXXFLAGSইত্যাদি। পরবর্তীকালের উদাহরণগুলির মধ্যে স্ট্যান্ডার্ড কমপ্লায়েন্স বা সতর্কতা পতাকা অন্তর্ভুক্ত রয়েছে - আপনি -std=c99আপনার সি ++ কম্পাইলারের কাছে যেতে চান না !

এরপরে আপনি আপনার মেকফিলটিতে এরকম কিছু শেষ করতে পারেন

CPPFLAGS=-I/usr/include
CFLAGS=-std=c99
CXXFLAGS=-Weffc++

1
নোট করুন যে আপনি কোনও এককভাবে দৌড়ে cppব্যবহার করতে পারবেন না CPPFLAGSএবং কোনও যুক্তিসঙ্গত ফলাফলের আশা করতে পারবেন না কারণ -std=c99কোন চিহ্নগুলি সংজ্ঞায়িত করা হয় তা প্রভাবিত করে (বিশেষত বৈশিষ্ট্য পরীক্ষা ম্যাক্রোগুলির পরিবর্তে)। পরিবর্তে, আপনার প্রয়োজন $(CC) $(CPPFLAGS) $(CFLAGS) -E
জেদ

10

CPPFLAGSম্যাক্রো উল্লেখ করতে ব্যবহার করতে হয় #includeডিরেক্টরি।

উভয় CPPFLAGSএবং CFLAGSআপনার ক্ষেত্রে কাজ করুন কারণ make(1) বিধি একটি কমান্ডে প্রিপ্রোসেসিং এবং সংকলন উভয়কেই একত্রিত করে (সুতরাং উভয় ম্যাক্রো কমান্ডে ব্যবহৃত হয়)।

আপনি .যদি ফর্মটি ব্যবহার করেন তবে আপনাকে অন্তর্ভুক্ত ডিরেক্টরি হিসাবে নির্দিষ্ট করার দরকার নেই #include "..."। আপনাকে স্ট্যান্ডার্ড সংকলক অন্তর্ভুক্ত ডিরেক্টরি নির্দিষ্ট করার দরকার নেই। আপনাকে অন্য সমস্ত অন্তর্ভুক্ত ডিরেক্টরিগুলি নির্দিষ্ট করতে হবে।


এটি আরও অর্থবোধ করে, তবে সিএফএলএগএস তখন কী করে তা আমি এখনও দেখতে পাচ্ছি না। যদি আপনি বোঝাচ্ছেন যে, আরও জটিল প্রকল্পগুলিতে সংকলন প্রিপ্রোসেসিং থেকে পৃথক পদক্ষেপে করা হয়ে থাকে, তখন কি প্রিপ্রোসেসিং সফল হবে তবে সিপিএফএলএজিএস প্রিপ্রসেসরের জন্য সিপিপিএফএলএগএস যুক্ত করা পথগুলি সংযুক্ত না করলে সংকলন ব্যর্থ হবে? আমি অনুমান করি যে প্রিপ্রসেসর ইতিমধ্যে # অন্তর্ভুক্ত নির্দেশিকা প্রক্রিয়াকরণ করলে সংকলকটি কী কী পাথগুলি অন্তর্ভুক্ত করে তা আমি বুঝতে পারি না?
EBM

4
@EB আপনি যদি প্রিপ্রোসেসড ফাইলগুলি সংকলন করেন তবে পাথগুলি অপ্রয়োজনীয় অন্তর্ভুক্ত করুন - প্রয়োজনীয় শিরোনামগুলি ইতিমধ্যে প্রাকপ্রসেসেড উত্সে যুক্ত করা হয়েছে (আপনি যখন gcc -Eকোনও ফাইল চালাবেন তখন আউটপুটটি দেখুন - কোনও # অন্তর্ভুক্ত নেই)। বেশিরভাগ আধুনিক সংকলক প্রাক-প্রক্রিয়াজাতকরণ এবং সংকলন পদক্ষেপগুলি একত্রিত করে, তাই আপনাকে এই সম্পর্কে চিন্তা করতে হবে না।
স্কট ওয়েলস


0

যারা অন্তর্নিহিত নিয়মগুলি উল্লেখ করেছেন তাদের সাথে যুক্ত করার জন্য, কী মেকটিটি সুস্পষ্টভাবে সংজ্ঞায়িত করেছে এবং আপনার এনভির ব্যবহার করে তা ব্যবহার করা ভাল:

make -p

এই ক্ষেত্রে:

%.o: %.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<

যা প্রসারিত হয়

COMPILE.c = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

এটি # environmentডেটাও প্রিন্ট করবে । এখানে, আপনি অন্যান্য দরকারী তথ্যের মধ্যে জিসিসির অন্তর্ভুক্ত পথ খুঁজে পাবেন।

C_INCLUDE_PATH=/usr/include

মেক ইন, যখন অনুসন্ধানের বিষয়টি আসে, পথগুলি অনেকগুলি হয়, আলো এক হয় ... বা সেই প্রভাবের কিছু।

  1. C_INCLUDE_PATHসিস্টেম-প্রশস্ত, এটি আপনার শেলের মধ্যে সেট করুন *.rc
  2. $(CPPFLAGS) প্রিপ্রোসেসরের জন্য পথ অন্তর্ভুক্ত।
  3. আপনার যদি মেকিংয়ের জন্য সাধারণ অনুসন্ধানের পথটি যুক্ত করতে হয় তবে ব্যবহার করুন:
VPATH = my_dir_to_search

... বা আরও নির্দিষ্ট

vpath %.c src
vpath %.h include

সাধারণ অনুসন্ধানের পথ হিসাবে ভিপিএটিএইচ ব্যবহার করুন তাই সতর্কতার সাথে ব্যবহার করুন। ভিপিএটিএইচএল-এ তালিকাভুক্ত একাধিক স্থানে যদি ফাইল উপস্থিত থাকে তবে মেক তালিকায় প্রথম ঘটনাটি নেবে।

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