موبائل ایپس میں 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 ایپل کے کراس پلیٹ فارم فریم ورک کی ترقی کی بنیاد ہے۔

Conditional Compilation کیا ہے

Conditional Compilation ایک طریقہ کار ہے جس میں مرتب مشروط تالیف کی ہدایات کا تجزیہ کرتا ہے اور آؤٹ پٹ بائنری میں صرف ان کوڈ بلاکس کو شامل کرتا ہے جن کی شرائط پوری ہوتی ہیں۔ یہ ایک ہی کوڈ بیس رکھنے کی اجازت دیتا ہے جو مختلف ہدف پلیٹ فارمز اور کنفیگریشنز کے مطابق ڈھل جاتا ہے۔

یہ تصور C/C++ سے پری پروسیسر ہدایات #ifdef، #ifndef، #endif کے ساتھ آیا ہے۔ جدید زبانوں (Swift, Rust, Go) میں، یہ طریقہ کار علیحدہ پری پروسیسر کے بغیر مرتب کی سطح پر کام کرتا ہے، جو حفاظت کو بڑھاتا ہے: مشروط بلاکس نحوی طور پر درست ہونے چاہئیں چاہے وہ تالیف نہ بھی ہوں۔

ایپل ڈبلیو ڈبلیو ڈی سی سیشن «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 سختی سے متعین منظرناموں میں مؤثر ہے۔ غلط استعمال کرنے پر، یہ کوڈ سمل پیدا کرتا ہے جس کی جانچ اور دیکھ بھال مشکل ہوتی ہے۔ آئیے صحیح منظرناموں اور عام غلطیوں پر غور کریں۔

صحیح منظرنامے

پہلا منظرنامہ — پلیٹ فارم تجرید: ایک واحد façade جس کے اندر 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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں