Conditional Compilation مرتب کو بلڈ ٹائم پر معلوم شرائط کی بنیاد پر سورس کوڈ کے کچھ حصوں کو شامل کرنے یا چھوڑنے کی اجازت دیتا ہے۔ The Swift Programming Language (2026) کے مطابق، #if ہدایت مشین کوڈ کی تخلیق سے پہلے AST تجزیہ کے دوران پروسیس ہوتی ہے۔ 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 چار اہم ہدایات فراہم کرتا ہے: #if، #elseif، #else، #endif۔ C پری پروسیسر کے برعکس، Swift تمام شاخوں میں کوڈ کی نحوی درستگی کا تقاضا کرتا ہے — مرتب تمام کوڈ کو پارس کرتا ہے لیکن صرف فعال شاخوں کے لیے مشین کوڈ تیار کرتا ہے۔
Swift بلٹ ان جانچ کے افعال کو سپورٹ کرتا ہے: os(iOS)، os(macOS)، os(tvOS)، os(watchOS)، os(Linux)، os(Windows)۔ یہ افعال اس ہدف پلیٹ فارم کی جانچ کرتے ہیں جس کے لیے ایپلیکیشن بنائی جا رہی ہے۔ && اور || کے ساتھ امتزاج پیچیدہ شرائط بنانے کی اجازت دیتا ہے۔
// 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 میں میکروز) ایسی جانچ سے محفوظ کی جا سکتی ہیں۔
// پسماندہ مطابقت
#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(ModuleName) فنکشن جانچتا ہے کہ آیا مخصوص کردہ ماڈیول موجودہ بلڈ ماحول میں دستیاب ہے۔ یہ سب سے لچکدار طریقہ کار ہے: یہ کسی مخصوص پلیٹ فارم سے منسلک نہیں ہے۔ مثال کے طور پر، CoreHaptics استعمال کرنے والا کوڈ صرف ان آلات پر تالیف ہوگا جہاں یہ فریم ورک دستیاب ہے۔
#if canImport(CoreHaptics)
import CoreHaptics
class HapticManager {
private var engine: CHHapticEngine?
func playTapFeedback() {
guard let engine else { return }
// ہیپٹک فیڈ بیک کا نفاذ
}
}
#endif
Kotlin زبان میں پری پروسیسر ہدایات نہیں ہیں۔ اس کے بجائے، Android ایکو سسٹم تین متبادل پیش کرتا ہے: BuildConfig فیلڈز (رن ٹائم جانچ)، sourceSets (مکمل فائلوں کی تبدیلی)، اور expect/actual (Kotlin Multiplatform میں)۔
Gradle sourceSets مختلف فلیورز یا بلڈ اقسام کے لیے مختلف کلاس نفاذ کی اجازت دیتے ہیں۔ src/debug/ ڈائریکٹری میں ڈیبگ نفاذ ہے، src/release/ میں — ریلیز نفاذ۔ بلڈ کے دوران، Gradle مناسب sourceSet کا انتخاب کرتا ہے اور صرف اس کی فائلوں کو تالیف کرتا ہے۔
// 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
}
}
KMP expect طریقہ کار (مشترکہ کوڈ میں اعلامیہ) اور actual (مخصوص پلیٹ فارم کے لیے نفاذ) فراہم کرتا ہے۔ یہ تالیف کے وقت کا طریقہ کار ہے: iOS کے لیے iOS sourceSet سے actual نفاذ تالیف ہوتا ہے، Android کے لیے — Android sourceSet سے۔ غیر ہدف نفاذ تالیف نہیں ہوتے۔
// 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
Android NDK کے ذریعے مقامی لائبریریاں تیار کرتے وقت، #ifdef، #ifndef، #define ہدایات کے ساتھ کلاسک C/C++ پری پروسیسر استعمال ہوتا ہے۔ Swift کے برعکس، C پری پروسیسر متن کی سطح پر کام کرتا ہے — غیر فعال شاخوں میں کوڈ نحوی طور پر غلط ہو سکتا ہے۔
NDK ہر پلیٹ فارم کے لیے میکروز کی وضاحت کرتا ہے: __ANDROID__ (Android)، __APPLE__ (iOS/macOS)، __linux__ (Linux)۔ فن تعمیرات کے لیے: __arm__، __aarch64__، __x86_64__۔ یہ میکروز مرتب کے ذریعے خود بخود اس وقت سیٹ کیے جاتے ہیں جب ہدف پلیٹ فارم کے لیے بلڈ کیا جاتا ہے۔
// 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/Kotlin | BuildConfig.FLAVOR |
سب سے خطرناک اینٹی پیٹرن — پورے کوڈ میں ہدایات کا پھیلاؤ۔ اگر ہر دوسری فائل میں #if ہے، تو یہ اشارہ ہے کہ فن تعمیر کو ری فیکٹرنگ کی ضرورت ہے۔ صحیح حل — پلیٹ فارم کوڈ کو پروٹوکول/انٹرفیس کے پیچھے نکالنا اور ڈیپنڈنسی انجیکشن استعمال کرنا ہے۔
اکثر پوچھے گئے سوالات
Conditional Compilation تالیف کے وقت کام کرتا ہے: غیر فعال کوڈ بائنری میں نہیں جاتا۔ رن ٹائم جانچیں (if / switch) ہمیشہ تالیف ہوتی ہیں، شرط عملدرآمد کے دوران جانچی جاتی ہے۔ پہلا زیادہ محفوظ اور موثر ہے، دوسرا زیادہ لچکدار (بغیر دوبارہ بلڈ کے تبدیل کیا جا سکتا ہے)۔
ہاں، Swift فنکشن کے اندر #if، لوپس اور حتیٰ کہ اظہار کے اندر بھی ہدایات کی اجازت دیتا ہے۔ یہ ان خصوصیات میں سے ایک ہے جو Swift کے ابتدائی ورژنز میں موجود نہیں تھی۔ مثال کے طور پر: let x = #if DEBUG 1 #else 0 #endif — درست کوڈ۔
Kotlin ڈیولپرز نے جان بوجھ کر پری پروسیسر کو مسترد کر دیا، اسے نازک کوڈ کا ذریعہ سمجھتے ہوئے۔ اس کے بجائے، وہ expect/actual (تالیف کے وقت کی حفاظت) اور Gradle sourceSets (فائل کی سطح پر علیحدگی) پیش کرتے ہیں۔ دونوں طریقے متن کی تبدیلی سے زیادہ قابل اعتماد ہیں۔
CI میں مختلف جھنڈوں کے امتزاج کے ساتھ ایپلیکیشن بنائیں۔ Swift کے لیے: مختلف Active Compilation Conditions کے ساتھ علیحدہ Xcode اسکیمز کنفیگر کریں۔ Android کے لیے: علیحدہ Build Variants کنفیگر کریں اور ہر ایک کے لیے ٹیسٹ چلائیں۔ آٹومیشن لازمی ہے۔
Swift میں، #if شرط ایک مرتب ہدایت ہے۔ اگر شرط خود نحوی طور پر غلط ہے (مثلاً، os() نام میں ٹائپو)، مرتب ایک تالیف کی غلطی جاری کرے گا۔ C/C++ میں، پری پروسیسر صرف میکرو کو نہیں ڈھونڈے گا اور شرط غلط ہو جائے گی۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں