मोबाइल ऐप्स में 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 एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें