মোবাইল অ্যাপে Conditional Compilation — সারমর্ম, নির্দেশিকা এবং কাজের নীতি

লেখক: IT Sectr প্রকাশিত: 2026-06-01 পড়ার সময়: 9 মিনিট

Conditional Compilation কম্পাইলারকে বিল্ড সময়ে পরিচিত শর্তের উপর ভিত্তি করে সোর্স কোডের অংশগুলি অন্তর্ভুক্ত বা বাদ দেওয়ার অনুমতি দেয়। The Swift Programming Language (2026) অনুসারে, #if নির্দেশিকা মেশিন কোড জেনারেশনের আগে AST বিশ্লেষণের সময় প্রক্রিয়া করা হয়। Conditional Compilation ডেভেলপারদের নকল ছাড়াই একাধিক প্ল্যাটফর্ম এবং কনফিগারেশনের জন্য একটি একক কোডবেস বজায় রাখার ক্ষমতা দেয়।

মূল বিষয়

  • Conditional Compilation — প্ল্যাটফর্ম, কনফিগারেশন বা ভাষার সংস্করণের শর্ত অনুসারে কোডের নির্বাচনী কম্পাইলেশনের কৌশল।
  • নির্দেশিকা #if, #elseif, #else, #endif — Swift, C, C++, Objective-C-তে প্রধান শর্তসাপেক্ষ কম্পাইলেশন কাঠামো।
  • Kotlin-এ প্রিপ্রসেসর নির্দেশিকা নেই — পরিবর্তে BuildConfig, expect/actual এবং sourceSets ব্যবহার করা হয়।
  • সুবিধা — অনুপযুক্ত প্ল্যাটফর্মের কোড কম্পাইল হয় না, বাইনারির আকার হ্রাস পায় এবং ত্রুটিগুলি দূর হয়।
  • iOS/macOS শেয়ার্ড কোড — Conditional Compilation হল Apple-এর ক্রস-প্ল্যাটফর্ম ফ্রেমওয়ার্ক বিকাশের ভিত্তি।

Conditional Compilation কী

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

ধারণাটি C/C++ থেকে প্রিপ্রসেসর নির্দেশিকা #ifdef, #ifndef, #endif সহ এসেছে। আধুনিক ভাষায় (Swift, Rust, Go), প্রক্রিয়াটি আলাদা প্রিপ্রসেসর ছাড়াই কম্পাইলার স্তরে কাজ করে, যা নিরাপত্তা বাড়ায়: শর্তসাপেক্ষ ব্লকগুলি বাক্যগতভাবে সঠিক হতে হবে এমনকি যদি সেগুলি কম্পাইল না হয়।

Apple WWDC সেশন “Embrace Swift” (2025) অনুসারে, প্রায় 40% Swift প্রজেক্ট একটি একক টার্গেটে iOS এবং macOS সমর্থন করতে শর্তসাপেক্ষ কম্পাইলেশন ব্যবহার করে। UIKit এবং SwiftUI সহ প্রজেক্টের জন্য, UI কোড প্রায়ই #if os(iOS) এবং #if os(macOS) নির্দেশিকা দ্বারা বিভক্ত হয়, যা বিজনেস লজিক পুনরায় ব্যবহারের অনুমতি দেয়।

মূল সুবিধা হল কম্পাইল-টাইম নিরাপত্তা। অনুপযুক্ত প্ল্যাটফর্মের কোড কেবল নির্বাহিত হয় না, বরং কম্পাইলও হয় না। এর অর্থ হল iOS-নির্দিষ্ট কোডের ত্রুটিগুলি macOS-এর জন্য বিল্ড করার সময় প্রকাশ পাবে না, এবং এর বিপরীত। রানটাইম চেকগুলি এমন গ্যারান্টি দেয় না।

Swift-এ Conditional Compilation

Swift চারটি মূল নির্দেশিকা প্রদান করে: #if, #elseif, #else, #endif। C প্রিপ্রসেসরের বিপরীতে, Swift সমস্ত শাখায় কোডের বাক্যগত শুদ্ধতা প্রয়োজন — কম্পাইলার সমস্ত কোড পার্স করে কিন্তু কেবল সক্রিয় শাখাগুলির জন্য মেশিন কোড জেনারেট করে।

প্ল্যাটফর্ম চেক os()

Swift অন্তর্নির্মিত চেক ফাংশন সমর্থন করে: os(iOS), os(macOS), os(tvOS), os(watchOS), os(Linux), os(Windows)। এই ফাংশনগুলি লক্ষ্য প্ল্যাটফর্ম পরীক্ষা করে যার জন্য অ্যাপ্লিকেশন তৈরি করা হচ্ছে। && এবং || এর সাথে সংমিশ্রণ জটিল শর্ত তৈরি করার অনুমতি দেয়।

swift
// iOS, macOS এবং tvOS-এর জন্য একীভূত কোড
import Foundation

class PlatformService {
    func getSystemVersion() -> String {
        #if os(iOS) || os(tvOS)
            return UIDevice.current.systemVersion
        #elseif os(macOS)
            let vers = ProcessInfo.processInfo.operatingSystemVersion
            return "\(vers.majorVersion).\(vers.minorVersion)"
        #else
            return "unknown"
        #endif
    }
}

কম্পাইলার সংস্করণ চেক

Swift কম্পাইলার সংস্করণ চেক সমর্থন করে: #if swift(>=5.9)। এটি লাইব্রেরি এবং ফ্রেমওয়ার্কগুলির জন্য উপযোগী যা একাধিক Swift সংস্করণ সমর্থন করে। নতুন ভাষা বৈশিষ্ট্যগুলি (যেমন Swift 5.9-এ ম্যাক্রো) এই ধরনের চেক দ্বারা সুরক্ষিত করা যেতে পারে।

swift
// পশ্চাদগামী সামঞ্জস্যতা
#if swift(>=5.9)
    @MainActor
    struct ModernView: View {
        var body: some View {
            Text("Modern SwiftUI")
        }
    }
#else
    struct ModernView: View {
        var body: some View {
            Text("Legacy SwiftUI")
        }
    }
#endif

মডিউল উপলব্ধতা চেক canImport()

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

swift
#if canImport(CoreHaptics)
    import CoreHaptics

    class HapticManager {
        private var engine: CHHapticEngine?

        func playTapFeedback() {
            guard let engine else { return }
            // স্পর্শ প্রতিক্রিয়া বাস্তবায়ন
        }
    }
#endif

Kotlin এবং Android-এ বিকল্প

Kotlin ভাষায় প্রিপ্রসেসর নির্দেশিকা নেই। পরিবর্তে, Android ইকোসিস্টেম তিনটি বিকল্প অফার করে: BuildConfig ফিল্ড (রানটাইম চেক), sourceSets (সম্পূর্ণ ফাইল প্রতিস্থাপন), এবং expect/actual (Kotlin Multiplatform-এ)।

Gradle-এ Source Sets

Gradle sourceSets বিভিন্ন ফ্লেভার বা বিল্ড টাইপের জন্য আলাদা ক্লাস বাস্তবায়নের অনুমতি দেয়। src/debug/ ডিরেক্টরিতে ডিবাগ বাস্তবায়ন থাকে, src/release/ এ — রিলিজ বাস্তবায়ন। বিল্ডের সময়, Gradle উপযুক্ত sourceSet নির্বাচন করে এবং কেবল তার ফাইলগুলি কম্পাইল করে।

kotlin
// src/debug/kotlin/com/example/Logger.kt
object Logger {
    fun log(tag: String, message: String) {
        Log.d(tag, message)
    }
}

// src/release/kotlin/com/example/Logger.kt
object Logger {
    fun log(tag: String, message: String) {
        // রিলিজে No-op
    }
}

Kotlin Multiplatform-এ Expect/Actual

KMP expect প্রক্রিয়া (সাধারণ কোডে ঘোষণা) এবং actual (নির্দিষ্ট প্ল্যাটফর্মের জন্য বাস্তবায়ন) প্রদান করে। এটি একটি কম্পাইল-টাইম প্রক্রিয়া: iOS-এর জন্য iOS sourceSet থেকে actual বাস্তবায়ন কম্পাইল হয়, Android-এর জন্য — Android sourceSet থেকে। অ-লক্ষ্য বাস্তবায়নগুলি কম্পাইল হয় না।

kotlin
// commonMain — expect ঘোষণা
expect fun getPlatformName(): String

// androidMain — Android-এর জন্য actual
actual fun getPlatformName(): String =
    "Android \${Build.VERSION.SDK_INT}"

// iosMain — iOS-এর জন্য actual
actual fun getPlatformName(): String =
    UIDevice.current.systemName() + " " + UIDevice.current.systemVersion

C/C++ প্রিপ্রসেসর এবং NDK

Android NDK-এর মাধ্যমে নেটিভ লাইব্রেরি বিকাশ করার সময়, #ifdef, #ifndef, #define নির্দেশিকা সহ ক্লাসিক C/C++ প্রিপ্রসেসর ব্যবহার করা হয়। Swift-এর বিপরীতে, C প্রিপ্রসেসর টেক্সট স্তরে কাজ করে — নিষ্ক্রিয় শাখাগুলিতে কোড বাক্যগতভাবে ভুল হতে পারে।

NDK প্ল্যাটফর্ম ফ্ল্যাগ

NDK প্রতিটি প্ল্যাটফর্মের জন্য ম্যাক্রো সংজ্ঞায়িত করে: __ANDROID__ (Android), __APPLE__ (iOS/macOS), __linux__ (Linux)। আর্কিটেকচারের জন্য: __arm__, __aarch64__, __x86_64__। এই ম্যাক্রোগুলি কম্পাইলার দ্বারা লক্ষ্য প্ল্যাটফর্মের জন্য বিল্ড করার সময় স্বয়ংক্রিয়ভাবে সেট করা হয়।

cpp
// Android এবং iOS-এর জন্য নেটিভ কোড
#include <cstdint>

#ifdef __ANDROID__
    int32_t getJniEnv(JNIEnv* env) {
        return env->GetVersion();
    }
#elif defined(__APPLE__)
    #include <TargetConditionals.h>
    int32_t getOsVersion() {
        #if TARGET_OS_IOS
            return "iOS";
        #elif TARGET_OS_OSX
            return "macOS";
        #endif
    }
#endif

NDK-এর সাথে কাজ করার সময়, মনে রাখা গুরুত্বপূর্ণ যে C/C++ প্রিপ্রসেসর একটি টেক্সট প্রতিস্থাপন। যদি নিষ্ক্রিয় শাখায় বাক্যগত ত্রুটি থাকে, কম্পাইলার এটি দেখতে পাবে না, কিন্তু যদি ভুল #define একটি সক্রিয় শাখা ভেঙে দেয় — ত্রুটিটি প্রকাশ পাবে। #define চেইন কমানো এবং constexpr ধ্রুবক ব্যবহার করার পরামর্শ দেওয়া হয়।

Rust-এর জন্য, যা UniFFI এবং Mozilla Application Services-এর মাধ্যমে মোবাইল বিকাশেও ব্যবহৃত হয়, এর নিজস্ব প্রক্রিয়া রয়েছে — Cargo.toml-এ ফিচার ফ্ল্যাগ। Rust-এ #[cfg(target_os = “android”)]-এর মতো ফ্ল্যাগগুলি Swift নির্দেশিকার মতো কাজ করে: চেক কম্পাইলার স্তরে করা হয়, প্রিপ্রসেসর স্তরে নয়। এটি Rust-কে নেটিভ লাইব্রেরির জন্য একটি আকর্ষণীয় পছন্দ করে তোলে যা একটি কোডবেস থেকে Android এবং iOS-এর জন্য কম্পাইল করতে হবে।

ব্যবহারিক দৃশ্যকল্প এবং অ্যান্টিপ্যাটার্ন

Conditional Compilation কঠোরভাবে সংজ্ঞায়িত দৃশ্যকল্পে কার্যকর। ভুলভাবে ব্যবহার করলে, এটি কোড স্মেল তৈরি করে যা পরীক্ষা এবং রক্ষণাবেক্ষণ করা কঠিন। আসুন সঠিক দৃশ্যকল্প এবং সাধারণ ভুলগুলি বিবেচনা করি।

সঠিক দৃশ্যকল্প

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

দৃশ্যকল্পভাষাশর্ত
প্ল্যাটফর্ম অ্যাবস্ট্রাকশনSwift#if os(iOS)
ডিবাগিংSwift/ObjC#if DEBUG
পশ্চাদগামী সামঞ্জস্যতাSwift#if swift(>=5.7)
নেটিভ লাইব্রেরিC/C++#ifdef __ANDROID__
A/B পরীক্ষণJava/KotlinBuildConfig.FLAVOR

অ্যান্টিপ্যাটার্ন

সবচেয়ে বিপজ্জনক অ্যান্টিপ্যাটার্ন — সমগ্র কোড জুড়ে নির্দেশিকার বিস্তার। যদি প্রতি দ্বিতীয় ফাইলে #if থাকে, এটি ইঙ্গিত দেয় যে আর্কিটেকচারের রিফ্যাক্টরিং প্রয়োজন। সঠিক সমাধান — প্রোটোকল/ইন্টারফেসের পিছনে প্ল্যাটফর্ম কোড বের করা এবং ডিপেন্ডেন্সি ইঞ্জেকশন ব্যবহার করা।

  • প্রতি ফাইলে #if — একটি আর্কিটেকচারাল অ্যান্টিপ্যাটার্ন। প্ল্যাটফর্ম কোড প্রোটোকলের পিছনে বিচ্ছিন্ন করা উচিত।
  • নেস্টেড #if — দ্রুত অপঠনযোগ্য হয়ে যায়। নেস্টিং গভীরতা 2 স্তরের বেশি হওয়া উচিত নয়।
  • সম্পূর্ণ ফাংশনের নকল — যদি একটি ফাংশন #if এবং #else-এ সম্পূর্ণভাবে কপি করা হয়, তবে এটি সাধারণ অংশে বের করা উচিত।
  • পরীক্ষণ — নিষ্ক্রিয় শাখার ভিতরের কোড পরীক্ষিত হয় না। সমস্ত সম্ভাব্য সংমিশ্রণের CI বিল্ড প্রয়োজনীয়।
  • জাদুকরী ফ্ল্যাগ — অপ্রলিখিত ফ্ল্যাগ যা নতুন ডেভেলপার টিম জানে না।

প্রায়শই জিজ্ঞাসিত প্রশ্ন

Conditional Compilation কীভাবে রানটাইম চেক থেকে আলাদা?

Conditional Compilation কম্পাইল সময়ে কাজ করে: নিষ্ক্রিয় কোড বাইনারিতে যায় না। রানটাইম চেক (if / switch) সর্বদা কম্পাইল হয়, শর্ত নির্বাহের সময় পরীক্ষা করা হয়। প্রথমটি বেশি নিরাপদ এবং কার্যকর, দ্বিতীয়টি বেশি নমনীয় (পুনর্নির্মাণ ছাড়াই পরিবর্তন করা যেতে পারে)।

Swift-এ কি ফাংশনের ভিতরে #if ব্যবহার করা যাবে?

হ্যাঁ, Swift ফাংশনের ভিতরে #if, লুপ এবং এমনকি এক্সপ্রেশনের ভিতরেও নির্দেশিকা অনুমতি দেয়। এটি এমন একটি বৈশিষ্ট্য যা Swift-এর প্রাথমিক সংস্করণে অনুপস্থিত ছিল। উদাহরণস্বরূপ: let x = #if DEBUG 1 #else 0 #endif — বৈধ কোড।

Kotlin কেন প্রিপ্রসেসর যোগ করেনি?

Kotlin ডেভেলপাররা ইচ্ছাকৃতভাবে প্রিপ্রসেসর প্রত্যাখ্যান করেছে, এটিকে ভঙ্গুর কোডের উৎস হিসেবে বিবেচনা করে। পরিবর্তে, তারা expect/actual (কম্পাইল-টাইম নিরাপত্তা) এবং Gradle sourceSets (ফাইল স্তরে বিচ্ছিন্নতা) অফার করে। উভয় পদ্ধতিই টেক্সট প্রতিস্থাপনের চেয়ে বেশি নির্ভরযোগ্য।

নিষ্ক্রিয় #if শাখার ভিতরে কোড কীভাবে পরীক্ষা করবেন?

CI-তে বিভিন্ন ফ্ল্যাগ সংমিশ্রণ সহ অ্যাপ্লিকেশন বিল্ড করুন। Swift-এর জন্য: বিভিন্ন Active Compilation Conditions সহ আলাদা Xcode স্কিম কনফিগার করুন। Android-এর জন্য: আলাদা Build Variants কনফিগার করুন এবং প্রতিটির জন্য পরীক্ষা চালান। অটোমেশন বাধ্যতামূলক

#if শর্তে বাক্যগত ত্রুটি থাকলে কী হয়?

Swift-এ, #if শর্ত একটি কম্পাইলার নির্দেশিকা। যদি শর্তটি নিজেই বাক্যগতভাবে ভুল হয় (যেমন, os() নামে টাইপো), কম্পাইলার একটি কম্পাইলেশন ত্রুটি দেবে। C/C++-এ, প্রিপ্রসেসর কেবল ম্যাক্রো খুঁজে পাবে না এবং শর্তটি মিথ্যা হয়ে যাবে।

সারাংশ

  • Conditional Compilation — একটি কম্পাইলেশন কৌশল যা রানটাইম চেকের বিপরীতে, বিল্ড সময়ে অ-লক্ষ্য কোড বাদ দেয়।
  • Swift #if-কে os(), canImport(), swift() সহ সমর্থন করে — কম্পাইল-টাইম নিরাপদ নির্দেশিকা যা সমস্ত শাখার বাক্যগত শুদ্ধতা প্রয়োজন।
  • Kotlin প্রিপ্রসেসরের পরিবর্তে expect/actual এবং Gradle sourceSets ব্যবহার করে — বেশি নির্ভরযোগ্য কিন্তু কম নমনীয় পদ্ধতি।
  • NDK-তে C/C++ প্ল্যাটফর্ম ম্যাক্রো __ANDROID__, __APPLE__ সহ ক্লাসিক টেক্সট প্রিপ্রসেসর #ifdef / #ifndef ব্যবহার করে।
  • সঠিক ব্যবহার — প্ল্যাটফর্ম অ্যাবস্ট্রাকশন, ডিবাগিং, পশ্চাদগামী সামঞ্জস্যতা। ভুল ব্যবহার — প্রতি ফাইলে #if, গভীর নেস্টিং, জাদুকরী ফ্ল্যাগ।
  • CI বাধ্যতামূলক — সমস্ত ফ্ল্যাগ সংমিশ্রণ স্বয়ংক্রিয়ভাবে বিল্ড এবং পরীক্ষা করা উচিত, অন্যথায় নিষ্ক্রিয় শাখায় কোড মৃত হয়ে যায়।

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন