| SCONS(1) | SCons 4.11.1 | SCONS(1) |
نام (NAME)
scons - ابزاری برای ساخت نرمافزار
خلاصه دستور (SYNOPSIS)
scons [گزینهها...] [name=val...] [هدفها...]
توضیحات (DESCRIPTION)
SCons یک سیستم ساخت متنباز و توسعهپذیر است که با تعیین اینکه کدام بخشها و مؤلفهها باید ساخته یا بازسازی شوند و فراخوانی دستورهای لازم برای ساخت آنها، فرایند ساخت نرمافزار (و سایر خروجیهای ملموس مانند فایلهای مستندات) را مدیریت و هماهنگ میکند. SCons قابلیتهای فراوانی را برای بهبود بهرهوری توسعهدهندگان ارائه میدهد؛ از جمله ساختهای موازی، کشکردن مصنوعات ساخت، پویش خودکار وابستگیها، و پایگاه دادهای از اطلاعات ساختهای پیشین تا نیازی به محاسبهٔ مجدد جزئیات در هر بار اجرا نباشد.
برای اجرای scons به Python نسخهٔ 3.7 یا بالاتر نیاز است؛ هیچ وابستگی یا پیشنیاز دیگری نباید وجود داشته باشد، مگر اینکه از ابزار آزمایشی Ninja استفاده شود (که نیازمند بستهٔ ninja است).
تغییریافته در نسخهٔ 4.3.0: پشتیبانی از Python نسخهٔ 3.5 حذف شده است. پروژهٔ CPython در سپتامبر ۲۰۲۰ به پشتیبانی از 3.5 پایان داد: https://peps.python.org/pep-0478.
تغییریافته در نسخهٔ 4.9.0: پشتیبانی از Python نسخهٔ 3.6 حذف شده است. پروژهٔ CPython در سپتامبر ۲۰۲۱ به پشتیبانی از 3.6 پایان داد: https://peps.python.org/pep-0494.
تغییریافته در نسخهٔ 4.11.0: پشتیبانی از Python نسخهٔ 3.7 منسوخ شده است و در انتشار آیندهٔ SCons حذف خواهد شد. پروژهٔ CPython در ژوئن ۲۰۲۳ به پشتیبانی از 3.7 پایان داد: https://peps.python.org/pep-0537.
تغییریافته در نسخهٔ 4.11.0: پشتیبانی از Python نسخهٔ 3.8 منسوخ شده است و در انتشار آیندهٔ SCons حذف خواهد شد. پروژهٔ CPython در سپتامبر ۲۰۲۴ به پشتیبانی از 3.8 پایان داد: https://peps.python.org/pep-0569.
شما یک فرایند ساخت SCons را با نوشتن اسکریپتی راهاندازی میکنید که موارد مورد نیاز برای ساخت (هدفها یا targets) و در صورت لزوم، قواعد ساخت آن فایلها (اقدامها یا actions) را توصیف میکند. SCons مجموعهای از متدهای سازنده (Builder) به همراه دارد که اقدامهای آمادهای را برای ساخت بسیاری از مؤلفههای رایج نرمافزاری مانند برنامههای اجرایی، فایلهای شیء (object files) و کتابخانهها ارائه میدهند؛ بهگونهای که برای بسیاری از پروژههای نرمافزاری، در فراخوانی یک سازنده تنها مشخصکردن هدفها و فایلهای ورودی (منابع یا sources) کفایت میکند.
SCons در یک لایهٔ انتزاعی فراتر از نام خالص فایلها عمل میکند. برای نمونه، اگر یک هدف کتابخانهٔ اشتراکی با نام “foo” مشخص کنید، SCons نام فایل وابسته به سیستمعامل واقعی (مانند libfoo.so در سیستمهای GNU/Linux و foo.dll در Windows) را پیگیری میکند و یک شناسه در اختیارتان میگذارد تا در مراحل دیگر به آن هدف ارجاع دهید، بنابراین نیازی نیست که خودتان از رشتههای خاص هر سیستمعامل استفاده کنید. SCons همچنین میتواند اطلاعات وابستگی را بهطور خودکار پویش کند؛ مانند فایلهای سرایند (header) که توسط فایلهای کد منبع فراخوانی شدهاند (برای نمونه، دستورهای پیشپردازندهٔ #include در فایلهای C یا C++)، در نتیجه نیازی به مشخصکردن دستی این وابستگیهای ضمنی (implicit dependencies) نیست. SCons از امکان تعریف پویشگرهای جدید برای پشتیبانی از انواع فایلهای ورودی دیگر نیز پشتیبانی میکند.
اطلاعات مربوط به فایلهای دخیل در ساخت، از جمله درهمسازی رمزنگارانه (cryptographic hash) محتویات فایلهای منبع، برای استفادهٔ مجدد در آینده کش میشوند. بهطور پیشفرض، این هش (امضای محتوا یا content signature) برای تصمیمگیری در مورد اینکه آیا فایلی از زمان آخرین ساخت تغییر کرده است یا خیر استفاده میشود، هرچند با انتخاب یک تابع Decider مناسب میتوان از الگوریتمهای دیگری نیز استفاده کرد. فایلهای وابستگی ضمنی نیز بخشی از محاسبات قدیمیبودن و نیاز به بازسازی (out-of-date) هستند. اطلاعات پویششدهٔ وابستگیهای ضمنی را میتوان بهصورت اختیاری کش کرد تا برای سرعت بخشیدن به ساختهای آینده به کار روند. همچنین هشِ هر اقدام ساختِ اجراشده (امضای ساخت یا build signature) کش میشود، تا تغییر در دستورالعملهای ساخت (تغییر پرچمها و غیره) یا تغییر در خود ابزارهای ساخت (مانند ارتقای کامپایلر) نیز بتواند ساخت مجدد را آغاز کند.
SCons از دایرکتوریهای منبع و ساخت مجزا (که “ساخت خارج از درخت” یا out-of-tree builds نیز نامیده میشود) از طریق تعریف دایرکتوریهای متغیر (variant directories) پشتیبانی میکند. استفاده از یک دایرکتوری ساخت جداگانه به پاکیزه نگهداشتن دایرکتوری منبع از مصنوعات هنگام جستجو کمک میکند، امکان برپایی ساختهای گوناگون (“گونهها” یا variants) را بدون تداخل فراهم میسازد، و بازنشانی ساخت را تنها با حذف دایرکتوری ساخت امکانپذیر میکند (توجه داشته باشید که SCons حالت “clean” نیز دارد). برای جزئیات بیشتر به بخش توضیحات VariantDir مراجعه کنید.
هنگام فراخوانی، scons در دایرکتوری جاری به دنبال فایلی میگردد که پیکربندی ساخت را توصیف کند و آن را میخواند. این فایل بهطور پیشفرض SConstruct نام دارد، هرچند برخی حالتهای دیگر آن، یا نامی که توسط توسعهدهنده انتخاب شده باشد نیز پذیرفته میشوند (بخش “فایلهای SConscript” را ببینید). در صورت یافتن، دایرکتوری جاری بهعنوان دایرکتوری اصلی پروژه تنظیم میشود. برخی از گزینههای خط فرمان مکانهای دیگری را برای جستجوی SConstruct مشخص میکنند (گزینههای -C، -D، -u و -U را ببینید)، که دایرکتوری اصلی پروژه را بر روی مسیر یافتشده تنظیم خواهند کرد. همچنین میتوان با گزینهٔ -f مسیری را برای پیکربندی ساخت مشخص کرد، که در این حالت دایرکتوری جاری همچنان دایرکتوری اصلی پروژه باقی میماند.
پیکربندی ساخت ممکن است به چندین فایل تقسیم شود: فایل SConstruct میتواند با فراخوانی تابع SConscript فایلهای پیکربندی بیشتری را مشخص کند، و هر فایلی که بدین صورت فراخوانی میشود نیز میتواند فایلهای بیشتری را به همین روش شامل شود. طبق قرارداد، این فایلهای فرعی SConscript نامیده میشوند، اگرچه میتوان از هر نامی استفاده کرد. در نتیجهٔ این قرارداد نامگذاری، اصطلاح “فایلهای SConscript” بهطور کلی برای اشاره به مجموعهٔ کامل فایلهای پیکربندی یک پروژه (شامل فایل SConstruct)، بدون در نظر گرفتن نامهای واقعی یا تعداد این فایلها، به کار میرود. یک ساخت سلسلهمراتبی بهصورت بازگشتی نیست - تمام فایلهای SConscript در یک مرحله (تکگذر) پردازش میشوند تا scons در هنگام بررسی آنچه باید ساخته شود، تصویری کامل از کل درخت وابستگی داشته باشد. هر فایل SConscript در یک بافتار (context) جداگانه پردازش میشود تا تنظیمات انجامشده در یک اسکریپت به اسکریپت دیگر نشت نکند؛ با این حال، اطلاعات را میتوان بهطور صریح میان اسکریپتها به اشتراک گذاشت.
پیش از خواندن فایلهای SConscript، دستور scons به دنبال یک site directory (دایرکتوری پایگاه) میگردد - دایرکتوریای به نام site_scons در دایرکتوریهای سیستمی مختلف و در دایرکتوری اصلی پروژه جستجو میشود، یا اگر گزینهٔ --site-dir داده شده باشد، تنها آن دایرکتوری بررسی میشود. دایرکتوریهای پایگاهِ یافتشده به ابتدای مسیر جستجوی ماژولهای Python (sys.path) افزوده میشوند، و بدین ترتیب اجازه میدهند تا ماژولهای موجود در چنین دایرکتوریهایی به روش معمول Python در فایلهای SConscript وارد (import) شوند. به ازای هر دایرکتوری پایگاه یافتشده، (۱) اگر حاوی فایلی به نام site_init.py باشد، آن فایل ارزیابی و اجرا میشود، و (۲) اگر حاوی دایرکتوریای به نام site_tools باشد، مسیر آن دایرکتوری به ابتدای toolpath پیشفرض افزوده میشود. برای جزئیات دربارهٔ مسیرهای پیشفرض و کنترل دایرکتوریهای پایگاه، گزینههای --site-dir و --no-site-dir را ببینید.
فایلهای SConscript به زبان برنامهنویسی Python نوشته میشوند. برای بسیاری از وظایف، نحو ساده را میتوان از روی مثالها فرا گرفت، بنابراین معمولاً برای استفادهٔ مؤثر از SCons نیازی به برنامهنویس Python بودن نیست. فایلهای SConscript در بستری اجرا میشوند که امکانات شرحدادهشده در این صفحهٔ راهنما را مستقیماً در دسترس قرار میدهد (یعنی نیازی به import کردن نیست). قابلیتهای استاندارد اسکریپتنویسی Python نظیر کنترل جریان، دستکاری دادهها و ماژولهای واردشدهٔ Python برای استفاده در پیکربندیهای پیچیدهتر ساخت در دسترس هستند. سایر فایلهای Python نیز میتوانند بخشی از سیستم ساخت شوند، اما بهطور خودکار از بستر SCons برخوردار نیستند و در صورت نیاز به دسترسی، باید آن را وارد (import) کنند (که بعداً توضیح داده شده است).
SCons تمام فایلهای SConscript درجشده را پیش از شروع ساخت هر هدفی، میخواند و اجرا میکند. پیامهای پیشرفت این رفتار را نشان میدهند (خطوط تغییر وضعیت - آنهایی که با برچسب scons: شروع میشوند - را میتوان با استفاده از گزینهٔ -Q پنهان کرد):
$ scons foo.out scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... cp foo.in foo.out scons: done building targets. $
برای تضمین ساختهای بازتولیدپذیر، SCons بهجای انتشار کامل محیطی که در زمان فراخوانی scons حاکم بوده است، از یک محیط اجرای محدود برای اجرای دستورات خارجی مورد نیاز برای ساخت اهداف استفاده میکند. این کار به جلوگیری از مشکلاتی مانند دریافت تنظیمات تصادفی یا مخرب، مقادیر اشکالزدایی موقتی که دیگر نیازی به آنها نیست، یا تفاوت تنظیمات یک توسعهدهنده با توسعهدهندهای دیگر (یا با خطلولهٔ CI) کمک میکند. متغیرهای محیطی مورد نیاز برای عملکرد صحیح این دستورات باید صریحاً در محیط اجرا تنظیم شوند، چه با انتساب مقادیر مورد نظر، یا با گزینش این مقادیر بهصورت جداگانه یا جمعی از میان متغیرهای محیطی ارائهشده توسط دیکشنری os.environ در Python (این مقادیر بهعنوان ورودیهای برنامهٔ خارجی باید قبل از استفاده اعتبارسنجی شوند). محیط اجرا برای یک محیط ساخت مشخص، مقدار $ENV آن است. تعداد کمی از متغیرهای محیطی بهطور خودکار توسط خود scons دریافت میشوند (بخش “محیط (ENVIRONMENT)” را ببینید).
بهویژه، اگر یک کامپایلر یا دستور خارجی دیگر که برای ساخت یک فایل هدف مورد نیاز است، در مکان استاندارد سیستم از نظر scons قرار نداشته باشد، در زمان اجرا پیدا نخواهد شد مگر اینکه شما صریحاً آن مکان را به مؤلفهٔ PATH در محیط اجرا اضافه کنید. این موضوع بهویژه در پلتفرمهای Windows قابل توجه است، جایی که نصب یک دستور در مکانی مختص به برنامه و وابستگی به تنظیم PATH برای پیدا شدن آن امری رایج است، که بهطور خودکار برای SCons کار نمیکند.
یک رویکرد نمونه، استخراج کامل متغیر محیطی PATH و تنظیم آن در محیط اجرا است:
import os
env = Environment(ENV={'PATH': os.environ['PATH']})
به همین ترتیب، اگر دستورات از متغیرهای محیطی خارجی خاصی استفاده میکنند که scons آنها را شناسایی نمیکند، میتوان آنها را به محیط اجرا منتقل کرد:
import os
env = Environment(
ENV={
'PATH': os.environ['PATH'],
'MODULEPATH': os.environ['MODULEPATH'],
'PKG_CONFIG_PATH': os.environ['PKG_CONFIG_PATH'],
}
)
یا میتوانید کل محیط خارجی کاربری را که برنامه را فراخوانی کرده است بهطور صریح منتقل کنید:
import os env = Environment(ENV=os.environ.copy())
این کار به بهای وابسته شدن ساخت شما به تنظیم صحیح محیط کاربر تمام میشود، اما ممکن است برای برخی پیکربندیها راحتتر باشد. اگر این کار در یک ساختار ساختی انجام شود که چگونگی تنظیم محیط را پیش از فراخوانی scons بهدقت کنترل میکند (مانند بسیاری از ساختارهای یکپارچهسازی مداوم یا CI)، نباید مشکلی ایجاد کند.
نکته
قطعهکدهای بالا برای نشان دادن یک مفهوم در نظر گرفته شدهاند. معمولاً پاک کردن کل مقدار پیشفرض محیط اجرا (env["ENV"]) ایدهٔ خوبی نیست، زیرا ممکن است حاوی اطلاعات مهمی برای اجرای دستورات ساخت باشد.
scons معمولاً در یک دایرکتوری سطح بالا که حاوی یک فایل SConstruct است (دایرکتوری ریشهٔ پروژه) اجرا میشود. هنگامی که scons فراخوانی میشود، خط فرمان (از جمله محتویات متغیر محیطی SCONSFLAGS در صورت تنظیم بودن) پردازش میشود. گزینههای خط فرمان (بخش “گزینهها (OPTIONS)” را ببینید) پردازش میشوند. هرگونه انتساب آرگومان متغیر جمعآوری شده و آرگومانهای باقیمانده بهعنوان اهدافی برای ساخت در نظر گرفته میشوند.
مقادیر متغیرهایی که باید به پروندههای SConscript ارسال شوند را میتوان در خط فرمان مشخص کرد:
scons debug=1
این متغیرها از طریق دیکشنری ARGUMENTS در دسترس هستند و میتوان از آنها در پروندههای SConscript برای تغییر فرایند ساخت به هر شکلی استفاده کرد:
if ARGUMENTS.get("debug", ""):
env = Environment(CCFLAGS="-g")
else:
env = Environment()
آرگومانهای متغیر خط فرمان همچنین در فهرست ARGLIST نیز در دسترس هستند، که بر پایهٔ ترتیب آنها در خط فرمان نمایهگذاری شدهاند. این ویژگی به شما امکان میدهد در صورت نیاز آنها را به ترتیب ورود، به جای نام پردازش کنید. هر مدخل ARGLIST یک تاپل متشکل از نام و مقدار است.
برای اطلاعات بیشتر، بخش “Command-Line Construction Variables” را ببینید.
scons میتواند حافظهٔ نهان (cache) فایلهای هدف (مشتقشده) را نگهداری کند تا بتوان آنها را بین چندین فرایند ساخت به اشتراک گذاشت. هنگامی که کش کردن فایلهای مشتقشده در یک پروندهٔ SConscript فعال باشد، هر فایل هدفی که توسط scons ساخته شود در کش کپی خواهد شد. اگر یک فایل هدف بهروز در کش یافت شود، به جای ساخت مجدد به صورت محلی، از کش بازیابی میشود. رفتار کش را میتوان غیرفعال کرد و با استفاده از گزینههای خط فرمان --cache-force، --cache-disable، --cache-readonly و --cache-show به شیوههای دیگر کنترل نمود. گزینهٔ --random برای جلوگیری از تلاش همزمان چندین فرایند ساخت جهت بهروزرسانی کش مفید است.
بهطور پیشفرض، scons در سیستمهای گوناگون به دنبال ابزارهای برنامهنویسی شناختهشده میگردد و بر اساس آنچه یافته است خود را مقداردهی اولیه میکند. در سیستمهای Windows که با عنوان win32 شناسایی میشوند، scons به ترتیب به دنبال ابزارهای Microsoft Visual C++، زنجیره ابزار MinGW، ابزارهای کامپایلر Intel، ابزارهای GCC، ابزارهای LLVM/clang و کامپایلر PharLap ETS میگردد. در سیستمهای Windows که به عنوان cygwin شناسایی میشوند (یعنی اگر scons از درون یک پوستهٔ cygwin اجرا شود)، این اولویت تغییر کرده و زنجیره ابزار GCC بر ابزارهای MSVC ترجیح داده میشود. در سیستمهای OS/2، scons به ترتیب به دنبال کامپایلر OS/2، زنجیره ابزار GCC و ابزارهای Microsoft Visual C++ میگردد. در سیستمهای SGI IRIX، IBM AIX، Hewlett Packard HP-UX و Oracle Solaris، scons به دنبال ابزارهای کامپایلر بومی (به ترتیب ابزارهای MIPSpro، Visual Age، aCC و Forte) و زنجیره ابزار GCC میگردد. در FreeBSD و OpenBSD، scons به ترتیب به دنبال ابزارهای LLVM/clang، زنجیره ابزار GCC و ابزارهای کامپایلر Intel میگردد. در تمامی پلتفرمهای دیگر، شامل پلتفرمهای POSIX (Linux و UNIX) و macOS، scons به ترتیب به دنبال زنجیره ابزار GCC، ابزارهای LLVM/clang و ابزارهای کامپایلر Intel میگردد. انتخاب پیشفرض ابزارها میتواند با استفاده از آرگومان tools در متدهای ایجاد construction environment، فراخوانی صریح بارگذار Tool، یا از طریق تنظیم متغیرهای مختلف construction variables نادیده گرفته و جایگزین شود.
انتخاب هدف (Target Selection)
SCons بر روی هدفهای انتخابشده عمل میکند، صرفنظر از اینکه عملیات درخواستی ساخت (build)، بدوناجرا (no-exec) یا پاکسازی (clean) باشد. هدفها به روش زیر انتخاب میشوند:
برای نادیدهگرفتن هدفهای پیشفرضی که از طریق فراخوانیهای Default مشخص شدهاند و در عوض ساخت تمام فایلهای هدف در دایرکتوری جاری یا زیرشاخههای آن، دایرکتوری جاری (.) را به عنوان یک هدف در خط فرمان مشخص کنید:
scons .
برای ساخت تمام فایلهای هدف، از جمله هر فایلی خارج از دایرکتوری جاری، دایرکتوری ریشه (root) را به عنوان هدف خط فرمان تعیین کنید (در سیستمهای POSIX):
scons /
یا نام مسیر درایو(هایی) که تمام هدفها باید در آن ساخته شوند (در سیستمهای Windows):
scons C:\ D:\
میتوان زیرمجموعهای از یک ساختار درختی سلسلهمراتبی را با ماندن در دایرکتوری اصلی پروژه و مشخص کردن زیردایرکتوری به عنوان هدفِ ساخت، ایجاد کرد:
scons src/subdir
یا با تغییر دایرکتوری و اجرای scons با گزینهٔ -u که ساختار سلسلهمراتبی دایرکتوری را به سمت بالا پیمایش میکند تا زمانی که فایل SConstruct را بیابد، و سپس هدفها را نسبت به زیردایرکتوری جاری میسازد (همچنین گزینههای مرتبط -D و -U را ببینید):
cd src/subdir scons -u .
در تمام موارد، ممکن است فایلهای بیشتری نسبت به آنچه درخواست شده ساخته شوند، زیرا scons باید اطمینان حاصل کند که تمام فایلهای وابسته ساخته شدهاند.
مشخص کردن اهداف «پاکسازی» در فایلهای SConscript معمولاً ضروری نیست. پرچم -c تمام اهداف انتخابشده را حذف میکند:
scons -c .
برای حذف تمام فایلهای هدف درون یا زیر دایرکتوری جاری، یا:
scons -c build export
برای حذف فایلهای هدف زیر build و export.
فایلها یا دایرکتوریهای اضافی برای حذف را میتوان با استفاده از تابع Clean در فایلهای SConscript مشخص کرد. در مقابل، اهدافی که بهطور معمول با فراخوانی -c حذف میشوند را میتوان با فراخوانی تابع NoClean به همراه آن اهداف، نگه داشت.
scons از ساخت چندین هدف بهصورت موازی از طریق گزینهٔ -j پشتیبانی میکند که تعداد وظایف همزمانی که میتوانند ایجاد شوند را به عنوان آرگومان خود میپذیرد:
scons -j 4
برای نمونه، چهار هدف را بهصورت موازی میسازد.
گزینهها (OPTIONS)
بهطور کلی، scons از همان گزینههای خط فرمان گنو Make و بسیاری از گزینههای پشتیبانیشده توسط cons پشتیبانی میکند.
-b
-c, --clean, --remove
در حالی که حالت پاکسازی به جای ساخت اهداف آنها را حذف میکند، کارهایی که مستقیماً در کد Python درون فایلهای SConscript انجام میشوند همچنان اجرا خواهند شد. اگر مهم است که از انجام برخی از این کارها در حالت پاکسازی جلوگیری شود، باید از آنها محافظت شود. یک فایل SConscript میتواند با پرسوجو از GetOption، مانند فراخوانی if GetOption("clean"): تشخیص دهد که کدام حالت فعال است.
--cache-debug=file
--cache-disable, --no-cache
--cache-force, --cache-populate
--cache-readonly
--cache-show
--config=mode
auto
force
cache
-C directory, --directory=directory
-D
--debug=type[,type...]
action-timestamps
جدید در نسخه 3.1.
count
duplicate
explain
findlibs
includes
$ scons --debug=includes foo.o
json
فایل خروجی پیشفرض عبارت است از scons_stats.json
نام یا مسیر فایل را میتوان با استفاده از DebugOptions تغییر داد؛ برای نمونه: DebugOptions(json='path/to/file.json')
$ scons --debug=memory,json foo.o
memoizer
memory
objects
pdb
$ scons --debug=pdb > /usr/lib/python3.11/site-packages/SCons/Script/Main.py(869)_main() -> options = parser.values (Pdb)
نکته
ابزار pdb در هنگام راهاندازی، در ابتدای روال اصلی (main routine) scons متوقف خواهد شد. مسیر جستجو (sys.path) در آن نقطه شامل مکان scons در حال اجرا خواهد بود، اما شامل خود پروژه نخواهد بود. اگر نیاز به تنظیم نقاط توقف (breakpoints) در فایلهای پروژهٔ خود دارید، یا باید آن را به مسیر اضافه کنید، یا هنگام ارجاع به فایلهای پروژه از مسیرهای مطلق استفاده نمایید. میتوان از یک فایل .pdbrc در ریشهٔ پروژه برای افزودن دایرکتوری جاری به مسیر جستجو استفاده کرد تا از وارد کردن دستی آن جلوگیری شود؛ مانند زیر:
sys.path.append('.')
به دلیل نحوهٔ پیادهسازی ماژول pdb، دستورهای break، tbreak و clear تنها ارجاع به نام فایلهایی را متوجه میشوند که دارای پسوند .py باشند (اگرچه خود پسوند را میتوان نادیده گرفت)، مگر اینکه از یک مسیر مطلق استفاده کنید. به عنوان یک استثنای ویژه برای این قاعده، نامهای SConstruct و SConscript بدون نیاز به پسوند .py شناخته میشوند.
تغییریافته در نسخهٔ 4.6.0: نامهای SConstruct و SConscript اکنون بدون نیاز به پسوند .py شناخته میشوند.
تغییریافته در نسخهٔ 4.8.0: نام SCsub اکنون بدون نیاز به پسوند .py شناخته میشود.
prepare
presub
$ scons --debug=presub Building myprog.o with action(s): $SHCC $SHCFLAGS $SHCCFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES ...
stacktrace
time
(هنگامی که scons بدون گزینه -j اجرا میشود، زمان واقعی سپریشده معمولاً به دلیل پردازشهای SCons که در بین اجرای هر فرمان انجام میشود، اندکی طولانیتر از زمان کل صرفشده برای اجرای همه فرمانهای ساخت خواهد بود. هنگامی که scons همراه با گزینه -j اجرا شود، و پیکربندی ساخت شما امکان موازیسازی مناسب را بدهد، زمان واقعی سپریشده باید به طور قابل توجهی کمتر از کل زمان صرفشده برای اجرای همه فرمانهای ساخت باشد، زیرا چندین فرمان ساخت و پردازشهای میانی SCons باید به طور همروند انجام شوند.)
sconscript
--diskcheck=type
بررسیهای موجود فعلی عبارتند از:
match
غیرفعال کردن برخی یا همهٔ این بررسیها میتواند کارایی را در پیکربندیهای بزرگ، یا زمانی که پیکربندیْ فایلها و/یا دایرکتوریها را در سیستمهای فایل شبکهای یا اشتراکی بررسی میکند، افزایش دهد؛ البته با افزایش اندک خطر یک ساخت نادرست یا عدم مدیریت مناسب خطاها.
--duplicate=ORDER
--enable-virtualenv
--experimental=feature
ویژگیهای موجود فعلی عبارتند از ninja (جدید در نسخه 4.2) و legacy_sched_deprecated (جدید در، و منسوخشده از نسخه 4.11.0).
نکته
زمانبند قدیمی (legacy scheduler) دقیقاً یک ویژگی آزمایشی نیست. این پرچم ویژگی، زمانبند کارهایی را انتخاب میکند که پیش از نسخه 4.7 در SCons پیشفرض بوده است. این پرچم ویژگی به عنوان legacy_sched در نسخه 4.7 معرفی شد. زمانبند قدیمی قرار است در یک انتشار آینده حذف شود، بنابراین این پرچم ویژگی اکنون منسوخ شده است. در نسخه 4.11.0، نام آن به legacy_sched_deprecated تغییر یافت تا کاربران فعلی هشداری دریافت کنند - به دلیل ماهیت پرچمهای ویژگیهای آزمایشی، استفاده از سازوکار استاندارد هشدار منسوخسازی SCons در اینجا امکانپذیر نیست.
احتیاط
ویژگیهای آزمایشی فاقد هرگونه تعهد در زمینهٔ سازگاری هستند - یک ویژگی معین ممکن است در نسخههای بعدی تغییرات چشمگیری داشته باشد یا به طور کامل حذف شود.
-f file, --file=file, --makefile=file, --sconstruct=file
-h, --help
توجه داشته باشید که استفاده از این گزینه مستلزم آن است که SCons فایلهای SConscript را پردازش کند، بنابراین خطاهای نحوی ممکن است مانع از نمایش پیام راهنما شوند.
--hash-chunksize=KILOBYTES
مقدار پیشفرض استفاده از تکههای ۶۴ کیلوبایتی است که باید برای اغلب کاربردها مناسب باشد.
جدید در نسخه 4.1.
--hash-format=ALGORITHM
فهرست مقادیر پشتیبانیشده عبارتند از: md5، sha1 و sha256. با این حال، مفسر Python استفادهشده برای اجرای scons باید پشتیبانی متناظر را در ماژول hashlib داشته باشد تا بتواند از الگوریتم مشخصشده استفاده کند.
اگر این گزینه مشخص نشود، نخستین قالب هش پشتیبانیشدهٔ یافتشده انتخاب میشود. معمولاً این قالب MD5 است، اما در یک سیستم منطبق با FIPS با نسخهای از Python قدیمیتر از 3.9، به طور پیشفرض SHA1 یا SHA256 انتخاب میشود. کلاینتهای Python نسخهٔ 3.9 به بعد همواره به صورت پیشفرض از MD5 استفاده میکنند، حتی در حالت FIPS.
مشخص کردن این گزینه نام پایگاهدادهٔ SConsign را تغییر میدهد. پایگاهدادهٔ پیشفرض .sconsign.dblite است. در صورت وجود این گزینه، ALGORITHM برای نشان دادن تفاوت در نام گنجانده میشود، حتی اگر آرگومان md5 باشد. برای نمونه، --hash-format=sha256 از یک پایگاهدادهٔ SConsign به نام .sconsign_sha256.dblite استفاده میکند.
جدید در نسخه 4.1.
-H, --help-options
-i, --ignore-errors
-I directory, --include-dir=directory
--ignore-virtualenv
--implicit-cache
scons تغییرات در مسیرهای جستجوی وابستگی ضمنی (مانند $CPPPATH، $LIBPATH) را که معمولاً باعث استفاده از نسخههای متفاوتی از فایلهای همنام میشوند، تشخیص نخواهد داد.
scons تغییرات در وابستگیهای ضمنی را در مواردی که یک وابستگی ضمنیِ جدید در مسیر جستجوی وابستگیهای ضمنی (مانند $CPPPATH، $LIBPATH) پیش از یک وابستگی ضمنیِ همنامِ فعلی اضافه شود، متوجه نخواهد شد.
--implicit-deps-changed
--implicit-deps-unchanged
--install-sandbox=sandbox_path
--interactive
حالت تعاملی SCons از دستورات زیر پشتیبانی میکند:
build [OPTIONS] [TARGETS] ...
گزینههای خط فرمان زیر در SCons بر دستور build تأثیر میگذارند:
--cache-debug=FILE --cache-disable, --no-cache --cache-force, --cache-populate --cache-readonly --cache-show --debug=TYPE -i, --ignore-errors -j N, --jobs=N -k, --keep-going -n, --no-exec, --just-print, --dry-run, --recon -Q -s, --silent, --quiet --taskmastertrace=FILE --tree=OPTIONS
هر گزینهٔ خط فرمان دیگری از SCons که مشخص شود، باعث خطا نخواهد شد اما هیچ تأثیری بر دستور build نخواهد داشت (عمدتاً به این دلیل که آنها بر نحوهٔ خوانده شدن فایلهای SConscript تأثیر میگذارند، که تنها یکبار در ابتدای حالت تعاملی رخ میدهد).
clean [OPTIONS] [TARGETS] ...
exit
help [COMMAND]
shell [COMMANDLINE]
version
یک خط خالی آخرین دستور تایپشده را تکرار میکند. اگر ماژول readline در دسترس باشد، میتوان از ویرایش خط فرمان استفاده کرد.
$ scons --interactive scons: Reading SConscript files ... scons: done reading SConscript files. scons>>> build -n prog scons>>> exit
-j N, --jobs=N
-k, --keep-going
-m
--max-drift=SECONDS
--md5-chunksize=KILOBYTES
تغییریافته در نسخه 4.2: منسوخ شد.
-n, --no-exec, --just-print, --dry-run, --recon
تنها ساخت اهداف متوقف میشود - هر کاری در سامانه ساخت که به طور مستقیم (در کد معمولی Python) انجام میشود، همچنان اجرا خواهد شد. میتوانید کدهایی را که نباید در حالت no-exec اجرا شوند، با بررسی مقدار گزینه در زمان اجرا توسط GetOption محافظت کنید:
if not GetOption("no_exec"):
# run regular instructions
خروجی در حد بیشترین تلاش است، زیرا SCons همیشه نمیتواند با دقت تعیین کند که چه چیزی ساخته خواهد شد. برای نمونه، اگر فایلی که توسط کنش یک سازنده (builder action) تولید شده به عنوان منبع نیز در ساخت به کار رود، آن فایل در یک درخت ساختهنشده اصلاً برای بررسی وابستگیها در دسترس نیست و ممکن است در درختی که قبلاً ساخته شده شامل اطلاعات قدیمی باشد.
SCons نمیتواند بررسیهای Configure را در حالت no-exec انجام دهد، زیرا آنها تغییراتی در سامانه فایل ایجاد میکنند (به $CONFIGUREDIR و $CONFIGURELOG مراجعه کنید). در صورتی که اطلاعات ذخیرهشده از ساخت قبلی قدیمی نشده باشند، میتواند از آنها استفاده کند، بنابراین یک ساخت «آمادهسازی» (priming) ممکن است اجراهای بعدی no-exec را کارآمدتر کند.
--no-site-dir
--package-type=type
--profile=file
-q, --question
-Q
--random
-s, --silent, --quiet
-S, --no-keep-going, --stop
--site-dir=path
مجموعه پیشفرض دایرکتوریهای سایتی که هنگام مشخص نشدن --site-dir جستجو میشوند، بسته به بستر سیستم به شرح زیر است. کاربران یا مدیران سیستم میتوانند رفتار خاص سایت یا پروژه را در SCons با برپایی یک دایرکتوری سایت در یک یا چند مورد از این مکانها تنظیم کنند. دایرکتوریها به ترتیبی که داده شدهاند، از عمومیترین (دایرکتوریهای «سیستمی») تا خاصترین (در پروژه جاری) بررسی میشوند؛ بنابراین آخرین فایل site_init.py اجراشده خاصترین فایل است و امکان بازنویسی همه موارد دیگر را دارد، و دایرکتوریها به ابتدای مسیرها اضافه میشوند تا باز هم آخرین دایرکتوری بررسیشده، در ابتدای مسیر حاصل قرار گیرد.
Windows:
%ALLUSERSPROFILE%/scons/site_scons %LOCALAPPDATA%/scons/site_scons %APPDATA%/scons/site_scons %USERPROFILE%/.scons/site_scons ./site_scons
توجه داشته باشید که نسخههای پیشین مستندات، مسیر متفاوتی را برای دایرکتوری سایت «سیستمی» فهرست کرده بودند؛ این مسیر همچنان بررسی میشود اما استفاده از آن توصیه نمیگردد:
%ALLUSERSPROFILE%/Application Data/scons/site_scons
Mac OS X:
/Library/Application Support/SCons/site_scons /opt/local/share/scons/site_scons (for MacPorts) /sw/share/scons/site_scons (for Fink) $HOME/Library/Application Support/SCons/site_scons $HOME/.scons/site_scons ./site_scons
Solaris:
/opt/sfw/scons/site_scons /usr/share/scons/site_scons $HOME/.scons/site_scons ./site_scons
Linux، HPUX و دیگر سیستمهای شبه-Posix:
/usr/share/scons/site_scons $HOME/.scons/site_scons ./site_scons
--stack-size=KILOBYTES
استفاده از اندازه پشته بسیار کوچک ممکن است سبب خطاهای سرریز پشته (stack overflow) شود. این حالت معمولاً به صورت خطاهای دسترسی به حافظه (segmentation fault) بروز میکند که باعث خاتمه نابهنگام scons پیش از ساخت هر چیزی میشود. استفاده از اندازه پشته بسیار بزرگ باعث مصرف حافظه بیش از حد نیاز توسط scons شده و ممکن است کل فرایند ساخت را کُند کند. مقدار پیشفرض، استفاده از اندازه پشته ۲۵۶ کیلوبایت است که باید برای بیشتر کاربردها مناسب باشد. نیازی به افزایش این مقدار نخواهید داشت مگر اینکه با خطاهای سرریز پشته مواجه شوید.
-t, --touch
--taskmastertrace=file
--tree=type[,type...]
all
derived
linedraw
جدید در نسخهٔ 4.0.
status
prune
میتوان چندین گزینه برای type را با کاما از یکدیگر جدا و مشخص کرد:
# تنها فایلهای مشتقشده را همراه با اطلاعات وضعیت چاپ میکند: scons --tree=derived,status # تمام وابستگیهای هدف را با اطلاعات وضعیت و هرس کردن # وابستگیهای گرههای قبلاً دیدهشده چاپ میکند: scons --tree=all,prune,status target
-u, --up, --search-up
-U
-v, --version
-w, --print-directory
--no-print-directory
--warn=type, --warn=no-type
all
cache-version
cache-write-error
cache-cleanup-error
corrupt-sconsign
dependency
deprecated
duplicate-environment
fortran-cxx-mix
future-reserved-variable
future-deprecated
link
misleading-keywords
no-object-count
توجه داشته باشید که پیشوند "no-" بخشی از نام این هشدار است. برای غیرفعال کردن، یک "-no" دیگر بیفزایید.
no-parallel-support
توجه داشته باشید که پیشوند "no-" بخشی از نام این هشدار است. برای غیرفعال کردن، یک "-no" دیگر بیفزایید.
python-version
reserved-variable
stack-size
target-not-built
-Y repository، --repository=repository، --srcdir=repository
مرجع فایلهای SCONSCRIPT (SCONSCRIPT FILE REFERENCE)
فایلهای SConscript (SConscript Files)
پیکربندی ساخت با یک یا چند فایل توصیف میشود که با نام فایلهای SConscript شناخته میشوند. برای یک ساخت معتبر باید حداقل یک فایل وجود داشته باشد (scons در صورتی که چنین فایلی پیدا نکند خارج خواهد شد). scons بهطور پیشفرض به دنبال این فایل با نام SConstruct در دایرکتوریای که scons را از آن اجرا میکنید میگردد، هرچند در صورت لزوم، به ترتیب به دنبال نامهای جایگزین Sconstruct، sconstruct، SConstruct.py، Sconstruct.py و sconstruct.py نیز میگردد. نام فایل متفاوتی (که میتواند شامل بخشی از مسیر باشد) را میتوان از طریق گزینهٔ -f مشخص کرد. بهجز فایل SConstruct، این فایلها بهطور خودکار جستجو نمیشوند؛ شما فایلهای پیکربندی اضافی را با فراخوانی تابع SConscript به فرایند ساخت اضافه میکنید. این ویژگی اجازه میدهد تا بخشهایی از ساخت، بسته به نحوهٔ فراخوانی scons، در زمان اجرا بهطور شرطی گنجانده یا حذف شوند.
هر فایل SConscript در یک پیکربندی ساخت، بهطور مستقل در یک زمینه (context) جداگانه فراخوانی میشود. این کار جداسازی لازم را فراهم میکند تا بخشهای مختلف ساخت تصادفاً با یکدیگر تداخل پیدا نکنند. برای بهاشتراکگذاری اطلاعات باید صریح عمل کنید؛ این کار با استفاده از تابع Export یا آرگومان exports در تابع SConscript، و همچنین تابع Return در فایل SConscript فراخوانیشده، و مصرف اطلاعات بهاشتراکگذاشتهشده با استفاده از تابع Import انجام میپذیرد.
بخشهای زیر امکانات مختلف SCons را که میتوان در فایلهای SConscript استفاده کرد شرح میدهند. پیوندهای سریع:
محیطهای ساخت (Construction Environments)
یک محیط ساخت (Construction Environment) ابزار پایهای است که از طریق آن اطلاعات ساخت را به SCons منتقل میکنید. یک محیط ساخت جدید با استفاده از تابع Environment ایجاد میشود:
env = Environment()
ویژگیهای محیط ساخت که متغیرهای ساخت (Construction Variables) نامیده میشوند، میتوانند با تعیین آنها به عنوان آرگومانهای کلیدواژهای هنگام ساخت شیء یا با انتساب مقدار به آنها پس از ایجاد شیء تنظیم شوند. این دو شیوه اسماً معادل یکدیگر هستند:
env = Environment(FOO='foo') env['FOO'] = 'foo'
توجه داشته باشید که برخی از تنظیمات مؤثر بر شناسایی ابزارها، تنها زمانی که ابزارها مقداردهی اولیه میشوند مورد ارجاع قرار میگیرند؛ بنابراین باید آنها را یا به عنوان بخشی از فراخوانی Environment ارائه دهید، یا مقداردهی اولیه ابزار را به تعویق بیندازید. برای مثال، مقداردهی اولیه نسخه Microsoft Visual C++ که قصد استفاده از آن را دارید:
# initializes msvc to v14.1
env = Environment(MSVC_VERSION="14.1")
env = Environment()
# msvc tool was initialized to default, does not reinitialize
env['MSVC_VERSION'] = "14.1"
env = Environment(tools=[])
env['MSVC_VERSION'] = "14.1"
# msvc tool initialization was deferred, so will pick up new value
env.Tool('default')
برای سهولت، متغیرهای ساخت میتوانند توسط آرگومان کلیدواژهای parse_flags در حین ساخت شیء نیز تنظیم یا اصلاح شوند؛ این کار اثری مشابه اعمال متد env.MergeFlags روی مقدار آرگومان پس از تکمیل تمام پردازشهای دیگر دارد. این قابلیت در صورتی مفید است که محتوای دقیق پرچمها نامشخص باشد (برای مثال، از یک فایل کنترلی خوانده شود) یا اگر لازم باشد پرچمها بین چندین متغیر ساخت توزیع شوند. env.ParseFlags نحوه توزیع این آرگومانها بین متغیرهای ساخت را شرح میدهد.
env = Environment(parse_flags='-Iinclude -DEBUG -lm')
این مثال 'include' را به متغیر ساخت $CPPPATH، مقدار 'EBUG' را به $CPPDEFINES و 'm' را به $LIBS اضافه میکند.
یک محیط ساخت موجود را میتوان با فراخوانی متد env.Clone تکثیر کرد. بدون آرگومان، این متد یک کپی با همان تنظیمات ایجاد میکند. در غیر این صورت، env.Clone همان آرگومانهای Environment را میپذیرد و از آنها برای ایجاد یک رونوشت اصلاحشده استفاده میکند.
SCons یک محیط ساخت ویژه به نام محیط پیشفرض (Default Environment) فراهم میکند. محیط پیشفرض تنها برای توابع عمومی استفاده میشود، یعنی درخواستهای ساختی که بدون بستر یک محیط ساخت معمولی فراخوانی شدهاند. برای اطلاعات بیشتر DefaultEnvironment را ببینید.
بهطور پیشفرض، یک محیط ساخت جدید با مجموعهای از متدهای سازنده (builder methods) و متغیرهای ساخت که متناسب با بستر (platform) جاری هستند مقداردهی اولیه میشود. از آرگومان کلیدواژهای اختیاری platform میتوان برای تعیین اینکه محیط ساخت باید برای یک بستر متفاوت مقداردهی اولیه شود، استفاده کرد:
env = Environment(platform='cygwin')
مشخص کردن یک بستر (platform)، متغیرهای ساخت مناسب را در محیط مقداردهی اولیه میکند تا از نامهای فایل با پیشوندها و پسوندهای مناسب آن بستر استفاده کرده و آنها را تولید نماید.
توجه داشته باشید که بستر win32 متغیرهای SystemDrive و SystemRoot را از محیط خارجی کاربر به دیکشنری ENV در محیط ساخت اضافه میکند. این امر بدان دلیل است که هر دستور اجرایی که از سوکتها برای اتصال با سایر سیستمها استفاده میکند، در سیستمهای ویندوز به درستی کار کند.
آرگومان platform میتواند یک مقدار رشتهای به نشانه یکی از بسترهای از پیش تعریفشده (aix، cygwin، darwin، hpux، irix، os2، posix، sunos یا win32)، یا یک شیء بستر قابل فراخوانی (callable) برگرداندهشده توسط فراخوانی Platform برای انتخاب یک بستر از پیش تعریفشده باشد، یا میتواند یک شیء قابل فراخوانی ارائهشده توسط کاربر باشد که در این صورت متد Environment آن را برای بهروزرسانی محیط ساخت جدید فراخوانی خواهد کرد:
def my_platform(env):
env['VAR'] = 'xyzzy'
env = Environment(platform=my_platform)
توجه داشته باشید که تعیین یک platform غیرپیشفرض یا تابع سفارشی برای مقداردهی اولیه ممکن است تنظیماتی را که باید برای سیستم میزبان انجام شوند دور بزند و باید با احتیاط استفاده شود. این کار بیش از همه در مواردی کاربرد دارد که platform جایگزینی برای موردی باشد که بهطور خودکار شناسایی میشد؛ مانند platform="cygwin" در سیستمی که در غیر این صورت به عنوان win32 شناسایی میشد.
آرگومانهای کلیدواژهای اختیاری tools و toolpath بر نحوه مقداردهی اولیه ابزارهای در دسترس محیط تأثیر میگذارند. برای جزئیات، به بخش “Tools” مراجعه کنید.
آرگومان کلیدواژهای اختیاری variables امکان ارسال یک شیء Variables را فراهم میکند که در مقداردهی اولیه محیط ساخت استفاده خواهد شد. برای جزئیات، به بخش “Command-Line Construction Variables” مراجعه کنید.
ابزارها (Tools)
SCons دارای ماژولهای ابزار درونی متعددی است (بهطور دقیقتر، ماژولهای مشخصات ابزار) که برای کمک به مقداردهی اولیه محیط ساخت پیش از ساخت بهکار میروند؛ همچنین میتوان ماژولهای بیشتری را برای اهداف خاص نوشت، یا از منابع خارجی اضافه کرد (مخزنی از ابزارهای ارائهشده توسط کاربران در دسترس است). اطلاعات بیشتر درباره نوشتن ابزارهای سفارشی را میتوانید در بخش Extending SCons و بهویژه Tool Modules بیابید.
یک ابزار SCons تنها مسئول برپاسازی است. برای نمونه، اگر یک فایل SConscript با فراخوانی سازنده (builder) Object، نیاز به ساخت یک فایل هدف (object file) از یک فایل مبدأ زبان C را اعلام کند، ابتدا باید ماژول ابزاری که نشاندهنده یک کامپایلر C موجود است اجرا شده باشد تا آن builder و تمام متغیرهای ساخت مورد نیازش را در محیط ساخت مربوطه برپا سازد. خود ابزار در فرایند ساخت فراخوانی نمیشود. برپاسازی ابزار هنگام ایجاد یک محیط ساخت رخ میدهد و در حالت عادی نیازی به مداخله ندارد - فهرست ابزارهای پیشفرض وابسته به هر platform برای بررسی قابلیتهای خاص آن platform و پیکربندی محیط استفاده میشوند و از ابزارهایی که قابل اعمال نیستند صرفنظر میشود.
در صورت نیاز، میتوان مجموعه خاصی از ابزارها را برای مقداردهی اولیه در یک محیط در حین ایجاد آن، با استفاده از آرگومان اختیاری tools مشخص کرد. tools باید یک لیست (list) باشد، حتی اگر شامل یک (یا صفر) ابزار باشد. این قابلیت برای بازنویسی پیشفرضها، تعیین ابزارهای توکارِ غیرپیشفرض، و فراخوانی ابزارهای اضافهشده مفید است:
env = Environment(tools=['msvc', 'lex'])
آرگومان tools فهرست ابزارهای پیشفرض را بازنویسی میکند و به آن اضافه نمیشود؛ بنابراین حتماً تمام ابزارهای مورد نیاز خود را درج کنید. برای مثال، اگر در حال ساخت یک برنامه C/C++ هستید، باید دستکم یک ابزار برای کامپایلر و پیونددهنده (linker) تعیین کنید، مانند: tools=['clang', 'link'].
اگر آرگومان tools حذف شود، یا اگر tools شامل نام رزروشده 'default' باشد، آنگاه SCons ابزارهای قابل استفاده را با بهکارگیری مسیر جستجو در محیط اجرا (یعنی env['ENV']['PATH']) برای یافتن برنامههای خارجی، و نام پلتفرم فعال برای تعیین ابزارهای پیشفرض آن پلتفرم، بهطور خودکار شناسایی میکند. توجه داشته باشید که محتویات PATH از محیط خارجی os.environ استفاده نمیشود. تغییر دادن PATH در محیط اجرا پس از ایجاد محیط ساخت، باعث شناسایی مجدد ابزارها نخواهد شد.
ابزارها را میتوان مستقیماً با استفاده از متد Tool نیز فراخوانی کرد (به بخش زیر مراجعه کنید).
SCons بهصورت پیشفرض از مشخصات ابزار زیر پشتیبانی میکند:
386asm
تنظیم میکند: $AS, $ASCOM, $ASFLAGS, $ASPPCOM, $ASPPFLAGS.
استفاده میکند: $CC, $CPPFLAGS, $_CPPDEFFLAGS, $_CPPINCFLAGS.
aixc++
تنظیم میکند: $CXX, $CXXVERSION, $SHCXX, $SHOBJSUFFIX.
aixcc
تنظیم میکند: $CC, $CCVERSION, $SHCC.
aixf77
تنظیم میکند: $F77, $SHF77.
aixlink
تنظیم میکند: $LINKFLAGS, $SHLIBSUFFIX, $SHLINKFLAGS.
applelink
تنظیم میکند: $APPLELINK_COMPATIBILITY_VERSION, $APPLELINK_CURRENT_VERSION, $APPLELINK_NO_COMPATIBILITY_VERSION, $APPLELINK_NO_CURRENT_VERSION, $FRAMEWORKPATHPREFIX, $LDMODULECOM, $LDMODULEFLAGS, $LDMODULEPREFIX, $LDMODULESUFFIX, $LINKCOM, $SHLINKCOM, $SHLINKFLAGS, $_APPLELINK_COMPATIBILITY_VERSION, $_APPLELINK_CURRENT_VERSION, $_FRAMEWORKPATH, $_FRAMEWORKS.
استفاده میکند از: $FRAMEWORKSFLAGS.
ar
تنظیم میکند: $AR, $ARCOM, $ARFLAGS, $LIBPREFIX, $LIBSUFFIX, $RANLIB, $RANLIBCOM, $RANLIBFLAGS.
as
تنظیم میکند: $AS, $ASCOM, $ASFLAGS, $ASPPCOM, $ASPPFLAGS.
استفاده میکند از: $CC, $CPPFLAGS, $_CPPDEFFLAGS, $_CPPINCFLAGS.
bcc32
تنظیم میکند: $CC, $CCCOM, $CCFLAGS, $CFILESUFFIX, $CFLAGS, $CPPDEFPREFIX, $CPPDEFSUFFIX, $INCPREFIX, $INCSUFFIX, $SHCC, $SHCCCOM, $SHCCFLAGS, $SHCFLAGS, $SHOBJSUFFIX.
استفاده میکند از: $_CPPDEFFLAGS, $_CPPINCFLAGS.
cc
تنظیم میکند: $CC, $CCCOM, $CCDEPFLAGS, $CCFLAGS, $CFILESUFFIX, $CFLAGS, $CPPDEFPREFIX, $CPPDEFSUFFIX, $FRAMEWORKPATH, $FRAMEWORKS, $INCPREFIX, $INCSUFFIX, $SHCC, $SHCCCOM, $SHCCFLAGS, $SHCFLAGS, $SHOBJSUFFIX.
استفاده میکند از: $CCCOMSTR, $PLATFORM, $SHCCCOMSTR.
clang
تنظیم میکند: $CC, $CCDEPFLAGS, $CCVERSION, $SHCCFLAGS.
clangxx
تنظیم میکند: $CXX, $CXXVERSION, $SHCXXFLAGS, $SHOBJSUFFIX, $STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME.
compilation_db
تنظیم میکند: $COMPILATIONDB_COMSTR, $COMPILATIONDB_PATH_FILTER, $COMPILATIONDB_USE_ABSPATH.
cvf
تنظیم میکند: $FORTRAN, $FORTRANCOM, $FORTRANMODDIR, $FORTRANMODDIRPREFIX, $FORTRANMODDIRSUFFIX, $FORTRANPPCOM, $OBJSUFFIX, $SHFORTRANCOM, $SHFORTRANPPCOM.
استفاده میکند از: $CPPFLAGS, $FORTRANFLAGS, $SHFORTRANFLAGS, $_CPPDEFFLAGS, $_FORTRANINCFLAGS, $_FORTRANMODFLAG.
cXX
تنظیم میکند: $CPPDEFPREFIX, $CPPDEFSUFFIX, $CXX, $CXXCOM, $CXXFILESUFFIX, $CXXFLAGS, $INCPREFIX, $INCSUFFIX, $OBJSUFFIX, $SHCXX, $SHCXXCOM, $SHCXXFLAGS, $SHOBJSUFFIX.
استفاده میکند از: $CXXCOMSTR, $SHCXXCOMSTR.
cyglink
تنظیم میکند: $IMPLIBPREFIX, $IMPLIBSUFFIX, $LDMODULEVERSIONFLAGS, $LINKFLAGS, $RPATHPREFIX, $RPATHSUFFIX, $SHLIBPREFIX, $SHLIBSUFFIX, $SHLIBVERSIONFLAGS, $SHLINKCOM, $SHLINKFLAGS, $_LDMODULEVERSIONFLAGS, $_SHLIBVERSIONFLAGS.
default
فهرست ابزارهای انتخابشده به صورت پیشفرض ایستا نیست، بلکه هم به پلتفرم و هم به نرمافزارهای نصبشده روی آن پلتفرم وابسته است. برخی از ابزارها در صورتی که دستور زیربنایی مربوطهشان یافت نشود مقداردهی اولیه نمیشوند، و برخی ابزارها از یک فهرست گزینهها بر مبنای «نخستین موردِ یافتشده» انتخاب میشوند. فهرست نهایی ابزارها را میتوان با بررسی متغیر ساخت $TOOLS در محیط ساخت مشاهده کرد.
در تمامی پلتفرمها، ابزارهای فهرست زیر در صورت برآورده شدن شرایط مربوطهشان انتخاب میشوند: filesystem;, wix, lex, yacc, rpcgen, swig, jar, javac, javah, rmic, dvipdf, dvips, gs, tex, latex, pdflatex, pdftex, tar, zip, textfile.
در سیستمهای لینوکس، فهرست ابزارهای پیشفرض این موارد را (بر اساس نخستین مورد یافتشده) انتخاب میکند: یک کامپایلر C از میان gcc, intelc, icc, cc; یک کامپایلر C++ از میان g++, intelc, icc, cXX; یک اسمبلر از میان gas, nasm, masm; یک پیونددهنده از میان gnulink, ilink; یک کامپایلر Fortran از میان gfortran, g77, ifort, ifl, f95, f90, f77; و یک آرشیوکننده ایستا ar. همچنین تمام موارد یافتشده از فهرست زیر را انتخاب میکند: m4 rpm.
در سیستمهای ویندوز، فهرست ابزارهای پیشفرض این موارد را (بر اساس نخستین مورد یافتشده) انتخاب میکند: یک کامپایلر C از میان msvc, mingw, gcc, intelc, icl, icc, cc, bcc32; یک کامپایلر C++ از میان msvc, intelc, icc, g++, cXX, bcc32; یک اسمبلر از میان masm, nasm, gas, 386asm; یک پیونددهنده از میان mslink, gnulink, ilink, linkloc, ilink32; یک کامپایلر Fortran از میان gfortran, g77, ifl, cvf, f95, f90, fortran; و یک آرشیوکننده ایستا از میان mslib, ar, tlib; همچنین تمام موارد یافتشده از فهرست زیر را انتخاب میکند: msvs, midl.
در سیستمهای مکاواس (MacOS)، فهرست ابزارهای پیشفرض این موارد را (بر اساس نخستین مورد یافتشده) انتخاب میکند: یک کامپایلر C از میان gcc, cc; یک کامپایلر C++ از میان g++, cXX; یک اسمبلر as; یک پیونددهنده از میان applelink, gnulink; یک کامپایلر Fortran از میان gfortran, f95, f90, g77; و یک آرشیوکننده ایستا ar. همچنین تمام موارد یافتشده از فهرست زیر را انتخاب میکند: m4, rpm.
در سیستمهای BSD که کامپایلر پایه آنها LLVM/clang است (FreeBSD و OpenBSD)، فهرست ابزارهای پیشفرض با لینوکس یکسان است، با این تفاوت که کامپایلر C (بر اساس نخستین مورد یافتشده) از میان clang, gcc, intelc, icc, cc و کامپایلر C++ از میان clangxx, g++, intelc, icc, cXX انتخاب میشود.
فهرستهای پیشفرض برای سایر پلتفرمها را میتوان با بررسی کد منبع scons یافت (ببینید: SCons/Tool/__init__.py).
dmd
مقادیر زیر را تنظیم میکند: $DC, $DCOM, $DDEBUG, $DDEBUGPREFIX, $DDEBUGSUFFIX, $DFILESUFFIX, $DFLAGPREFIX, $DFLAGS, $DFLAGSUFFIX, $DINCPREFIX, $DINCSUFFIX, $DLIB, $DLIBCOM, $DLIBDIRPREFIX, $DLIBDIRSUFFIX, $DLIBFLAGPREFIX, $DLIBFLAGSUFFIX, $DLIBLINKPREFIX, $DLIBLINKSUFFIX, $DLINK, $DLINKCOM, $DLINKFLAGPREFIX, $DLINKFLAGS, $DLINKFLAGSUFFIX, $DPATH, $DRPATHPREFIX, $DRPATHSUFFIX, $DVERPREFIX, $DVERSIONS, $DVERSUFFIX, $SHDC, $SHDCOM, $SHDLIBVERSIONFLAGS, $SHDLINK, $SHDLINKCOM, $SHDLINKFLAGS.
docbook
وابستگیهای ضمنی به تصاویر و XIncludeها در صورت برآورده کردن پیشنیازهای HTML بهطور خودکار شناسایی میشوند. بدین منظور از شیوهنامهٔ کمکی utils/xmldepend.xsl اثر Paul DuBois استفاده میشود.
توجه داشته باشید که هیچ پشتیبانیای برای تفکیک کاتالوگ XML ارائه نمیشود! این ابزار پردازندههای XSLT و رندرکنندههای PDF را با شیوهنامههای مشخصشده توسط شما فراخوانی میکند، همین و بس. باقی کارها بر عهدهٔ شماست و هنگام تفکیک نامها از طریق یک کاتالوگ، همچنان باید بدانید چه کاری انجام میدهید.
برای فعالسازی ابزار "docbook"، باید نام آن را به سازندهٔ Environment اضافه کنید، مانند این:
env = Environment(tools=['docbook'])
ابزار docbook هنگام راهاندازی، تلاش میکند پردازندهٔ مورد نیاز xsltproc و یک رندرکنندهٔ PDF، مانند fop را پیدا کند. بنابراین مطمئن شوید که این موارد به متغیر محیطی PATH سیستم شما اضافه شدهاند و میتوان آنها را بدون تعیین مسیر کامل، مستقیماً فراخوانی کرد.
برای پایهایترین پردازش Docbook به HTML، باید این موارد را نصب داشته باشید:
رندر گرفتن به PDF مستلزم نصب یکی از برنامههای fop یا xep است.
ایجاد یک سند HTML یا PDF بسیار ساده و سرراست است. عبارت:
env = Environment(tools=['docbook'])
env.DocbookHtml('manual.html', 'manual.xml')
env.DocbookPdf('manual.pdf', 'manual.xml')
را بنویسید تا هر دو خروجی را از منبع XML خود یعنی manual.xml به دست آورید. به عنوان یک میانبر، میتوانید تنها ریشهٔ نام فایلها را تعیین کنید، مانند این:
env = Environment(tools=['docbook'])
env.DocbookHtml('manual')
env.DocbookPdf('manual')
و همان نتیجه را دریافت کنید. فهرستهای هدف و منبع نیز پشتیبانی میشوند:
env = Environment(tools=['docbook']) env.DocbookHtml(['manual.html','reference.html'], ['manual.xml','reference.xml'])
یا حتی:
env = Environment(tools=['docbook']) env.DocbookHtml(['manual','reference'])
مهم
هر زمان که فهرست منابع را حذف کنید، نباید پسوند فایل را مشخص نمایید! این ابزار از نامهای دادهشده به عنوان ریشهٔ نام فایل استفاده میکند و پسوندهای مربوط به فایلهای هدف و منبع را بر همین اساس اضافه مینماید.
سازندههای DocbookHtmlChunked، DocbookHtmlhelp و DocbookSlidesHtml خاص هستند، از این جهت که:
در نتیجه، مشخص کردن نام هدف HTML عملاً کاربردی ندارد. بنابراین نحو پایه برای این سازندهها همواره بدین صورت است:
env = Environment(tools=['docbook'])
env.DocbookHtmlhelp('manual')
اگر میخواهید از یک فایل XSL خاص استفاده کنید، میتوانید پارامتر اضافی xsl را در فراخوانی سازندهٔ خود بهصورت زیر تعیین کنید:
env.DocbookHtml('other.html', 'manual.xml', xsl='html.xsl')
از آنجا که در صورت استفادهٔ مداوم از یک نامگذاری محلی یکسان برای فایلهای XSL سفارشیتان، مثلاً html.xsl برای HTML و pdf.xsl برای خروجی PDF، این کار ممکن است خستهکننده شود، مجموعهای از متغیرها برای تنظیم نام پیشفرض XSL در نظر گرفته شده است. این متغیرها عبارتند از:
DOCBOOK_DEFAULT_XSL_HTML DOCBOOK_DEFAULT_XSL_HTMLCHUNKED DOCBOOK_DEFAULT_XSL_HTMLHELP DOCBOOK_DEFAULT_XSL_PDF DOCBOOK_DEFAULT_XSL_EPUB DOCBOOK_DEFAULT_XSL_MAN DOCBOOK_DEFAULT_XSL_SLIDESPDF DOCBOOK_DEFAULT_XSL_SLIDESHTML
و میتوانید هنگام ساخت محیط خود، آنها را تنظیم کنید:
env = Environment(
tools=['docbook'],
DOCBOOK_DEFAULT_XSL_HTML='html.xsl',
DOCBOOK_DEFAULT_XSL_PDF='pdf.xsl',
)
env.DocbookHtml('manual') # now uses html.xsl
تنظیم میکند: $DOCBOOK_DEFAULT_XSL_EPUB، $DOCBOOK_DEFAULT_XSL_HTML، $DOCBOOK_DEFAULT_XSL_HTMLCHUNKED، $DOCBOOK_DEFAULT_XSL_HTMLHELP، $DOCBOOK_DEFAULT_XSL_MAN، $DOCBOOK_DEFAULT_XSL_PDF، $DOCBOOK_DEFAULT_XSL_SLIDESHTML، $DOCBOOK_DEFAULT_XSL_SLIDESPDF، $DOCBOOK_FOP، $DOCBOOK_FOPCOM، $DOCBOOK_FOPFLAGS، $DOCBOOK_XMLLINT، $DOCBOOK_XMLLINTCOM، $DOCBOOK_XMLLINTFLAGS، $DOCBOOK_XSLTPROC، $DOCBOOK_XSLTPROCCOM، $DOCBOOK_XSLTPROCFLAGS، $DOCBOOK_XSLTPROCPARAMS.
استفاده میکند: $DOCBOOK_FOPCOMSTR، $DOCBOOK_XMLLINTCOMSTR، $DOCBOOK_XSLTPROCCOMSTR.
dvi
dvipdf
تنظیم میکند: $DVIPDF، $DVIPDFCOM، $DVIPDFFLAGS.
استفاده میکند: $DVIPDFCOMSTR.
dvips
تنظیم میکند: $DVIPS، $DVIPSFLAGS، $PSCOM، $PSPREFIX، $PSSUFFIX.
استفاده میکند: $PSCOMSTR.
f03
تنظیم میکند: $F03، $F03COM، $F03FLAGS، $F03PPCOM، $SHF03، $SHF03COM، $SHF03FLAGS، $SHF03PPCOM، $_F03INCFLAGS.
استفاده میکند: $F03COMSTR، $F03PPCOMSTR، $FORTRANCOMMONFLAGS، $SHF03COMSTR، $SHF03PPCOMSTR.
f08
تنظیم میکند: $F08, $F08COM, $F08FLAGS, $F08PPCOM, $SHF08, $SHF08COM, $SHF08FLAGS, $SHF08PPCOM, $_F08INCFLAGS.
استفاده میکند: $F08COMSTR, $F08PPCOMSTR, $FORTRANCOMMONFLAGS, $SHF08COMSTR, $SHF08PPCOMSTR.
f77
تنظیم میکند: $F77, $F77COM, $F77FILESUFFIXES, $F77FLAGS, $F77PPCOM, $F77PPFILESUFFIXES, $FORTRAN, $FORTRANCOM, $FORTRANFLAGS, $SHF77, $SHF77COM, $SHF77FLAGS, $SHF77PPCOM, $SHFORTRAN, $SHFORTRANCOM, $SHFORTRANFLAGS, $SHFORTRANPPCOM, $_F77INCFLAGS.
استفاده میکند: $F77COMSTR, $F77PPCOMSTR, $FORTRANCOMMONFLAGS, $FORTRANCOMSTR, $FORTRANFLAGS, $FORTRANPPCOMSTR, $SHF77COMSTR, $SHF77PPCOMSTR, $SHFORTRANCOMSTR, $SHFORTRANFLAGS, $SHFORTRANPPCOMSTR.
f90
تنظیم میکند: $F90, $F90COM, $F90FLAGS, $F90PPCOM, $SHF90, $SHF90COM, $SHF90FLAGS, $SHF90PPCOM, $_F90INCFLAGS.
استفاده میکند: $F90COMSTR, $F90PPCOMSTR, $FORTRANCOMMONFLAGS, $SHF90COMSTR, $SHF90PPCOMSTR.
f95
تنظیم میکند: $F95, $F95COM, $F95FLAGS, $F95PPCOM, $SHF95, $SHF95COM, $SHF95FLAGS, $SHF95PPCOM, $_F95INCFLAGS.
استفاده میکند: $F95COMSTR, $F95PPCOMSTR, $FORTRANCOMMONFLAGS, $SHF95COMSTR, $SHF95PPCOMSTR.
fortran
تنظیم میکند: $FORTRAN, $FORTRANCOM, $FORTRANFLAGS, $SHFORTRAN, $SHFORTRANCOM, $SHFORTRANFLAGS, $SHFORTRANPPCOM.
استفاده میکند: $CPPFLAGS, $FORTRANCOMSTR, $FORTRANPPCOMSTR, $SHFORTRANCOMSTR, $SHFORTRANPPCOMSTR, $_CPPDEFFLAGS.
g++
تنظیم میکند: $CXX, $CXXVERSION, $SHCXXFLAGS, $SHOBJSUFFIX.
g77
تنظیم میکند: $F77, $F77COM, $F77FILESUFFIXES, $F77PPCOM, $F77PPFILESUFFIXES, $FORTRAN, $FORTRANCOM, $FORTRANPPCOM, $SHF77, $SHF77COM, $SHF77FLAGS, $SHF77PPCOM, $SHFORTRAN, $SHFORTRANCOM, $SHFORTRANFLAGS, $SHFORTRANPPCOM.
استفاده میکند: $F77FLAGS, $FORTRANCOMMONFLAGS, $FORTRANFLAGS.
gas
تنظیم میکند: $AS.
gcc
تنظیم میکند: $CC, $CCDEPFLAGS, $CCVERSION, $SHCCFLAGS.
gdc
تنظیم میکند: $DC, $DCOM, $DDEBUG, $DDEBUGPREFIX, $DDEBUGSUFFIX, $DFILESUFFIX, $DFLAGPREFIX, $DFLAGS, $DFLAGSUFFIX, $DINCPREFIX, $DINCSUFFIX, $DLIB, $DLIBCOM, $DLIBDIRPREFIX, $DLIBDIRSUFFIX, $DLIBFLAGPREFIX, $DLIBFLAGSUFFIX, $DLIBLINKPREFIX, $DLIBLINKSUFFIX, $DLINK, $DLINKCOM, $DLINKFLAGPREFIX, $DLINKFLAGS, $DLINKFLAGSUFFIX, $DPATH, $DRPATHPREFIX, $DRPATHSUFFIX, $DVERPREFIX, $DVERSIONS, $DVERSUFFIX, $SHDC, $SHDCOM, $SHDLIBVERSIONFLAGS, $SHDLINK, $SHDLINKCOM, $SHDLINKFLAGS.
gettext
هنگامی که gettext را فعال میکنید، به صورت داخلی تمام ابزارهای یادشده را بارگذاری میکند، بنابراین توصیه میشود مستندات اختصاصی هر یک را ببینید.
هر یک از ابزارهای فوق سازنده(های) اختصاصی خود را ارائه میدهند که میتوان از آنها برای انجام فعالیتهای ویژه مربوط به بینالمللیسازی نرمافزار استفاده کرد. با این حال ممکن است به سازنده سطحبالای Translate علاقهمند باشید.
برای استفاده از ابزارهای gettext، ابزار 'gettext' را به محیط ساخت خود اضافه کنید:
env = Environment(tools=['default', 'gettext'])
gfortran
تنظیم میکند: $F77, $F90, $F95, $FORTRAN, $SHF77, $SHF77FLAGS, $SHF90, $SHF90FLAGS, $SHF95, $SHF95FLAGS, $SHFORTRAN, $SHFORTRANFLAGS.
gnulink
تنظیم میکند: $LDMODULEVERSIONFLAGS, $RPATHPREFIX, $RPATHSUFFIX, $SHLIBVERSIONFLAGS, $SHLINKFLAGS, $_LDMODULESONAME, $_SHLIBSONAME.
gs
تنظیم میکند: $GS, $GSCOM, $GSFLAGS.
استفاده میکند: $GSCOMSTR.
hpc++
hpcc
تنظیم میکند: $CXX, $CXXVERSION, $SHCXXFLAGS.
hplink
تنظیم میکند: $LINKFLAGS, $SHLIBSUFFIX, $SHLINKFLAGS.
icc
تنظیم میکند: $CC, $CCCOM, $CFILESUFFIX, $CPPDEFPREFIX, $CPPDEFSUFFIX, $CXXCOM, $CXXFILESUFFIX, $INCPREFIX, $INCSUFFIX.
استفاده میکند: $CCFLAGS, $CFLAGS, $CPPFLAGS, $_CPPDEFFLAGS, $_CPPINCFLAGS.
icl
ifl
تنظیم میکند: $FORTRAN, $FORTRANCOM, $FORTRANPPCOM, $SHFORTRANCOM, $SHFORTRANPPCOM.
استفاده میکند: $CPPFLAGS, $FORTRANFLAGS, $_CPPDEFFLAGS, $_FORTRANINCFLAGS.
ifort
تنظیم میکند: $F77, $F90, $F95, $FORTRAN, $SHF77, $SHF77FLAGS, $SHF90, $SHF90FLAGS, $SHF95, $SHF95FLAGS, $SHFORTRAN, $SHFORTRANFLAGS.
ilink
تنظیم میکند: $LIBDIRPREFIX, $LIBDIRSUFFIX, $LIBLINKPREFIX, $LIBLINKSUFFIX, $LINK, $LINKCOM, $LINKFLAGS.
ilink32
تنظیم میکند: $LIBDIRPREFIX, $LIBDIRSUFFIX, $LIBLINKPREFIX, $LIBLINKSUFFIX, $LINK, $LINKCOM, $LINKFLAGS.
install
تنظیم میکند: $INSTALL, $INSTALLSTR.
intelc
تنظیم میکند: $AR, $CC, $CXX, $INTEL_C_COMPILER_VERSION, $LINK.
jar
تنظیم میکند: $JAR, $JARCOM, $JARFLAGS, $JARSUFFIX.
استفاده میکند: $JARCOMSTR.
javac
تنظیم میکند: $JAVABOOTCLASSPATH, $JAVAC, $JAVACCOM, $JAVACFLAGS, $JAVACLASSPATH, $JAVACLASSSUFFIX, $JAVAINCLUDES, $JAVASOURCEPATH, $JAVASUFFIX.
استفاده میکند: $JAVACCOMSTR.
javah
تنظیم میکند: $JAVACLASSSUFFIX, $JAVAH, $JAVAHCOM, $JAVAHFLAGS.
استفاده میکند: $JAVACLASSPATH, $JAVAHCOMSTR.
latex
تنظیم میکند: $LATEX, $LATEXCOM, $LATEXFLAGS.
استفاده میکند: $LATEXCOMSTR.
ldc
تنظیم میکند: $DC, $DCOM, $DDEBUG, $DDEBUGPREFIX, $DDEBUGSUFFIX, $DFILESUFFIX, $DFLAGPREFIX, $DFLAGS, $DFLAGSUFFIX, $DINCPREFIX, $DINCSUFFIX, $DLIB, $DLIBCOM, $DLIBDIRPREFIX, $DLIBDIRSUFFIX, $DLIBFLAGPREFIX, $DLIBFLAGSUFFIX, $DLIBLINKPREFIX, $DLIBLINKSUFFIX, $DLINK, $DLINKCOM, $DLINKFLAGPREFIX, $DLINKFLAGS, $DLINKFLAGSUFFIX, $DPATH, $DRPATHPREFIX, $DRPATHSUFFIX, $DVERPREFIX, $DVERSIONS, $DVERSUFFIX, $SHDC, $SHDCOM, $SHDLIBVERSIONFLAGS, $SHDLINK, $SHDLINKCOM, $SHDLINKFLAGS.
lex
تنظیم میکند: $LEX, $LEXCOM, $LEXFLAGS, $LEXUNISTD.
استفاده میکند: $LEXCOMSTR, $LEXFLAGS, $LEX_HEADER_FILE, $LEX_TABLES_FILE.
link
تنظیم میکند: $LDMODULE, $LDMODULECOM, $LDMODULEFLAGS, $LDMODULENOVERSIONSYMLINKS, $LDMODULEPREFIX, $LDMODULESUFFIX, $LDMODULEVERSION, $LDMODULEVERSIONFLAGS, $LIBDIRPREFIX, $LIBDIRSUFFIX, $LIBLINKPREFIX, $LIBLINKSUFFIX, $LINK, $LINKCOM, $LINKFLAGS, $SHLIBSUFFIX, $SHLINK, $SHLINKCOM, $SHLINKFLAGS, $__LDMODULEVERSIONFLAGS, $__SHLIBVERSIONFLAGS.
استفاده میکند: $LDMODULECOMSTR, $LINKCOMSTR, $SHLINKCOMSTR.
linkloc
تنظیم میکند: $LIBDIRPREFIX, $LIBDIRSUFFIX, $LIBLINKPREFIX, $LIBLINKSUFFIX, $LINK, $LINKCOM, $LINKFLAGS, $SHLINK, $SHLINKCOM, $SHLINKFLAGS.
استفاده میکند: $LINKCOMSTR, $SHLINKCOMSTR.
m4
تنظیم میکند: $M4, $M4COM, $M4FLAGS.
استفاده میکند: $M4COMSTR.
masm
تنظیم میکند: $AS, $ASCOM, $ASFLAGS, $ASPPCOM, $ASPPFLAGS.
استفاده میکند: $ASCOMSTR, $ASPPCOMSTR, $CPPFLAGS, $_CPPDEFFLAGS, $_CPPINCFLAGS.
midl
تنظیم میکند: $MIDL, $MIDLCOM, $MIDLFLAGS.
استفاده میکند: $MIDLCOMSTR.
mingw
تنظیم میکند: $AS, $CC, $CXX, $LDMODULECOM, $LIBPREFIX, $LIBSUFFIX, $OBJSUFFIX, $RC, $RCCOM, $RCFLAGS, $RCINCFLAGS, $RCINCPREFIX, $RCINCSUFFIX, $SHCCFLAGS, $SHCXXFLAGS, $SHLINKCOM, $SHLINKFLAGS, $SHOBJSUFFIX, $WINDOWSDEFPREFIX, $WINDOWSDEFSUFFIX.
استفاده میکند: $RCCOMSTR, $SHLINKCOMSTR.
msgfmt
تنظیم میکند: $MOSUFFIX, $MSGFMT, $MSGFMTCOM, $MSGFMTCOMSTR, $MSGFMTFLAGS, $POSUFFIX.
استفاده میکند: $LINGUAS_FILE.
msginit
تنظیم میکند: $MSGINIT, $MSGINITCOM, $MSGINITCOMSTR, $MSGINITFLAGS, $POAUTOINIT, $POCREATE_ALIAS, $POSUFFIX, $POTSUFFIX, $_MSGINITLOCALE.
استفاده میکند: $LINGUAS_FILE, $POAUTOINIT, $POTDOMAIN.
msgmerge
تنظیم میکند: $MSGMERGE, $MSGMERGECOM, $MSGMERGECOMSTR, $MSGMERGEFLAGS, $POSUFFIX, $POTSUFFIX, $POUPDATE_ALIAS.
استفاده میکند: $LINGUAS_FILE, $POAUTOINIT, $POTDOMAIN.
mslib
تنظیم میکند: $AR, $ARCOM, $ARFLAGS, $LIBPREFIX, $LIBSUFFIX.
استفاده میکند: $ARCOMSTR.
mslink
تنظیم میکند: $LDMODULE, $LDMODULECOM, $LDMODULEFLAGS, $LDMODULEPREFIX, $LDMODULESUFFIX, $LIBDIRPREFIX, $LIBDIRSUFFIX, $LIBLINKPREFIX, $LIBLINKSUFFIX, $LINK, $LINKCOM, $LINKFLAGS, $REGSVR, $REGSVRCOM, $REGSVRFLAGS, $SHLINK, $SHLINKCOM, $SHLINKFLAGS, $WINDOWSDEFPREFIX, $WINDOWSDEFSUFFIX, $WINDOWSEXPPREFIX, $WINDOWSEXPSUFFIX, $WINDOWSPROGMANIFESTPREFIX, $WINDOWSPROGMANIFESTSUFFIX, $WINDOWSSHLIBMANIFESTPREFIX, $WINDOWSSHLIBMANIFESTSUFFIX, $WINDOWS_INSERT_DEF.
استفاده میکند: $LDMODULECOMSTR, $LINKCOMSTR, $REGSVRCOMSTR, $SHLINKCOMSTR.
mssdk
استفاده میکند: $MSSDK_DIR, $MSSDK_VERSION, $MSVS_VERSION.
msvc
تنظیم میکند: $BUILDERS, $CC, $CCCOM, $CCDEPFLAGS, $CCFLAGS, $CCPCHFLAGS, $CCPDBFLAGS, $CFILESUFFIX, $CFLAGS, $CPPDEFPREFIX, $CPPDEFSUFFIX, $CXX, $CXXCOM, $CXXFILESUFFIX, $CXXFLAGS, $INCPREFIX, $INCSUFFIX, $OBJPREFIX, $OBJSUFFIX, $PCHCOM, $PCHPDBFLAGS, $RC, $RCCOM, $RCFLAGS, $SHCC, $SHCCCOM, $SHCCFLAGS, $SHCFLAGS, $SHCXX, $SHCXXCOM, $SHCXXFLAGS, $SHOBJPREFIX, $SHOBJSUFFIX.
استفاده میکند از: $CCCOMSTR, $CXXCOMSTR, $MSVC_NOTFOUND_POLICY, $MSVC_SCRIPTERROR_POLICY, $MSVC_SCRIPT_ARGS, $MSVC_SDK_VERSION, $MSVC_SPECTRE_LIBS, $MSVC_TOOLSET_VERSION, $MSVC_USE_SCRIPT, $MSVC_USE_SCRIPT_ARGS, $MSVC_USE_SETTINGS, $MSVC_VERSION, $PCH, $PCHSTOP, $PDB, $SHCCCOMSTR, $SHCXXCOMSTR.
msvs
تنظیم میکند: $MSVSBUILDCOM, $MSVSCLEANCOM, $MSVSENCODING, $MSVSPROJECTCOM, $MSVSREBUILDCOM, $MSVSSCONS, $MSVSSCONSCOM, $MSVSSCONSCRIPT, $MSVSSCONSFLAGS, $MSVSSOLUTIONCOM.
mwcc
تنظیم میکند: $CC, $CCCOM, $CFILESUFFIX, $CPPDEFPREFIX, $CPPDEFSUFFIX, $CXX, $CXXCOM, $CXXFILESUFFIX, $INCPREFIX, $INCSUFFIX, $MWCW_VERSION, $MWCW_VERSIONS, $SHCC, $SHCCCOM, $SHCCFLAGS, $SHCFLAGS, $SHCXX, $SHCXXCOM, $SHCXXFLAGS.
استفاده میکند از: $CCCOMSTR, $CXXCOMSTR, $SHCCCOMSTR, $SHCXXCOMSTR.
mwld
تنظیم میکند: $AR, $ARCOM, $LIBDIRPREFIX, $LIBDIRSUFFIX, $LIBLINKPREFIX, $LIBLINKSUFFIX, $LINK, $LINKCOM, $SHLINK, $SHLINKCOM, $SHLINKFLAGS.
nasm
تنظیم میکند: $AS, $ASCOM, $ASFLAGS, $ASPPCOM, $ASPPFLAGS.
استفاده میکند از: $ASCOMSTR, $ASPPCOMSTR.
ninja
نکته
این یک قابلیت آزمایشی است. این عملکرد ممکن است بدون طی چرخه منسوخسازی دستخوش تغییر و/یا حذف شود.
استفاده میکند: $AR, $ARCOM, $ARFLAGS, $CC, $CCCOM, $CCDEPFLAGS, $CCFLAGS, $CXX, $CXXCOM, $ESCAPE, $LINK, $LINKCOM, $PLATFORM, $PRINT_CMD_LINE_FUNC, $PROGSUFFIX, $RANLIB, $RANLIBCOM, $SHCCCOM, $SHCXXCOM, $SHLINK, $SHLINKCOM.
packaging
تنظیم میکند: $PDFPREFIX, $PDFSUFFIX.
pdflatex
تنظیم میکند: $LATEXRETRIES, $PDFLATEX, $PDFLATEXCOM, $PDFLATEXFLAGS.
استفاده میکند: $PDFLATEXCOMSTR.
pdftex
تنظیم میکند: $LATEXRETRIES, $PDFLATEX, $PDFLATEXCOM, $PDFLATEXFLAGS, $PDFTEX, $PDFTEXCOM, $PDFTEXFLAGS.
استفاده میکند: $PDFLATEXCOMSTR, $PDFTEXCOMSTR.
python
در دسترس از scons 4.0 به بعد..
rmic
تنظیم میکند: $JAVACLASSSUFFIX, $RMIC, $RMICCOM, $RMICFLAGS.
استفاده میکند: $RMICCOMSTR.
rpcgen
تنظیم میکند: $RPCGEN, $RPCGENCLIENTFLAGS, $RPCGENFLAGS, $RPCGENHEADERFLAGS, $RPCGENSERVICEFLAGS, $RPCGENXDRFLAGS.
sgiar
تنظیم میکند: $AR, $ARCOMSTR, $ARFLAGS, $LIBPREFIX, $LIBSUFFIX, $SHLINK, $SHLINKFLAGS.
استفاده میکند: $ARCOMSTR, $SHLINKCOMSTR.
sgic++
تنظیم میکند: $CXX, $CXXFLAGS, $SHCXX, $SHOBJSUFFIX.
sgicc
تنظیم میکند: $CXX, $SHOBJSUFFIX.
sgilink
تنظیم میکند: $LINK, $RPATHPREFIX, $RPATHSUFFIX, $SHLINKFLAGS.
sunar
تنظیم میکند: $AR, $ARCOM, $ARFLAGS, $LIBPREFIX, $LIBSUFFIX.
استفاده میکند: $ARCOMSTR.
sunc++
تنظیم میکند: $CXX, $CXXVERSION, $SHCXX, $SHCXXFLAGS, $SHOBJPREFIX, $SHOBJSUFFIX.
suncc
تنظیم میکند: $CXX, $SHCCFLAGS, $SHOBJPREFIX, $SHOBJSUFFIX.
sunf77
تنظیم میکند: $F77, $FORTRAN, $SHF77, $SHF77FLAGS, $SHFORTRAN, $SHFORTRANFLAGS.
sunf90
تنظیم میکند: $F90, $FORTRAN, $SHF90, $SHF90FLAGS, $SHFORTRAN, $SHFORTRANFLAGS.
sunf95
تنظیم میکند: $F95, $FORTRAN, $SHF95, $SHF95FLAGS, $SHFORTRAN, $SHFORTRANFLAGS.
sunlink
تنظیم میکند: $RPATHPREFIX, $RPATHSUFFIX, $SHLINKFLAGS.
swig
تنظیم میکند: $SWIG, $SWIGCFILESUFFIX, $SWIGCOM, $SWIGCXXFILESUFFIX, $SWIGDIRECTORSUFFIX, $SWIGFLAGS, $SWIGINCPREFIX, $SWIGINCSUFFIX, $SWIGPATH, $SWIGVERSION, $_SWIGINCFLAGS.
استفاده میکند: $SWIGCOMSTR.
tar
تنظیم میکند: $TAR, $TARCOM, $TARFLAGS, $TARSUFFIX.
استفاده میکند: $TARCOMSTR.
tex
تنظیم میکند: $BIBTEX, $BIBTEXCOM, $BIBTEXFLAGS, $LATEX, $LATEXCOM, $LATEXFLAGS, $MAKEINDEX, $MAKEINDEXCOM, $MAKEINDEXFLAGS, $TEX, $TEXCOM, $TEXFLAGS.
استفاده میکند: $BIBTEXCOMSTR, $LATEXCOMSTR, $MAKEINDEXCOMSTR, $TEXCOMSTR.
textfile
تنظیم میکند: $FILE_ENCODING, $LINESEPARATOR, $SUBSTFILEPREFIX, $SUBSTFILESUFFIX, $TEXTFILEPREFIX, $TEXTFILESUFFIX.
استفاده میکند: $SUBST_DICT.
tlib
تنظیم میکند: $AR, $ARCOM, $ARFLAGS, $LIBPREFIX, $LIBSUFFIX.
استفاده میکند: $ARCOMSTR.
xgettext
تنظیم میکند: $POTSUFFIX, $POTUPDATE_ALIAS, $XGETTEXTCOM, $XGETTEXTCOMSTR, $XGETTEXTFLAGS, $XGETTEXTFROM, $XGETTEXTFROMPREFIX, $XGETTEXTFROMSUFFIX, $XGETTEXTPATH, $XGETTEXTPATHPREFIX, $XGETTEXTPATHSUFFIX, $_XGETTEXTDOMAIN, $_XGETTEXTFROMFLAGS, $_XGETTEXTPATHFLAGS.
استفاده میکند: $POTDOMAIN.
yacc
تنظیم میکند: $YACC, $YACCCOM, $YACCFLAGS, $YACCHFILESUFFIX, $YACCHXXFILESUFFIX, $YACCVCGFILESUFFIX, $YACC_GRAPH_FILE_SUFFIX.
استفاده میکند: $YACCCOMSTR, $YACCFLAGS, $YACC_GRAPH_FILE, $YACC_HEADER_FILE.
zip
تنظیم میکند: $ZIP, $ZIPCOM, $ZIPCOMPRESSION, $ZIPFLAGS, $ZIPSUFFIX.
استفاده میکند: $ZIPCOMSTR.
متدهای سازنده (Builder Methods)
متدهای سازنده (Builder methods) توابع ویژهای هستند که برای اعلان روابط در گراف وابستگی ساخت استفاده میشوند. فراخوانی یک Builder مستقیماً چیزی را نمیسازد، بلکه هدف یا اهداف (آنچه میخواهید ساخته شود)، منابع (آنچه هدف از آن ساخته میشود) و محیط ساخت (construction environment) مورد استفاده برای تنظیمات ساخت را ثبت میکند. خود سازنده نیز معمولاً اطلاعاتی در مورد نحوه تولید اهداف دارد که مورد استفاده قرار میگیرد، به جز Command که در آن فراخواننده مسئول تعیین عمل (action) است. مجری کارهای SCons بعداً با استفاده از این اطلاعات تصمیم میگیرد که آیا و چه زمانی ساخت را آغاز کند.
تمام متدهای واقعی Builder از قواعد نحوی یکسانی برای فراخوانی تابع استفاده میکنند. به منظور اختصار، این امضای مشترک در فهرست Builders گنجانده نشده است. شبهسازندهها (Pseudo-Builders) انعطافپذیری بیشتری در نحوه فراخوانی دارند و لزوماً از این قاعده پیروی نمیکنند، همانطور که در متن مدخلهای مربوط به آنها شرح داده شده است.
Buildername(target, source, [key=val, ...])
آرگومانهای target و source میتوانند به صورت آرگومانهای مکانی یا کلیدواژهای مشخص شوند. برخی آرگومانهای کلیدواژهای اضافی برای همه سازندهها شناخته شده هستند، و هر آرگومان کلیدواژهای ناشناخته به عنوان تخصیص موقت متغیر ساخت (construction variable) در نظر گرفته میشود. شما میتوانید منابع و اهداف را به صورت یک اسکالر یا یک لیست، متشکل از رشتهها یا Nodeها مشخص کنید. برای راحتی، متد Split میتواند برای تقسیم یک رشته جدا شده با فاصلههای سفید (whitespace) به یک لیست استفاده شود.
SCons میتواند مسیرهای منابع و اهداف مشخصشده را در چندین قالب مختلف حل (resolve) کند. آرگومانهای target و source میتوانند اسکالر (رشته یا Node) یا مجموعهای (از رشتهها یا Nodeها) باشند.
«دایرکتوری جاری» برای تفکیک مسیر نسبی دارای گزینههایی است. SCons به طور پیشفرض به دایرکتوری حاوی فایل SConscript (شامل SConstruct) که در حال حاضر مشغول پردازش آن است تغییر مکان میدهد. استفاده از تابع SConscriptChdir این رفتار پیشفرض را فعال یا غیرفعال میکند. آرگومان srcdir در سازنده بر محلی که مسیرهای فایل مبدأ در آن جستجو میشوند تاثیر میگذارد (جزئیات را در ادامه ببینید). تعیین یک یا چند مخزن کد منبع از طریق تابع Repository یا گزینه -Y/--repository به SCons اعلام میکند که پس از دایرکتوری جاری واقعی، مکانهای دیگری را نیز جستجو کند. مفهوم دایرکتوری جاری برای اهداف (و در برخی موارد منابع) تغییر میکند اگر یک دایرکتوری متغیر با استفاده از تابع VariantDir یا پارامتر variant_dir= در تابع SConscript تنظیم شده باشد. این گزینهها روی مسیرهای نسبی به شاخه اصلی تاثیری ندارند.
نکته
در Windows، مسیرهای DOS ممکن است با یک شناسهٔ بخش (volume) یا حرف درایو و به دنبال آن جداکنندهٔ بخش (:) آغاز شوند. ادامهٔ مسیر مطلق یا نسبی است؛ اگر مشخصکنندهٔ بخش وجود داشته باشد، تفکیک برای مسیرهای مطلق از ریشهٔ درایو مشخصشده و برای مسیرهای نسبی از دایرکتوری جاری در درایو مشخصشده آغاز میشود. اگر حرف درایو مشخصشده با درایو جاری متفاوت باشد، مسیر نسبی فاقد زمینه (context) خواهد بود: از آنجا که SCons یک برنامهٔ کنسولی (خط فرمانی) است، ممکن است وضعیت را از ترمینالی که در آن اجرا شده به ارث ببرد، از جمله دایرکتوریهای جاری ذخیرهشده برای سایر درایوها؛ SCons هیچ راهی برای دانستن آنها ندارد. استفاده از حرف درایو در مسیر همچنین مانع از استفاده از شکل وابسته به ریشه (top-relative) میشود.
موارد زیر نمونههای معادل از فراخوانی متد سازندهٔ Program هستند:
env.Program('bar', ['bar.c', 'foo.c'])
env.Program('bar', Split('bar.c foo.c'))
env.Program('bar', env.Split('bar.c foo.c'))
env.Program(source=['bar.c', 'foo.c'], target='bar')
env.Program(target='bar', source=Split('bar.c foo.c'))
env.Program(target='bar', source=env.Split('bar.c foo.c'))
env.Program('bar', source='bar.c foo.c'.split())
نمونههای دیگری از مسیرهای مبدأ و هدف:
نکته
مسیرهای وابسته به ریشه فقط در جاهایی کار میکنند که SCons مسیر را تفسیر کند (به نمونهها رجوع کنید). این رشته برای استفاده در زمینههای دیگر (مانند کد خالص Python که شامل فراخوانی API متعلق به SCons نمیشود)، ابتدا باید به یک مسیر نسبی یا مطلق تبدیل شود؛ یک رشتهٔ مناسب را میتوان از Node ایجادشده از یک مسیر وابسته به ریشه استخراج کرد. علاوه بر این، برخی مسیرها توسط SCons مدیریت میشوند اما مستقیماً در ساخت مشارکت ندارند، بنابراین به دلیل عدم ایجاد Node، برای # ارزیابی نمیشوند. میتوانید صراحتاً یک گرهٔ File یا Dir برای اجبار به ارزیابی ایجاد کنید، مانند هنگام تعیین مسیری برای حافظهٔ نهان فایلهای مشتقشده: CacheDir(Dir('#cache')).
# The comments describing the targets that will be built
# assume these calls are in a SConscript file in the
# a subdirectory named "subdir".
# Builds the program "subdir/foo" from "subdir/foo.c":
env.Program('foo', 'foo.c')
# Builds the program "/tmp/bar" from "subdir/bar.c":
env.Program('/tmp/bar', 'bar.c')
# An initial '#' or '#/' are equivalent; the following
# calls build the programs "foo" and "bar" (in the
# top-level SConstruct directory) from "subdir/foo.c" and
# "subdir/bar.c", respectively:
env.Program('#foo', 'foo.c')
env.Program('#/bar', 'bar.c')
# Builds the program "other/foo" (relative to the top-level
# SConstruct directory) from "subdir/foo.c":
env.Program('#other/foo', 'foo.c')
# os.path.exists() is pure Python, so this fails:
if os.path.exists('#inc/foo.h'):
env.Append(CPPPATH='#inc')
# create a Node to make it work:
if os.path.exists(File('#inc/foo.h')):
env.Append(CPPPATH='#inc')
اگر SCons بتواند نام هدف را از مبدأ (یا مبدأها) استنتاج کند، آرگومان target میتواند حذف شود. اگر سازنده (Builder) از آن پشتیبانی کند، SCons نام پایهٔ نخستین فایل مبدأ را گرفته و از آن به عنوان نام پایهٔ هدف استفاده میکند و پیشوند/پسوند مناسب را میافزاید. برای سازندههایی که به عنوان تکمبدأ (single-source) تعیین شدهاند، یک هدف جداگانه برای هر فایل مبدأ ساخته میشود. اگر چندین مبدأ به یک سازندهٔ تکمبدأ ارسال شوند، آرگومان هدف باید حذف شود، و به هر هدف نامی استنتاجشده از فایل مبدأ متناظر اختصاص داده خواهد شد.
آرگومان کلیدی و اختیاری srcdir مشخص میکند رشتههای فایل مبدأ که مسیرهای مطلق یا وابسته به ریشه نیستند، بهصورت نسبی نسبت به مقدار srcdir تفسیر شوند. نمونهٔ زیر برنامهٔ build/prog (یا build/prog.exe در Windows) را از فایلهای src/f1.c و src/f2.c میسازد، بهجای اینکه آنها را در دایرکتوریِ فایل SConscript در حال ارزیابی جستجو کند.
env.Program('build/prog', ['f1.c', 'f2.c'], srcdir='src')
آرگومان کلیدی و اختیاری parse_flags رفتاری مشابه متد env.MergeFlags ایجاد میکند، که در آن مقدار آرگومان به تنظیمات جداگانه تقسیم شده و در متغیرهای ساخت مربوطه ادغام میشود. نمونهٔ زیر 'include' را به متغیر ساخت $CPPPATH، 'EBUG' را به $CPPDEFINES و 'm' را به $LIBS اضافه میکند:
env.Program('hello', 'hello.c', parse_flags='-Iinclude -DEBUG -lm')
آرگومان کلیدواژهای اختیاری chdir مشخص میکند که کنش(های) سازنده (Builder) باید پس از تغییر دایرکتوری اجرا شوند. اگر آرگومان chdir یک رشتهٔ مسیر یا یک Node دایرکتوری باشد، scons به دایرکتوری مشخصشده تغییر مکان خواهد داد. اگر chdir یک رشته یا Node نبوده و مقدار آن درست (true) ارزیابی شود، آنگاه scons به دایرکتوری فایل هدف تغییر مکان میدهد. پس از اتمام کنش، دایرکتوری اولیه بازیابی میشود.
# scons پیش از اجرای تابع کنش Copy، به زیردایرکتوری "sub/dir"
# تغییر مکان خواهد داد
env.Command(
target='sub/dir/foo.out',
source='sub/dir/foo.in',
action=Copy('${TARGET.file}', '${SOURCE.file}'),
chdir='sub/dir',
)
# در اینجا chdir رشته نیست، بنابراین scons برای اجرای کنش
# به دایرکتوری هدف ("sub/dir") تغییر مکان خواهد داد.
env.Command('
target='sub/dir/foo.out',
source='sub/dir/foo.in',
action=Copy('${TARGET.file}', '${SOURCE.file}'),
chdir=True
)
هشدار
Python تنها یک مکان دایرکتوری جاری را دنبال میکند، حتی اگر چندین ریسهٔ در حال اجرا وجود داشته باشد. این بدان معناست که استفاده از آرگومان chdir با SCons در حالت چندریسهای (گزینهٔ -j) کار نخواهد کرد، زیرا ریسههای کاری (worker threads) مجزایی که توسط SCons ایجاد میشوند، هنگام شروع به تغییر دایرکتوری با یکدیگر تداخل پیدا میکنند.
نکته
SCons هنگام بسط دادن متغیرهای ساخت (construction variables) مانند $TARGET و $SOURCE، chdir را در نظر نمیگیرد، بنابراین آنها نسبت به دایرکتوری chdir نادرست خواهند بود. اگر از آرگومان کلیدواژهای chdir استفاده کنید، معمولاً نیاز خواهید داشت که با استفاده از بسطهایی مانند ${TARGET.file} و ${SOURCE.file} که به بخش نام فایلِ هدف و منبع بسط مییابند، یک خط فرمان متفاوت مشخص کنید.
آرگومانهای کلیدواژهای که بهطور مشخص شناخته نشدهاند، به عنوان جایگزینهای متغیر ساخت (construction variable overrides) در نظر گرفته میشوند که آن متغیرها را بهصورت محدود جایگزین کرده یا اضافه میکنند. این جایگزینیها تنها هنگام ساخت هدفِ فراخوانی سازنده اِعمال خواهند شد و بر سایر بخشهای ساخت تأثیری نخواهند داشت. برای نمونه، اگر میخواهید کتابخانههایی را مشخص کنید که تنها مورد نیاز یک برنامه هستند:
env.Program('hello', 'hello.c', LIBS=['gl', 'glut'])
یا تولید یک کتابخانهٔ اشتراکی با یک پسوند غیراستاندارد:
env.SharedLibrary(
target='word',
source='word.cpp',
SHLIBSUFFIX='.ocx',
LIBSUFFIXES=['.ocx'],
)
توجه داشته باشید که اگر میخواهید scons بهطور خودکار وابستگیها را برای نامهای غیراستاندارد کتابخانه جستجو کند، باید هر دو متغیر ساخت $SHLIBSUFFIX و $LIBSUFFIXES تنظیم شده باشند؛ برای اطلاعات بیشتر، توضیحات این متغیرها را ببینید.
اگرچه متدهای سازندهٔ تعریفشده توسط scons در واقع متدهای یک شیء محیط ساخت (construction environment) هستند، اما بسیاری از آنها را میتوان بدون یک محیط صریح نیز فراخوانی کرد:
Program('hello', 'hello.c')
SharedLibrary('word', 'word.cpp')
اگر به این شیوه فراخوانی شود، سازنده (builder) به صورت داخلی از «محیط پیشفرض» (Default Environment) استفاده خواهد کرد که متشکل از ابزارها و مقادیری است که scons آنها را برای سیستم محلی مناسب تشخیص داده است.
متدهای سازندهای که میتوانند بدون یک محیط صریح فراخوانی شوند (که در فهرست سازندههای زیر بدون پیشوند env. مشخص شدهاند) را میتوان از ماژولهای سفارشی Python که در یک فایل SConscript وارد (import) میکنید، با افزودن خطوط زیر به ماژول Python فراخوانی کرد:
from SCons.Script import *
یک سازنده ممکن است در صورتی که یک Emitter متصل تصمیم به این کار بگیرد، اهدافی اضافه بر اهداف درخواستشده بیافزاید (برای اطلاعات بیشتر بخش موسوم به “Builder Objects” را ببینید؛ $PROGEMITTER یک نمونه است). برای نمونه، پیونددهندهٔ GNU آرگومان خط فرمان -Map=mapfile را میپذیرد که باعث میشود علاوه بر فایل اجرایی در حال پیوند، یک فایل نگاشت پیونددهنده (linker map file) نیز تولید کند. اگر emitter سازندهٔ Program به گونهای پیکربندی شده باشد که در صورت تنظیم این گزینه، این mapfile را اضافه کند، آنگاه در حالی که شما تنها یک هدف مشخص کرده بودید، دو هدف بازگردانده خواهند شد.
به همین دلیل، متدهای سازنده همواره یک NodeList بازمیگردانند؛ شیئی شبیه به لیست که عناصر آن Nodeها هستند. گرهها (Nodes) بازنمایی داخلی اهداف ساخت یا منابع هستند (برای اطلاعات بیشتر بخش موسوم به “Node Objects” را ببینید). شیء NodeList بازگرداندهشده را میتوان بهعنوان منبع (source) به دیگر متدهای سازنده، یا به دیگر توابع یا متدهای SCons که در حالت عادی یک رشتهٔ مسیر میپذیرند، ارسال کرد.
برای نمونه، جهت افزودن یک تعریف پیشپردازندهٔ خاص هنگام کامپایل یک فایل شیء (object file) مشخص، اما نه فایلهای دیگر:
bar_obj_list = env.StaticObject('bar.c', CPPDEFINES='-DBAR')
env.Program("prog", ['foo.c', bar_obj_list, 'main.c'])
استفاده از یک Node مانند این نمونه، با اجتناب از الزام به تعیین پسوند شیء وابسته به پلتفرم هنگام فراخوانی متد سازندهٔ Program، موجب ساخت چندسکوییتر و قابلحملتری میشود.
شیء NodeList همچنین برای ارسال به تابع Default، به همان دلیلِ اجتناب از نامهای وابسته به پلتفرم، بسیار مناسب است:
tgt = env.Program("prog", ["foo.c", "bar.c", "main.c"])
Default(tgt)
گره (Node) نشاندهندهٔ هدف صراحتاً درخواستشده، همواره نخستین عنصر از NodeList بازگرداندهشده است و میتوان آن را از طریق نمایهسازی لیست دریافت کرد (مانند bar_obj_list[0]). نام مسیر فایل یک Node را میتوان با استفاده از سازندهٔ رشتهٔ Python یعنی str به دست آورد (مانند str(bar_obj_list[0])).
فراخوانیهای سازنده بهطور خودکار لیستهای ارائهشده بهعنوان منبع و هدف را «تخت» (flatten) میکنند، بنابراین آنها میتوانند آزادانه حاوی عناصری باشند که خود لیست هستند، مانند bar_obj_list که توسط فراخوانی StaticObject بازگردانده شده است. اگر لازم است لیستی از لیستهای بازگرداندهشده توسط سازندهها را مستقیماً در کد Python دستکاری کنید، میتوانید یا به صورت دستی یک لیست جدید بسازید:
foo = Object('foo.c')
bar = Object('bar.c')
objects = ['begin.o'] + foo + ['middle.o'] + bar + ['end.o']
for obj in objects:
print(str(obj))
یا میتوانید از تابع Flatten ارائهشده توسط SCons برای ایجاد لیستی استفاده کنید که تنها شامل Nodeها باشد، که ممکن است راحتتر باشد:
foo = Object('foo.c')
bar = Object('bar.c')
objects = Flatten(['begin.o', foo, 'middle.o', bar, 'end.o'])
for obj in objects:
print(str(obj))
نکته
از آنجا که فراخوانیهای سازنده یک شیء شبیه لیست بازمیگردانند و نه یک لیست واقعی Python، مناسب نیست که از عملگر جمع Python (+ یا +=) برای الحاق نتایج سازنده به یک لیست Python استفاده شود. زیرا لیست و شیء از انواع متفاوتی هستند، و Python لیست اصلی را درجا بهروزرسانی نخواهد کرد، بلکه در عوض یک شیء جدید از نوع NodeList حاوی پیوند عناصر لیست و نتایج سازنده ایجاد خواهد کرد. این امر برای هر متغیر دیگر Python در پیکربندی SCons شما که همچنان ارجاعی به لیست اصلی دارد، مشکلساز خواهد شد. در عوض، از متد extend لیست در Python استفاده کنید تا اطمینان یابید لیست بهصورت درجا (in-place) بهروزرسانی میشود. مثال:
object_files = []
# Do NOT use += here:
# object_files += Object('bar.c')
#
# It will not update the object_files list in place.
#
# Instead, use the list extend method:
object_files.extend(Object('bar.c'))
bar_obj_list = env.StaticObject('bar.c', CPPDEFINES='-DBAR')
print("The path to bar_obj is:", str(bar_obj_list[0]))
تمام هدفهای متدهای سازنده بهطور خودکار به سورسهایشان وابسته هستند. SCons فایلهای سورس را در زبانهای مختلف برنامهنویسی برای نشانههای شناختهشدهٔ وابستگی (مثلاً دستورات #include برای سورسهایی که به پیشپردازندهٔ C فرستاده میشوند) اسکن میکند، که این امر تا حد زیادی نیاز به مشخص کردن صریح وابستگی را از بین میبرد. همچنین میتوانید با استفاده از متد env.Depends یک محیط ساخت (construction environment)، یک وابستگی صریح مشخص کنید، هرچند که این کار توصیه نمیشود مگر اینکه وابستگی نتواند بهطور قابل اعتمادی توسط اسکنرهای موجود شناسایی شود.
بهطور پیشفرض، SCons میتواند فایلهای سورس C، فایلهای سورس C++، فایلهای سورس Fortran با پسوندهای مشخص (.F (فقط در سیستمهای POSIX)، .fpp، یا .FPP) و فایلهای زبان اسمبلی با پسوندهای مشخص (.S (فقط در سیستمهای POSIX)، .spp، یا .SPP) را برای وابستگیهای پیشپردازندهٔ C اسکن کند. همچنین SCons دارای پشتیبانی پیشفرض برای اسکن فایلهای سورس D، Java، SWIG و LaTeX است.
سازندهها (Builders) برای کارایی بیشتر در زمان اجرا ایجاد شده و به عنوان متد به محیط ساخت اضافه میشوند. SCons الگوهایی را برای بسیاری از Builderها برای انواع ساخت شناختهشده فراهم میکند، و همچنین میتوان Builderهای دیگری نوشت و به پروژه اضافه کرد. این الگوها معمولاً در ماژولهای مشخصات ابزار (Tool specification modules) وجود دارند که هنگام اجرا، پیش از نمونهسازی Builder، میتوانند حضور ابزارهای خارجی مورد نیاز، مانند باینری کامپایلر، و سایر شرایط لازم را بررسی کنند. بنابراین Builderهای موجود در یک محیط ساخت با توجه به نوع پلتفرم، نحوهٔ پیکربندی پلتفرم و ابزارهای انتخابشده برای بارگذاری تفاوت دارند. متدهای سازندهٔ موجود به صورت جفتهای کلید-مقدار در صفت $BUILDERS محیط ساخت ثبت میشوند. اگرچه یک Builder به عنوان متدی از یک محیط ساخت ایجاد میشود، اما میتوان آنها را به عنوان یک تابع سراسری نیز فراخوانی کرد. یک Builder که به این روش فراخوانی شود، به صورت داخلی از محیط پیشفرض (Default Environment) برای جستجوی متغیرهای ساخت استفاده خواهد کرد:
Program('hello', 'hello.c')
SharedLibrary('word', 'word.cpp')
Builderهایی که به سبک تابع سراسری فراخوانی میشوند، بهطور خودکار درون فایلهای SConscript در دسترس (در scope) هستند. آنها درون ماژولهای Python خاص پروژه که آنها را از طریق دستور import در Python از یک فایل SConscript وارد میکنید، در دسترس نیستند و باید آنها را صریحاً به scope سراسری آن ماژول اضافه کنید. میتوانید این کار را با افزودن import زیر به ماژول Python انجام دهید: from SCons.Script import *.
متدهای سازندهٔ زیر در توزیع هستهٔ نرمافزاری SCons دارای الگو هستند.
CFile(), env.CFile()
# builds foo.c env.CFile(target='foo.c', source='foo.l') # builds bar.c env.CFile(target='bar', source='bar.y')
Command(), env.Command()
CompilationDatabase(), env.CompilationDatabase()
CompilationDatabase یک سازندهٔ ویژه است که هدفی را برای ایجاد یک پایگاه دادهٔ کامپایل با قالب JSON و سازگار با ابزارهای clang اضافه میکند (به مشخصات LLVM[1] مراجعه کنید). این پایگاه داده برای استفاده توسط ابزارها و ویرایشگرهای مختلف مناسب است که میتوانند از آن برای بهدست آوردن اطلاعات ساخت و وابستگیها استفاده کنند که در غیر این صورت برای SCons درونی میبود. این سازنده نیازی به مشخص کردن هیچ فایل سورسی ندارد، بلکه ترتیبی میدهد تا اطلاعات مربوط به تمام جفتهای سورس/خروجی C، C++ و اسمبلی شناساییشده در ساخت را که توسط فیلتر اختیاری $COMPILATIONDB_PATH_FILTER مستثنی نشدهاند، خروجی دهد. این هدف مشمول قواعد معمول انتخاب هدف در SCons است.
اگر بدون آرگومان فراخوانی شود، نام هدف سازنده بهطور پیشفرض compile_commands.json خواهد بود.
اگر با یک آرگومان موضعی تکی فراخوانی شود، scons نام هدف را از آن آرگومان سورس «استنتاج» میکند، همان نام را به آن میدهد و سپس سورس را نادیده میگیرد. این روش معمول برای فراخوانی سازنده در حالتی است که نام هدفی غیر از پیشفرض مورد نظر باشد.
اگر با هر یک از آرگومانهای کلیدواژهای target= یا source= فراخوانی شود، مقدار آن آرگومان به عنوان نام هدف در نظر گرفته میشود. اگر با هر دو فراخوانی شود، مقدار target= استفاده شده و source= نادیده گرفته میشود. اگر با چند سورس فراخوانی شود، فهرست سورسها نادیده گرفته خواهد شد، زیرا راهی برای استنتاج قصد مورد نظر وجود ندارد؛ در این حالت از نام هدف پیشفرض استفاده خواهد شد.
نکته
باید ابزار compilation_db را پیش از مشخص کردن هر بخشی از ساخت خود بارگذاری کنید، در غیر این صورت برخی از فایلهای سورس/خروجی در پایگاه دادهٔ کامپایل ظاهر نخواهند شد.
CXXFile(), env.CXXFile()
# builds foo.cc env.CXXFile(target='foo.cc', source='foo.ll') # builds bar.cc env.CXXFile(target='bar', source='bar.yy')
DocbookEpub(), env.DocbookEpub()
env = Environment(tools=['docbook'])
env.DocbookEpub('manual.epub', 'manual.xml')
یا به سادگی
env = Environment(tools=['docbook'])
env.DocbookEpub('manual')
DocbookHtml(), env.DocbookHtml()
env = Environment(tools=['docbook'])
env.DocbookHtml('manual.html', 'manual.xml')
یا به سادگی
env = Environment(tools=['docbook'])
env.DocbookHtml('manual')
DocbookHtmlChunked(), env.DocbookHtmlChunked()
env = Environment(tools=['docbook'])
env.DocbookHtmlChunked('manual')
که در آن manual.xml فایل ورودی است.
اگر از پارامتر root.filename در شیوهنامههای سفارشی خود استفاده میکنید، باید نام هدف جدید را مشخص کنید. این کار تضمین میکند که وابستگیها به درستی تنظیم شوند، بهویژه برای پاکسازی از طریق “scons -c”:
env = Environment(tools=['docbook'])
env.DocbookHtmlChunked('mymanual.html', 'manual', xsl='htmlchunk.xsl')
پشتیبانی اولیهای برای پارامتر base.dir فراهم شده است. میتوانید کلمه کلیدی base_dir را به فراخوانی Builder خود اضافه کنید، و پیشوند دادهشده به ابتدای تمام نامهای فایل ایجاد شده افزوده میشود:
env = Environment(tools=['docbook'])
env.DocbookHtmlChunked('manual', xsl='htmlchunk.xsl', base_dir='output/')
مطمئن شوید که اسلش پایانی را برای پوشه پایه فراموش نکنید، در غیر این صورت فایلهای شما فقط تغییر نام خواهند یافت!
DocbookHtmlhelp(), env.DocbookHtmlhelp()
env = Environment(tools=['docbook'])
env.DocbookHtmlhelp('manual')
که در آن manual.xml فایل ورودی است.
اگر از پارامتر root.filename در شیوهنامههای سفارشی خود استفاده میکنید، باید نام هدف جدید را مشخص کنید. این کار تضمین میکند که وابستگیها به درستی تعیین شوند، بهویژه برای پاکسازی از طریق “scons -c”:
env = Environment(tools=['docbook'])
env.DocbookHtmlhelp('mymanual.html', 'manual', xsl='htmlhelp.xsl')
پشتیبانی اولیهای برای پارامتر base.dir فراهم شده است. میتوانید کلمه کلیدی base_dir را به فراخوانی Builder خود اضافه کنید، و پیشوند دادهشده به ابتدای تمام نامهای فایل ایجاد شده افزوده میشود:
env = Environment(tools=['docbook'])
env.DocbookHtmlhelp('manual', xsl='htmlhelp.xsl', base_dir='output/')
مطمئن شوید که اسلش پایانی را برای پوشه پایه فراموش نکنید، در غیر این صورت فایلهای شما فقط تغییر نام خواهند یافت!
DocbookMan(), env.DocbookMan()
env = Environment(tools=['docbook'])
env.DocbookMan('manual')
که در آن manual.xml فایل ورودی است. توجه داشته باشید که میتوانید یک نام هدف تعیین کنید، اما نامهای خروجی واقعی بهطور خودکار از مدخلهای refname در منبع XML شما تنظیم میشوند.
DocbookPdf(), env.DocbookPdf()
env = Environment(tools=['docbook'])
env.DocbookPdf('manual.pdf', 'manual.xml')
یا صرفاً:
env = Environment(tools=['docbook'])
env.DocbookPdf('manual')
DocbookSlidesHtml(), env.DocbookSlidesHtml()
env = Environment(tools=['docbook'])
env.DocbookSlidesHtml('manual')
اگر از پارامتر titlefoil.html در شیوهنامههای خود استفاده میکنید، باید نام هدف جدید را تعیین کنید. این کار تضمین میکند که وابستگیها بهدرستی برقرار شوند، بهویژه برای پاکسازی از طریق “scons -c”:
env = Environment(tools=['docbook'])
env.DocbookSlidesHtml('mymanual.html','manual', xsl='slideshtml.xsl')
پشتیبانی اولیهای از پارامتر base.dir فراهم شده است. میتوانید کلیدواژهٔ base_dir را به فراخوانی سازندهٔ خود اضافه کنید، و پیشوند دادهشده به ابتدای تمام نامهای فایلهای ایجادشده افزوده میشود:
env = Environment(tools=['docbook'])
env.DocbookSlidesHtml('manual', xsl='slideshtml.xsl', base_dir='output/')
مطمئن شوید که ممیز پایانی (trailing slash) را برای پوشه پایه فراموش نکنید، وگرنه فایلهای شما فقط تغییر نام مییابند!
DocbookSlidesPdf(), env.DocbookSlidesPdf()
env = Environment(tools=['docbook'])
env.DocbookSlidesPdf('manual.pdf', 'manual.xml')
یا صرفاً:
env = Environment(tools=['docbook'])
env.DocbookSlidesPdf('manual')
DocbookXInclude(), env.DocbookXInclude()
env = Environment(tools=['docbook'])
env.DocbookXInclude('manual_xincluded.xml', 'manual.xml')
DocbookXslt(), env.DocbookXslt()
env = Environment(tools=['docbook'])
env.DocbookXslt('manual_transformed.xml', 'manual.xml', xsl='transform.xslt')
توجه داشته باشید که این سازنده نیازمند تنظیم پارامتر xsl است.
DVI(), env.DVI()
پسوند .dvi (که به صورت سختکدشده درون خود TeX قرار دارد) در صورتی که از قبل وجود نداشته باشد، به طور خودکار به هدف افزوده میشود. مثالها:
# builds from aaa.tex env.DVI(target = 'aaa.dvi', source = 'aaa.tex') # builds bbb.dvi env.DVI(target = 'bbb', source = 'bbb.ltx') # builds from ccc.latex env.DVI(target = 'ccc.dvi', source = 'ccc.latex')
Gs(), env.Gs()
env = Environment(tools=['gs'])
env.Gs(
'cover.jpg',
'scons-scons.pdf',
GSFLAGS='-dNOPAUSE -dBATCH -sDEVICE=jpeg -dFirstPage=1 -dLastPage=1 -q',
)
Install(), env.Install()
env.Install(target='/usr/local/bin', source=['foo', 'bar'])
توجه داشته باشید که اگر مسیرهای هدف انتخابشده برای سازندهی Install (و سازندگان مرتبط InstallAs و InstallVersionedLib) خارج از درخت پروژه باشند، مانند مثال بالا، ممکن است به طور پیشفرض برای «ساخت» انتخاب نشوند، زیرا در صورت نبود دستورالعملهای دیگر، scons اهدافی را میسازد که در زیر دایرکتوری سطح بالا (دایرکتوری حاوی فایل SConstruct، معمولاً دایرکتوری جاری) قرار دارند. در این حالت از اهداف خط فرمان یا تابع Default استفاده کنید.
اگر گزینهی --install-sandbox داده شود، مسیر دایرکتوری مشخصشده به عنوان پیشوند به دایرکتوری هدف اضافه خواهد شد. این قابلیت برای آزمایش رفتار نصب بدون نصب در یک مکان «فعال» در سیستم مفید است.
همچنین ببینید FindInstalledFiles. برای توضیحات و نکات بیشتر در مورد نصب، راهنمای کاربر را ببینید (بهویژه بخش اهداف خط فرمان (Command-Line Targets) و فصلهای مربوط به نصب فایلها (Installing Files) و اهداف نام مستعار (Alias Targets)).
InstallAs(), env.InstallAs()
env.InstallAs(target='/usr/local/bin/foo',
source='foo_debug')
env.InstallAs(target=['../lib/libfoo.a', '../lib/libbar.a'],
source=['libFOO.a', 'libBAR.a'])
یادداشت زیر Install را ببینید.
InstallVersionedLib(), env.InstallVersionedLib()
env.InstallVersionedLib(target='/usr/local/bin/foo',
source='libxyz.1.5.2.so')
یادداشت زیر Install را ببینید.
Jar(), env.Jar()
اگر مقدار $JARCHDIR تنظیم شده باشد، دستور jar با استفاده از گزینهٔ -C به پوشهٔ مشخصشده تغییر مسیر میدهد. اگر $JARCHDIR بهطور صریح تنظیم نشده باشد، SCons از بالاترین سطح هر زیردرخت پوشهای که فایلهای .class جاوا در آن توسط سازندهٔ Java ساخته شدهاند استفاده خواهد کرد.
اگر محتویات هر یک از فایلهای منبع با رشتهٔ Manifest-Version آغاز شود، آن فایل یک مانیفست در نظر گرفته میشود و همراه با تنظیم گزینهٔ m به دستور jar ارسال میگردد.
env.Jar(target = 'foo.jar', source = 'classes')
env.Jar(target = 'bar.jar',
source = ['bar1.java', 'bar2.java'])
Java(), env.Java()
ابزار SCons هر فایل منبع .java را برای یافتن کلاسهای تعریفشده درون آن (از جمله کلاسهای درونی) تجزیه میکند و از روی آن، فایلهای هدف .class را که ایجاد خواهند شد تشخیص میدهد. فایلهای کلاس زیر پوشهٔ هدفِ مشخصشده قرار خواهند گرفت.
همچنین SCons هر فایل جاوا را برای یافتن نام بستهبندی (package) جاوا جستجو میکند، با این فرض که این نام در خطی که با رشتهٔ package در ستون اول آغاز میشود یافت میشود؛ فایلهای .class حاصل در پوشهای متناسب با نام بستهٔ مشخصشده قرار داده میشوند. برای نمونه، فایل Foo.java که یک کلاس عمومی یکتای Foo را تعریف میکند و شامل نام بستهٔ sub.dir است، یک فایل کلاس متناظر sub/dir/Foo.class تولید خواهد کرد.
مثالها:
env.Java(target='classes', source='src') env.Java(target='classes', source=['src1', 'src2']) env.Java(target='classes', source=['File1.java', 'File2.java'])
فایلهای منبع جاوا میتوانند از کدگذاری بومی سیستمعامل زیربنایی استفاده کنند. از آنجا که SCons بهطور پیشفرض در حالت سادهٔ ASCII کامپایل میکند، کامپایلر هشدارهایی دربارهٔ نویسههای غیرقابل نگاشت تولید خواهد کرد که ممکن است در ادامهٔ پردازش فایل به خطا بیانجامد. در این حالت، کاربر باید متغیر محیطی LANG را مشخص کند تا به کامپایلر اعلام شود چه کدگذاری استفاده شده است. برای سازگاری و قابلیت حمل، بهتر است کدگذاری بهصورت صریح تعیین (hard-code) شود تا کامپایل هنگام اجرا بر روی سیستمی با کدگذاری دیگر نیز کار کند.
env = Environment() env['ENV']['LANG'] = 'en_GB.UTF-8'
JavaH(), env.JavaH()
اگر متغیر ساخت $JAVACLASSDIR چه در محیط و چه در فراخوانی خودِ متد سازندهٔ JavaH تنظیم شده باشد، آنگاه مقدار این متغیر از ابتدای هر نام فایل .class حذف خواهد شد.
مثالها:
# builds java_native.h
classes = env.Java(target="classdir", source="src")
env.JavaH(target="java_native.h", source=classes)
# builds include/package_foo.h and include/package_bar.h
env.JavaH(target="include", source=["package/foo.class", "package/bar.class"])
# builds export/foo.h and export/bar.h
env.JavaH(
target="export",
source=["classes/foo.class", "classes/bar.class"],
JAVACLASSDIR="classes",
)
نکته
نسخههای جاوا از 10.0 به بعد دیگر از دستور javah برای تولید هدرها/منابع JNI استفاده نمیکنند، و در واقع این دستور را بهطور کامل حذف کردهاند (ببینید پیشنهاد بهبود جاوا JEP 313[2])، که این امر استفاده از این ابزار را برای این منظور دشوارتر میسازد. اگر چندین نسخهٔ جاوا روی سیستم وجود داشته باشد، ممکن است SCons بهطور خودکار یک javah متعلق به نسخهای قدیمیتر را پیدا کند که این امر به نتایج نادرست منجر خواهد شد. برای استفاده با نسخهٔ جدیدتر جاوا، مقادیر پیشفرض $JAVAH (برای شامل شدن مسیر به javac) و $JAVAHFLAGS (برای دربرداشتن دستکم یک پرچم -h) را بازنویسی کنید، و توجه داشته باشید که تولید هدرها با javac تنها نیازمند فراهم کردن فایلهای منبع .java است، نه فایلهای .class.
Library(), env.Library()
LoadableModule(), env.LoadableModule()
M4(), env.M4()
env.M4(target = 'foo.c', source = 'foo.c.m4')
MOFiles(), env.MOFiles()
مثال ۱. ایجاد pl.mo و en.mo با کامپایل pl.po و en.po:
env.MOFiles(['pl', 'en'])
مثال ۲. کامپایل فایلها برای زبانهای تعریفشده در فایل LINGUAS:
env.MOFiles(LINGUAS_FILE=True)
مثال ۳. ایجاد pl.mo و en.mo با کامپایل pl.po و en.po بههمراه فایلهای مربوط به زبانهای تعریفشده در فایل LINGUAS:
env.MOFiles(['pl', 'en'], LINGUAS_FILE=True)
مثال ۴. کامپایل فایلها برای زبانهای تعریفشده در فایل LINGUAS (روشی دیگر):
env['LINGUAS_FILE'] = True env.MOFiles()
MSVSProject(), env.MSVSProject()
یک فایل پروژهی Microsoft Visual C++ را بر اساس نسخهی پیکربندیشدهی Visual Studio (یا دقیقتر بگوییم، MSBuild) میسازد: یا جدیدترین نسخهی نصبشده، یا نسخهی مشخصشده توسط $MSVC_VERSION در محیط ساخت فعلی. برای Visual Studio 6.0 یک فایل .dsp تولید میشود. برای نسخههای ۲۰۰۲ تا ۲۰۰۸ ویژوال استودیو، یک فایل .vcproj تولید میشود. برای Visual Studio 2010 و بالاتر یک فایل .vcxproj تولید میشود. توجه داشته باشید که چندین طرح نسخهبندی در محیط کامپایل مایکروسافت دخیل هستند - برای دیدن معادلها، توضیحات $MSVC_VERSION را ببینید. توجه داشته باشید که SCons نحوهی ساخت فایلهای پروژه را برای سایر زبانها نمیداند (برای مثال .csproj برای #C، .vbproj برای Visual Basic یا .pyproject برای Python).
برای فایل .vcxproj، قالب زیربنایی همان شمای اکسامال (XML Schema) مربوط به MSBuild است و جزئیات آن مطابق با این پیوند است: https://learn.microsoft.com/en-us/cpp/build/reference/vcxproj-file-structure[3]. فایل راهحل تولیدشده، Visual Studio را قادر میسازد ساختار پروژه را درک کند و این امکان را میدهد که با استفاده از MSBuild برای فراخوانی مجدد SCons ساخته شود. فایل پروژه حاوی نسخهی مجموعهابزاری (toolset) است که همانطور که در بالا توضیح داده شد توسط SCons انتخاب شده است. از آنجا که نسخههای جدید Visual Studio از چندین مجموعهابزار همزمان پشتیبانی میکنند، اگر مجموعهابزار مورد نظر با پیشفرض SCons مطابقت ندارد، از $MSVC_VERSION برای انتخاب آن استفاده کنید. فایل پروژه همچنین شامل مدخلهایی است که نحوهی فراخوانی SCons را برای ساخت پروژه از داخل Visual Studio (یا از خط فرمان MSBuild) شرح میدهند. در برخی شرایط ممکن است SCons این را به اشتباه تولید کند - بهویژه هنگام استفاده از توزیع scons-local، که به شیوهای متناسب با خط فراخوانی پیشفرض نصب نشده است. در این صورت، متغیر ساخت $SCONS_HOME میتواند برای توصیف روش صحیح تعیین مکان کد SCons بهمنظور درونریزی (import) آن استفاده شود.
بهطور پیشفرض، یک فایل راهحل متناظر نیز برای پروژه تولید میشود. این رفتار میتواند با تعیین auto_build_solution=0 برای سازندهی MSVSProject غیرفعال شود. فایل راهحل همچنین میتواند بهطور مستقل با فراخوانی سازندهی MSVSSolution تولید شود، مانند حالتی که یک راهحل باید چندین پروژه را توصیف کند. برای اطلاعات بیشتر، توضیحات MSVSSolution را ببینید.
سازندهی MSVSProject چندین آرگومان کلیدواژهای را میپذیرد که فهرستهایی از نامهای فایل را برای قرار گرفتن در فایل پروژه توصیف میکنند. در حال حاضر، srcs، incs، localincs، resources و misc شناخته میشوند. این نامها بهگونهای طراحی شدهاند که خودتوضیح باشند، اما توجه داشته باشید که نامهای فایل باید به صورت رشته مشخص شوند، نه به عنوان گرههای پرونده (File Nodes) در SCons (برای مثال اگر فایلهایی را برای گنجاندن با استفاده از تابع Glob تولید میکنید، نتایج باید قبل از ارسال به MSVSProject به فهرستی از رشتهها تبدیل شوند). دلیل این امر این است که Visual Studio و MSBuild چیزی دربارهی انواع گرههای SCons نمیدانند. هر یک از فهرستهای نامهای فایل بهصورت جداگانه اختیاری هستند، اما حداقل یک فهرست باید مشخص شود تا فایل پروژهی حاصل خالی نباشد.
علاوه بر فهرستهای مقادیر بالا، مقادیر زیر نیز میتوانند به عنوان آرگومانهای کلیدواژهای مشخص شوند:
target
variant
cmdargs
cppdefines
cppflags
cpppaths
buildtarget
runfile
نکته
SCons و Microsoft Visual Studio پروژهها را به روشهای متفاوتی درک میکنند و این نگاشت گاهی ناقص است:
از آنجا که SCons همیشه دستورات ساخت خود را از دایرکتوریای که فایل SConstruct در آن قرار دارد اجرا میکند، اگر یک فایل پروژه را در دایرکتوریای متفاوت از دایرکتوری فایل SConstruct تولید کنید، کاربران قادر نخواهند بود با دوبار کلیک روی نام فایل در پیامهای خطای کامپایل که در پنجره خروجی کنسول Visual Studio نمایش داده میشوند به آن دسترسی یابند. این مشکل میتواند با افزودن گزینه کامپایلر Microsoft Visual C++ /FC به متغیر $CCFLAGS برطرف شود تا کامپایلر مسیر کامل هر فایلی را که باعث خطای کامپایل میشود چاپ کند.
اگر فایل پروژه فقط برای شناساندن چیدمان فایلها به مرورگر پروژه Visual Studio استفاده شود مشکلی وجود نخواهد داشت؛ با این حال، نباید از Visual Studio برای ایجاد تغییرات در ساختار پروژه، گزینههای ساخت و غیره استفاده شود، زیرا این تغییرات (الف) به توصیف SCons از پروژه منتقل نمیشوند و (ب) در صورت تولید مجدد فایل پروژه توسط SCons از بین خواهند رفت. فایلهای SConscript باید مرجع اصلی و توصیف نهایی ساخت باقی بمانند.
اگر از فایل پروژه برای هدایت MSBuild استفاده شود (مانند انتخاب «build» از رابط کاربری Visual Studio)، کنترل مستقیمی را که هنگام اجرای ساخت مستقیماً از طریق SCons بر انتخاب هدف و گزینههای خط فرمان داشتید از دست میدهید، زیرا این موارد در فایل پروژه بر اساس مقادیر مشخصشده در فراخوانی MSVSProject بهصورت ثابت (hard-code) ثبت میشوند. میتوانید بخشی از این کنترل را با تعریف چندین گونه و استفاده از فراخوانیهای متعدد MSVSProject برای چیدمان اهداف ساخت، آرگومانها، تعاریف، پرچمها و مسیرهای متفاوت برای گونههای مختلف بازیابید.
اگر ساخت درون یک solution با چندین پروژه MSBuild تقسیم شود، این نگاشت بیش از پیش دچار محدودیت و پیچیدگی میشود. در این حالت، مهم است که Visual Studio را روی انجام ساختهای موازی تنظیم نکنید، زیرا در این صورت ساخت پروژههای مجزا را بهصورت موازی اجرا میکند و SCons در صورت فراخوانی به این روش عملکرد مناسبی ندارد. در عوض، میتوانید فرایند ساخت SCons را برای ساخت موازی تنظیم کنید - برای چگونگی انجام این کار با num_jobs، تابع SetOption را ببینید.
barsrcs = ['bar.cpp']
barincs = ['bar.h']
barlocalincs = ['StdAfx.h']
barresources = ['bar.rc', 'resource.h']
barmisc = ['bar_readme.txt']
dll = env.SharedLibrary(target='bar.dll', source=barsrcs)
buildtarget = [s for s in dll if str(s).endswith('dll')]
env.MSVSProject(
target='Bar' + env['MSVSPROJECTSUFFIX'],
srcs=barsrcs,
incs=barincs,
localincs=barlocalincs,
resources=barresources,
misc=barmisc,
buildtarget=buildtarget,
variant='Release',
)
DebugSettings
تغییریافته در نسخهٔ 2.4: پارامتر اختیاری DebugSettings افزوده شد.
در حال حاضر، تنها Visual Studio نسخهٔ v9.0 و Visual Studio نسخهٔ v11 پیادهسازی شدهاند؛ برای سایر نسخهها فایلی تولید نمیشود. برای تولید فایل کاربر، کافی است یک دیکشنری DebugSettings با پارامترهای مناسب برای نسخهٔ MSVS خود به محیط بیفزایید. اگر دیکشنری خالی باشد یا حاوی هیچ مقدار معتبری نباشد، هیچ فایلی تولید نخواهد شد.
در ادامه مثالی جامعتر آورده شده است که شامل راهاندازی یک پروژه برای گونهها و DebugSettings میشود:
# Assuming you store your defaults in a file
vars = Variables('variables.py')
msvcver = vars.args.get('vc', '9')
# Check command args to force one Microsoft Visual Studio version
if msvcver == '9' or msvcver == '11':
env = Environment(MSVC_VERSION=msvcver + '.0', MSVC_BATCH=False)
else:
env = Environment()
AddOption(
'--userfile',
action='store_true',
dest='userfile',
default=False,
help="Create Visual C++ project file",
)
#
# 1. Configure your Debug Setting dictionary with options you want in the list
# of allowed options, for instance if you want to create a user file to launch
# a specific application for testing your dll with Microsoft Visual Studio 2008 (v9):
#
V9DebugSettings = {
'Command': 'c:\\myapp\\using\\thisdll.exe',
'WorkingDirectory': 'c:\\myapp\\using\\',
'CommandArguments': '-p password',
# 'Attach':'false',
# 'DebuggerType':'3',
# 'Remote':'1',
# 'RemoteMachine': None,
# 'RemoteCommand': None,
# 'HttpUrl': None,
# 'PDBPath': None,
# 'SQLDebugging': None,
# 'Environment': '',
# 'EnvironmentMerge':'true',
# 'DebuggerFlavor': None,
# 'MPIRunCommand': None,
# 'MPIRunArguments': None,
# 'MPIRunWorkingDirectory': None,
# 'ApplicationCommand': None,
# 'ApplicationArguments': None,
# 'ShimCommand': None,
# 'MPIAcceptMode': None,
# 'MPIAcceptFilter': None,
}
#
# 2. Because there are a lot of different options depending on the Microsoft
# Visual Studio version, if you use more than one version you have to
# define a dictionary per version, for instance if you want to create a user
# file to launch a specific application for testing your dll with Microsoft
# Visual Studio 2012 (v11):
#
V10DebugSettings = {
'LocalDebuggerCommand': 'c:\\myapp\\using\\thisdll.exe',
'LocalDebuggerWorkingDirectory': 'c:\\myapp\\using\\',
'LocalDebuggerCommandArguments': '-p password',
# 'LocalDebuggerEnvironment': None,
# 'DebuggerFlavor': 'WindowsLocalDebugger',
# 'LocalDebuggerAttach': None,
# 'LocalDebuggerDebuggerType': None,
# 'LocalDebuggerMergeEnvironment': None,
# 'LocalDebuggerSQLDebugging': None,
# 'RemoteDebuggerCommand': None,
# 'RemoteDebuggerCommandArguments': None,
# 'RemoteDebuggerWorkingDirectory': None,
# 'RemoteDebuggerServerName': None,
# 'RemoteDebuggerConnection': None,
# 'RemoteDebuggerDebuggerType': None,
# 'RemoteDebuggerAttach': None,
# 'RemoteDebuggerSQLDebugging': None,
# 'DeploymentDirectory': None,
# 'AdditionalFiles': None,
# 'RemoteDebuggerDeployDebugCppRuntime': None,
# 'WebBrowserDebuggerHttpUrl': None,
# 'WebBrowserDebuggerDebuggerType': None,
# 'WebServiceDebuggerHttpUrl': None,
# 'WebServiceDebuggerDebuggerType': None,
# 'WebServiceDebuggerSQLDebugging': None,
}
#
# 3. Select the dictionary you want depending on the version of Visual Studio
# Files you want to generate.
#
if not env.GetOption('userfile'):
dbgSettings = None
elif env.get('MSVC_VERSION', None) == '9.0':
dbgSettings = V9DebugSettings
elif env.get('MSVC_VERSION', None) == '11.0':
dbgSettings = V10DebugSettings
else:
dbgSettings = None
#
# 4. Add the dictionary to the DebugSettings keyword.
#
barsrcs = ['bar.cpp', 'dllmain.cpp', 'stdafx.cpp']
barincs = ['targetver.h']
barlocalincs = ['StdAfx.h']
barresources = ['bar.rc', 'resource.h']
barmisc = ['ReadMe.txt']
dll = env.SharedLibrary(target='bar.dll', source=barsrcs)
env.MSVSProject(
target='Bar' + env['MSVSPROJECTSUFFIX'],
srcs=barsrcs,
incs=barincs,
localincs=barlocalincs,
resources=barresources,
misc=barmisc,
buildtarget=[dll[0]] * 2,
variant=('Debug|Win32', 'Release|Win32'),
cmdargs=f'vc={msvcver}',
DebugSettings=(dbgSettings, {}),
)
MSVSSolution(), env.MSVSSolution()
یک فایل راهکار Visual Studio را بر اساس نسخه پیکربندیشده Visual Studio میسازد: یا آخرین نسخه نصبشده، یا نسخهای که توسط $MSVC_VERSION در محیط ساخت مشخص شده است. برای Visual Studio 6، یک فایل .dsw تولید میشود. برای Visual Studio .NET 2002 و جدیدتر، یک فایل .sln تولید خواهد شد. توجه داشته باشید که در محیط ترجمه و کامپایل مایکروسافت چندین طرح نسخهبندی دخیل هستند - برای معادلها به توضیحات $MSVC_VERSION مراجعه کنید.
فایل راهکار محفظهای برای یک یا چند پروژه است و از قالبی که در https://learn.microsoft.com/en-us/visualstudio/extensibility/internals/solution-dot-sln-file[4] توصیف شده، پیروی میکند.
مقادیر زیر باید مشخص شوند:
target
variant
projects
علاوه بر آرگومانهای اجباری بالا، مقادیر اختیاری زیر میتوانند به عنوان آرگومانهای کلیدواژهای مشخص شوند:
auto_filter_projects
مقادیر پذیرفتهشده برای auto_filter_projects عبارتند از:
None
None مقدار پیشفرض است.
True یا ارزیابی به True
False یا ارزیابی به False
هنگام باز کردن فایل راهکار تولیدشده با VS IDE، محیط VS IDE احتمالاً گزارش خواهد داد که رکوردهای نادرستی از Project وجود دارند که پشتیبانی نمیشوند یا نیاز به اصلاح دارند.
نمونه کاربرد:
env.MSVSSolution(
target="Bar" + env["MSVSSOLUTIONSUFFIX"],
projects=["bar" + env["MSVSPROJECTSUFFIX"]],
variant="Release",
)
Ninja(), env.Ninja()
نکته
این یک ویژگی آزمایشی است. برای فعالسازی آن باید از یکی از روشهای زیر استفاده کنید
# On the command line
--experimental=ninja
# Or in your SConstruct
SetOption('experimental', 'ninja')
این قابلیت ممکن است بدون چرخه منسوخسازی (deprecation cycle) تغییر یافته و/یا حذف شود.
برای استفاده از این ابزار باید بسته ninja در Python را نصب کنید، زیرا این ابزار به طور پیشفرض به قابلیت import کردن این بسته وابسته است این کار از طریق دستور زیر امکانپذیر است:
python -m pip install ninja
اگر با یک تکآرگومان موضعی فراخوانی شود، scons نام هدف را از آن آرگومان منبع «استنتاج» کرده، همان نام را به آن اختصاص میدهد و سپس منبع را نادیده میگیرد. در صورتی که نام هدفی غیر از پیشفرض خواسته شده باشد، این روش معمول فراخوانی سازنده است.
اگر با هر یک از آرگومانهای کلیدواژهای target= یا source= فراخوانی شود، مقدار آرگومان به عنوان نام هدف در نظر گرفته میشود. اگر با هر دو فراخوانی شود، مقدار target= استفاده شده و source= نادیده گرفته میشود. اگر با چند منبع فراخوانی شود، فهرست منابع نادیده گرفته خواهد شد، زیرا راهی برای استنتاج هدف مورد نظر وجود ندارد؛ در این حالت نام هدف پیشفرض استفاده خواهد شد.
از scons 4.2 به بعد در دسترس است.
Object(), env.Object()
Package(), env.Package()
env = Environment(tools=['default', 'packaging'])
SCons میتواند بستهها را در چندین قالب بستهبندی شناختهشده بسازد. نوع بستهٔ هدف میتواند با متغیر ساخت $PACKAGETYPE یا گزینهٔ خط فرمان --package-type انتخاب شود. نوع بسته میتواند یک فهرست باشد، که در این صورت SCons تلاش خواهد کرد تا بستهها را برای هر نوع موجود در فهرست بسازد. مثال:
env.Package(PACKAGETYPE=['src_zip', 'src_targz'], ...other args...)
بستهبندهای پشتیبانیشده در حال حاضر عبارتند از:
| msi | بستهٔ Microsoft Installer |
| rpm | بستهٔ RPM Package Manager |
| ipkg | بستهٔ Itsy Package Management |
| tarbz2 | فایل tar فشردهشده با bzip2 |
| targz | فایل tar فشردهشده با gzip |
| tarxz | فایل tar فشردهشده با xz |
| zip | فایل zip |
| src_tarbz2 | فایل tar فشردهشده با bzip2 مناسب به عنوان منبع برای بستهبند دیگر |
| src_targz | فایل tar فشردهشده با gzip مناسب به عنوان منبع برای بستهبند دیگر |
| src_tarxz | فایل tar فشردهشده با xz مناسب به عنوان منبع برای بستهبند دیگر |
| src_zip | فایل zip مناسب به عنوان منبع برای بستهبند دیگر |
فهرست فایلهایی که باید در بسته گنجانده شوند را میتوان با آرگومان کلیدواژهای source مشخص کرد. در صورت حذف، تابع FindInstalledFiles در پشت صحنه فراخوانی میشود تا تمام فایلهایی را که یک سازندهٔ Install، InstallAs یا InstallVersionedLib به آنها متصل است، انتخاب کند. اگر آرگومان کلیدواژهای target حذف شود، نام(های) هدف از روی نوع(های) بسته استنتاج خواهد شد.
فراداده تا حدی از ویژگیهای فایلهایی که باید بستهبندی شوند، و تا حدی از برچسبهای بستهبندی به دست میآید. برچسبها را میتوان به صورت آرگومانهای کلیدواژهای به فراخوانی سازندهٔ Package ارسال کرد، و همچنین میتوان آنها را با استفاده از تابع Tag به فایلها (یا دقیقتر، گرههایی (Nodes) که نمایانگر فایلها هستند) ضمیمه کرد. برخی از برچسبهای سطح بسته اجباری هستند و در صورت حذف منجر به خطا خواهند شد. برچسبهای اجباری بسته به نوع بسته متفاوت هستند.
هنگام بستهبندی، سازنده از یک مکان موقت مشخصشده با مقدار متغیر $PACKAGEROOT استفاده میکند - سورسهای بسته پیش از بستهبندی در آنجا کپی میشوند.
مثال بستهبندی:
env = Environment(tools=["default", "packaging"])
env.Install("/bin/", "my_program")
env.Package(
NAME="foo",
VERSION="1.2.3",
PACKAGEVERSION=0,
PACKAGETYPE="rpm",
LICENSE="gpl",
SUMMARY="balalalalal",
DESCRIPTION="this should be really really long",
X_RPM_GROUP="Application/fu",
SOURCE_URL="https://foo.org/foo-1.2.3.tar.gz",
)
در این مثال، هدف /bin/my_program ایجاد شده توسط فراخوانی Install به طور پیشفرض ساخته نخواهد شد زیرا زیر دایرکتوری اصلی پروژه قرار ندارد. با این حال، از آنجا که هیچ source مشخصی برای سازندهٔ Package تعیین نشده است، بر اساس قاعدهٔ سورسهای پیشفرض برای بستهبندی انتخاب میشود. از آنجا که بستهبندی با استفاده از $PACKAGEROOT انجام میشود، در واقع هیچ نوشتنی در دایرکتوری /bin سیستم رخ نمیدهد، و هدف حتماً انتخاب خواهد شد، چرا که پس از تغییر مبنا به زیر $PACKAGEROOT اکنون زیر دایرکتوری اصلی پروژه قرار میگیرد.
PCH(), env.PCH()
env['PCH'] = env.PCH('StdAfx.cpp')[0]
نکته
این سازنده مختص پیادهسازی PCH در Microsoft Visual C++ است. سایر زنجیرههای کامپایلر نیز پشتیبانی از هدر از پیش کامپایلشده را پیادهسازی میکنند، اما PCH در حال حاضر با آنها کار نمیکند. در نتیجه، این سازنده تنها زمانی در محیط ساخت ایجاد میشود که Microsoft Visual C++ به عنوان کامپایلر استفاده شود.
این سازنده تنها در یک پروژه ++C به درستی کار میکند. پیادهسازی مایکروسافت بین هدرهای از پیش کامپایلشدهی C و ++C تمایز قائل میشود. استفاده از این سازنده باعث میشود تولید PCH با پرچمی انجام شود که به cl.exe اعلام میکند تمام فایلها، فایلهای ++C هستند؛ اگر سپس آن فایل PCH هنگام کامپایل یک فایل منبع C داده شود، cl.exe ساخت را به دلیل نقض سازگاری با خطا مواجه خواهد کرد.
در صورت امکان، پروژه را طوری ساماندهی کنید که فایل منبع ++C ارسالشده به سازنده PCH، در فهرست سورسهایی که باید به صورت دیگر در پروژه کامپایل شوند قرار نگیرد. SCons در نتیجه فراخوانی PCH، آن فایل را به درستی در درخت وابستگی ردیابی کرده و (برای MSVC 11.0 و بالاتر) فایل شیء متناظر را به طور خودکار به خط پیوند اضافه میکند. اگر فهرست منابع به طور خودکار تولید میشود، برای مثال با استفاده از تابع Glob، ممکن است حذف آن فایل از فهرست ضروری باشد.
PDF(), env.PDF()
# builds from aaa.tex env.PDF(target = 'aaa.pdf', source = 'aaa.tex') # builds bbb.pdf from bbb.dvi env.PDF(target = 'bbb', source = 'bbb.dvi')
POInit(), env.POInit()
گرههای هدف تعریفشده از طریق POInit به طور پیشفرض ساخته نمیشوند (آنها از گره '.' نادیده گرفته میشوند) اما به یک Alias ویژه (به طور پیشفرض 'po-create') افزوده میگردند. نام مستعار را میتوان از طریق متغیر ساخت $POCREATE_ALIAS تغییر داد. تمام فایلهای PO تعریفشده از طریق POInit را میتوان به راحتی با دستور scons po-create مقداردهی اولیه کرد.
مثال ۱. مقداردهی اولیه en.po و pl.po از messages.pot:
env.POInit(['en', 'pl']) # messages.pot --> [en.po, pl.po]
مثال ۲. مقداردهی اولیه en.po و pl.po از foo.pot:
env.POInit(['en', 'pl'], ['foo']) # foo.pot --> [en.po, pl.po]
مثال ۳. مقداردهی اولیه en.po و pl.po از foo.pot اما با استفاده از متغیر ساخت $POTDOMAIN:
env.POInit(['en', 'pl'], POTDOMAIN='foo') # foo.pot --> [en.po, pl.po]
مثال ۴. مقداردهی اولیه فایلهای PO برای زبانهای تعریفشده در فایل LINGUAS. فایلها از قالب messages.pot مقداردهی اولیه خواهند شد:
env.POInit(LINGUAS_FILE=True) # needs 'LINGUAS' file
مثال ۵. مقداردهی اولیه فایلهای PO en.po و pl.pl به علاوه فایلهای مربوط به زبانهای تعریفشده در فایل LINGUAS. فایلها از قالب messages.pot مقداردهی اولیه خواهند شد:
env.POInit(['en', 'pl'], LINGUAS_FILE=True)
مثال ۶. میتوانید ابتدا محیط خود را از پیش پیکربندی کنید، و سپس فایلهای PO را مقداردهی اولیه نمایید:
env['POAUTOINIT'] = True env['LINGUAS_FILE'] = True env['POTDOMAIN'] = 'foo' env.POInit()
که همان اثری را دارد که:
env.POInit(POAUTOINIT=True, LINGUAS_FILE=True, POTDOMAIN='foo')
PostScript(), env.PostScript()
# builds from aaa.tex env.PostScript(target = 'aaa.ps', source = 'aaa.tex') # builds bbb.ps from bbb.dvi env.PostScript(target = 'bbb', source = 'bbb.dvi')
POTUpdate(), env.POTUpdate()
نکته
ممکن است ببینید که xgettext(1) توسط ابزار xgettext فراخوانی میشود، حتی اگر هیچ تغییر واقعی در پیامهای بینالمللیسازیشده رخ نداده باشد (بنابراین فایل POT بهروزرسانی نمیشود). این رویداد هر بار که یک فایل منبع تغییر کند رخ میدهد. در چنین حالتی ما xgettext(1) را فراخوانی کرده و خروجی آن را با محتوای فایل POT مقایسه میکنیم تا تصمیم بگیریم آیا فایل باید بهروزرسانی شود یا خیر.
مثال ۱. بیایید دایرکتوری po/ را ایجاد کرده و اسکریپت SConstruct زیر را در آن قرار دهیم:
# SConstruct in 'po/' subdir env = Environment(tools=['default', 'xgettext']) env.POTUpdate(['foo'], ['../a.cpp', '../b.cpp']) env.POTUpdate(['bar'], ['../c.cpp', '../d.cpp'])
سپس scons را چند بار فراخوانی کنید:
$ scons # Does not create foo.pot nor bar.pot $ scons foo.pot # Updates or creates foo.pot $ scons pot-update # Updates or creates foo.pot and bar.pot $ scons -c # Does not clean foo.pot nor bar.pot.
نتایج همانگونه خواهند بود که در توضیحات بالا آمده است.
مثال ۲. آرگومان target میتواند حذف شود، که در این حالت نام هدف پیشفرض messages.pot استفاده میشود. هدف همچنین میتواند با تنظیم متغیر ساخت $POTDOMAIN یا ارائهٔ آن به عنوان یک جایگزین به سازندهٔ POTUpdate بازنویسی شود:
# SConstruct script env = Environment(tools=['default', 'xgettext']) env['POTDOMAIN'] = "foo" env.POTUpdate(source=["a.cpp", "b.cpp"]) # Creates foo.pot ... env.POTUpdate(POTDOMAIN="bar", source=["c.cpp", "d.cpp"]) # and bar.pot
مثال ۳. پارامتر source نیز در صورتی که در یک فایل جداگانه، برای مثال POTFILES.in مشخص شده باشد، میتواند حذف شود:
# POTFILES.in in 'po/' subdirectory ../a.cpp ../b.cpp # end of file
نام فایلی (POTFILES.in) که حاوی فهرست منابع است از طریق $XGETTEXTFROM ارائه میشود:
# SConstruct file in 'po/' subdirectory env = Environment(tools=['default', 'xgettext']) env.POTUpdate(XGETTEXTFROM='POTFILES.in')
مثال ۴. میتوانید از $XGETTEXTPATH برای تعریف مسیر جستجوی منبع استفاده کنید. برای مثال فرض کنید فایلهای a.cpp، b.cpp، po/SConstruct، po/POTFILES.in را دارید. در این صورت فایلهای مرتبط با POT شما میتوانند به این شکل باشند:
# POTFILES.in in 'po/' subdirectory a.cpp b.cpp # end of file
# SConstruct file in 'po/' subdirectory env = Environment(tools=['default', 'xgettext']) env.POTUpdate(XGETTEXTFROM='POTFILES.in', XGETTEXTPATH='../')
مثال ۵. چندین دایرکتوری جستجو را میتوان بهصورت یک لیست تعریف کرد، یعنی XGETTEXTPATH=['dir1', 'dir2', ...]. ترتیب در لیست، ترتیب جستجوی فایلهای منبع را مشخص میکند. مسیر اولین فایل یافتشده استفاده میشود.
بیایید اسکریپت 0/1/po/SConstruct را ایجاد کنیم:
# SConstruct file in '0/1/po/' subdirectory env = Environment(tools=['default', 'xgettext']) env.POTUpdate(XGETTEXTFROM='POTFILES.in', XGETTEXTPATH=['../', '../../'])
و همچنین 0/1/po/POTFILES.in:
# POTFILES.in in '0/1/po/' subdirectory a.cpp # end of file
دو فایل *.cpp بنویسید، اولی 0/a.cpp است:
/* 0/a.cpp */
gettext("Hello from ../../a.cpp")
و دومی 0/1/a.cpp است:
/* 0/1/a.cpp */
gettext("Hello from ../a.cpp")
سپس scons را اجرا کنید. شما 0/1/po/messages.pot را با پیام "Hello from ../a.cpp" به دست خواهید آورد. زمانی که ترتیب را در $XGETTEXTFOM معکوس کنید، یعنی هنگامی که SConscript را بهصورت زیر بنویسید:
# SConstruct file in '0/1/po/' subdirectory env = Environment(tools=['default', 'xgettext']) env.POTUpdate(XGETTEXTFROM='POTFILES.in', XGETTEXTPATH=['../../', '../'])
آنگاه messages.pot شامل خط msgid "Hello from ../../a.cpp" خواهد بود و نه msgid "Hello from ../a.cpp".
POUpdate(), env.POUpdate()
گرههای هدف بهطور پیشفرض برای ساخت انتخاب نمیشوند (برای نمونه scons .). در عوض، آنها بهطور خودکار به یک Alias ویژه (بهطور پیشفرض 'po-update') افزوده میشوند. نام مستعار را میتوان از طریق متغیر ساخت $POUPDATE_ALIAS تغییر داد. میتوانید بهسادگی پروندههای PO را در پروژهٔ خود با دستور scons po-update بهروزرسانی کنید. توجه داشته باشید که POUpdate برخلاف POInit، هدفهای خود را به نام مستعار po-create نمیافزاید.
مثال ۱. بهروزرسانی en.po و pl.po از قالب messages.pot (همچنین ببینید $POTDOMAIN)، با این فرض که مورد دوم وجود دارد یا قانونی برای ساخت آن تعریف شده است (ببینید POTUpdate):
env.POUpdate(['en','pl']) # messages.pot --> [en.po, pl.po]
مثال ۲. بهروزرسانی en.po و pl.po از قالب foo.pot:
env.POUpdate(['en', 'pl'], ['foo']) # foo.pot --> [en.po, pl.pl]
مثال ۳. بهروزرسانی en.po و pl.po از foo.pot (روشی دیگر):
env.POUpdate(['en', 'pl'], POTDOMAIN='foo') # foo.pot -- > [en.po, pl.pl]
مثال ۴. بهروزرسانی پروندهها برای زبانهای تعریفشده در پروندهٔ LINGUAS. پروندهها از قالب messages.pot بهروزرسانی میشوند:
env.POUpdate(LINGUAS_FILE=True) # needs 'LINGUAS' file
مثال ۵. مشابه بالا، اما بهروزرسانی از قالب foo.pot:
env.POUpdate(LINGUAS_FILE=True, source=['foo'])
مثال ۶. بهروزرسانی en.po و pl.po بههمراه پروندهها برای زبانهای تعریفشده در پروندهٔ LINGUAS. پروندهها از قالب messages.pot بهروزرسانی میشوند:
# produce 'en.po', 'pl.po' + files defined in 'LINGUAS': env.POUpdate(['en', 'pl' ], LINGUAS_FILE=True)
مثال ۷. استفاده از $POAUTOINIT برای مقداردهی اولیهٔ خودکار پروندهٔ PO در صورتی که وجود نداشته باشد:
env.POUpdate(LINGUAS_FILE=True, POAUTOINIT=True)
مثال ۸. بهروزرسانی پروندههای PO برای زبانهای تعریفشده در پروندهٔ LINGUAS. پروندهها از قالب foo.pot بهروزرسانی میشوند. تمام تنظیمات لازم از پیش از طریق محیط پیکربندی شدهاند.
env['POAUTOINIT'] = True env['LINGUAS_FILE'] = True env['POTDOMAIN'] = 'foo' env.POUpdate()
Program(), env.Program()
env.Program(target='foo', source=['foo.o', 'bar.c', 'baz.f'])
ProgramAllAtOnce(), env.ProgramAllAtOnce()
کدهای منبع D میتوانند مانند منابع C و C++ بهصورت فایلبهفایل کامپایل شوند، و زبان D برای این مدل ساخت با سازندههای Object و Program در scons یکپارچه شده است. با این حال، کدهای D میتوانند فرا-برنامهنویسی روی کل کد منبع (whole source meta-programming) انجام دهند (برخی از چارچوبهای آزمون این کار را میکنند). برای این منظور ضروری است که تمام منابع در یک فراخوانی واحد به کامپایلر D، کامپایل و پیوند (link) داده شوند. این سازنده در خدمت این هدف است.
env.ProgramAllAtOnce('executable', ['mod_a.d, mod_b.d', 'mod_c.d'])
این دستور ماژولهای mod_a، mod_b و mod_c را در یک فرایند کامپایل واحد بدون ایجاد فایلهای شیء اولیه برای ماژولها، کامپایل خواهد کرد. برخی از کامپایلرهای D فایل executable.o را ایجاد خواهند کرد و برخی دیگر ایجاد نخواهند کرد.
RES(), env.RES()
env.RES('resource.rc')
RMIC(), env.RMIC()
اگر متغیر ساخت $JAVACLASSDIR تنظیم شده باشد، چه در محیط و چه در فراخوانی خود متد سازنده RMIC، مقدار این متغیر از ابتدای هر نام فایل .class حذف خواهد شد.
classes = env.Java(target='classdir', source='src')
env.RMIC(target='outdir1', source=classes)
env.RMIC(
target='outdir2',
source=['package/foo.class', 'package/bar.class'],
)
env.RMIC(
target='outdir3',
source=['classes/foo.class', 'classes/bar.class'],
JAVACLASSDIR='classes',
)
RPCGenClient(), env.RPCGenClient()
# Builds src/rpcif_clnt.c
env.RPCGenClient('src/rpcif.x')
RPCGenHeader(), env.RPCGenHeader()
# Builds src/rpcif.h
env.RPCGenHeader('src/rpcif.x')
RPCGenService(), env.RPCGenService()
# Builds src/rpcif_svc.c
env.RPCGenClient('src/rpcif.x')
RPCGenXDR(), env.RPCGenXDR()
# Builds src/rpcif_xdr.c
env.RPCGenClient('src/rpcif.x')
SharedLibrary(), env.SharedLibrary()
پیشوند فایل کتابخانه هدف، مشخصشده توسط متغیر ساخت $SHLIBPREFIX (به طور پیشفرض، lib در سیستمهای POSIX، و بدون مقدار در سیستمهای Windows)، و پسوند، مشخصشده توسط متغیر ساخت $SHLIBSUFFIX (به طور پیشفرض، .dll در سیستمهای Windows، و .so در سیستمهای POSIX)، به طور خودکار (اگر از قبل وجود نداشته باشد) به نام هدف اضافه میشوند تا نام فایل کتابخانه تشکیل شود. در یک سیستم POSIX، اگر متغیر ساخت $SHLIBVERSION تنظیم شده باشد، (پس از یک نقطه) به انتهای نام کتابخانه حاصل اضافه میشود.
مثال:
env.SharedLibrary(target='bar', source=['bar.c', 'foo.o'])
در سیستمهای Windows، متد سازنده SharedLibrary همیشه علاوه بر کتابخانه مشترک (.dll)، یک کتابخانه واردات (.lib) نیز خواهد ساخت، و در صورتی که فایلی با پسوند .lib به طور صریح در اهداف فهرست نشده باشد، یک کتابخانه .lib با همان نام پایه اضافه میکند.
در سیستمهای Cygwin، متد سازنده SharedLibrary همیشه علاوه بر کتابخانه مشترک (.dll)، یک کتابخانه واردات (.dll.a) نیز خواهد ساخت، و در صورتی که فایلی با پسوند .dll.a به طور صریح در اهداف فهرست نشده باشد، یک کتابخانه .dll.a با همان نام پایه اضافه میکند.
در برخی پلتفرمها، میان یک کتابخانه مشترک (که برای حل ارجاعات خارجی به طور خودکار توسط سیستم بارگذاری میشود) و یک ماژول قابل بارگذاری (که با اقدام کاربر به طور صریح بارگذاری میشود) تمایز وجود دارد. برای بیشترین سازگاری و قابلیت حمل، برای مورد دوم از سازنده LoadableModule استفاده کنید.
اگر $SHLIBVERSION تعریف شده باشد، یک کتابخانه مشترک نسخهدار ایجاد میشود. این کار $SHLINKFLAGS را بر حسب نیاز تغییر میدهد، شماره نسخه را به نام کتابخانه اضافه میکند و هر پیوند نمادین مورد نیازی را میسازد.
env.SharedLibrary(target='bar', source=['bar.c', 'foo.o'], SHLIBVERSION='1.5.2')
در یک سیستم POSIX، ارائه یک رشته نسخه ساده (بدون نقطه) دقیقاً یک پیوند نمادین ایجاد میکند: SHLIBVERSION="1" (به عنوان مثال) کتابخانه libbar.so.1 و پیوند نمادین libbar.so را ایجاد میکند. ارائه یک رشته نسخه نقطهدار دو پیوند نمادین ایجاد خواهد کرد (بدون در نظر گرفتن تعداد بخشها در نسخه): SHLIBVERSION="1.5.2" برای همان کتابخانه، کتابخانه libbar.so.1.5.2 و پیوندهای نمادین libbar.so و libbar.so.1 را ایجاد میکند. یک سیستم Darwin (OSX) در هر دو حالت یک پیوند نمادین ایجاد میکند؛ برای مثال دوم، کتابخانه libbar.1.5.2.dylib و پیوند libbar.dylib خواهد بود.
در سیستمهای Windows، مشخص کردن آرگومان کلیدواژهای register=1 باعث میشود که .dll پس از ساخته شدن ثبت شود. دستوری که اجرا میشود توسط متغیر ساخت $REGSVR (به طور پیشفرض regsvr32) تعیین شده و پرچمهای ارسالی توسط $REGSVRFLAGS مشخص میشوند. به طور پیشفرض، $REGSVRFLAGS شامل گزینه /s است تا هنگام اجرا، از باز شدن کادرهای محاورهای و نیاز به توجه کاربر جلوگیری کند. اگر $REGSVRFLAGS را تغییر میدهید، حتماً گزینه /s را بگنجانید. به عنوان مثال،
env.SharedLibrary(target='bar', source=['bar.cxx', 'foo.obj'], register=1)
پس از پایان پیوند دادن آن، bar.dll را به عنوان یک شیء COM ثبت خواهد کرد.
SharedObject(), env.SharedObject()
env.SharedObject(target='ddd', source='ddd.c')
env.SharedObject(target='eee.o', source='eee.cpp')
env.SharedObject(target='fff.obj', source='fff.for')
env.SharedObject(source=Glob('*.c'))
در برخی پلتفرمها، ساخت یک شیء مشترک علاوه بر موارد مورد نیاز برای ساخت یک شیء معمولی (ایستا)، نیازمند گزینه(های) کامپایلر اضافی است (مانند -fPIC برای gcc). اگر اشیاء مشترک و ایستا تفاوت داشته باشند، SCons تنها اجازه میدهد اشیاء مشترک به یک کتابخانه مشترک پیوند داده شوند، و برای کمک به نمایش و ردیابی این تفاوت، از پسوند متفاوتی برای اشیاء مشترک استفاده خواهد کرد.
فایلهای منبع بر اساس نگاشتهای پسوند در شیء SourceFileScanner پویش خواهند شد. برای اطلاعات بیشتر به بخش "Scanner Objects" در صفحه راهنما مراجعه کنید.
StaticLibrary(), env.StaticLibrary()
env.StaticLibrary(target='bar', source=['bar.c', 'foo.o'])
هر فایل شیء فهرستشده در source باید برای یک کتابخانهٔ ایستا ساخته شده باشد (یعنی با استفاده از متد سازندهٔ StaticObject). در صورت وجود هرگونه عدم تطابق، scons خطایی صادر خواهد کرد.
StaticObject(), env.StaticObject()
.asm فایل زبان اسمبلی
.ASM فایل زبان اسمبلی
.c فایل C
.C Windows: فایل C
POSIX: فایل C++
.cc فایل C++
.cpp فایل C++
.cxx فایل C++
.cxx فایل C++
.c++ فایل C++
.C++ فایل C++
.d فایل D
.f فایل Fortran
.F Windows: فایل Fortran
POSIX: فایل Fortran + پیشپردازندهٔ C
.for فایل Fortran
.FOR فایل Fortran
.fpp فایل Fortran + پیشپردازندهٔ C
.FPP فایل Fortran + پیشپردازندهٔ C
.m فایل Object C
.mm فایل Object C++
.s فایل زبان اسمبلی
.S Windows: فایل زبان اسمبلی
ARM: CodeSourcery Sourcery Lite
.sx فایل زبان اسمبلی + پیشپردازندهٔ C
POSIX: فایل زبان اسمبلی + پیشپردازندهٔ C
.spp فایل زبان اسمبلی + پیشپردازندهٔ C
.SPP فایل زبان اسمبلی + پیشپردازندهٔ C
پیشوند فایل شیء هدف، که توسط متغیر ساخت $OBJPREFIX مشخص میشود (بهطور پیشفرض رشتهٔ خالی)، و پسوند آن، که توسط متغیر ساخت $OBJSUFFIX مشخص میشود (.obj در سیستمهای Windows و .o در سیستمهای POSIX)، در صورتی که از قبل موجود نباشند، بهطور خودکار به هدف افزوده میشوند. StaticObject یک سازندهٔ تکمنبعی است. مثالها:
env.StaticObject(target='aaa', source='aaa.c')
env.StaticObject(target='bbb.o', source='bbb.c++')
env.StaticObject(target='ccc.obj', source='ccc.f')
env.StaticObject(source=Glob('*.c'))
فایلهای منبع مطابق با نگاشتهای پسوند در شیء SourceFileScanner پویش خواهند شد. برای اطلاعات بیشتر بخش “Scanner Objects” در صفحهٔ راهنما را ببینید.
Substfile(), env.Substfile()
بهطور پیشفرض، کدگذاری فایل هدف “utf-8” است و میتواند توسط $FILE_ENCODING تغییر کند. مثالها:
اگر نام یک فایل منبع تکی مشخص شده باشد و دارای پسوند .in باشد، این پسوند حذف شده و باقیماندهٔ نام به عنوان نام هدف پیشفرض استفاده میشود.
پیشوند و پسوند مشخصشده توسط متغیرهای ساخت $SUBSTFILEPREFIX و $SUBSTFILESUFFIX (در هر دو مورد بهطور پیشفرض یک رشتهٔ خالی)، در صورتی که از قبل موجود نباشند، بهطور خودکار به هدف افزوده میشوند.
اگر متغیر ساختی به نام $SUBST_DICT وجود داشته باشد، میتواند یک دیکشنری Python یا توالیای از چندتاییهای (key, value) باشد. اگر یک دیکشنری باشد، به فهرستی از چندتاییها با ترتیبی نامشخص تبدیل میشود؛ بنابراین اگر یک کلید پیشوندی از کلید دیگر باشد یا اگر یک جایگزینی بتواند با جایگزینی دیگر بیشتر بسط یابد، رخ دادن یا ندادن بسط غیرقابل پیشبینی خواهد بود.
هر بار وقوع یک کلید در منبع با مقدار متناظر آن جایگزین میشود، که میتواند یک تابع قابل فراخوانی در Python یا یک رشته باشد. اگر مقدار یک تابع قابل فراخوانی باشد، بدون هیچ آرگومانی فراخوانی میشود تا یک رشته به دست آید. رشتهها با subst بسط داده میشوند و نتیجه جایگزین کلید میشود.
env = Environment(tools=['default'])
env['prefix'] = '/usr/bin'
script_dict = {'@prefix@': '/bin', '@exec_prefix@': '$prefix'}
env.Substfile('script.in', SUBST_DICT=script_dict)
conf_dict = {'%VERSION%': '1.2.3', '%BASE%': 'MyProg'}
env.Substfile('config.h.in', conf_dict, SUBST_DICT=conf_dict)
# UNPREDICTABLE - one key is a prefix of another
bad_foo = {'$foo': '$foo', '$foobar': '$foobar'}
env.Substfile('foo.in', SUBST_DICT=bad_foo)
# PREDICTABLE - keys are applied longest first
good_foo = [('$foobar', '$foobar'), ('$foo', '$foo')]
env.Substfile('foo.in', SUBST_DICT=good_foo)
# UNPREDICTABLE - one substitution could be further expanded
bad_bar = {'@bar@': '@soap@', '@soap@': 'lye'}
env.Substfile('bar.in', SUBST_DICT=bad_bar)
# PREDICTABLE - substitutions are expanded in order
good_bar = (('@bar@', '@soap@'), ('@soap@', 'lye'))
env.Substfile('bar.in', SUBST_DICT=good_bar)
# the SUBST_DICT may be in common (and not an override)
substutions = {}
subst = Environment(tools=['textfile'], SUBST_DICT=substitutions)
substitutions['@foo@'] = 'foo'
subst['SUBST_DICT']['@bar@'] = 'bar'
subst.Substfile(
'pgm1.c',
[Value('#include "@foo@.h"'), Value('#include "@bar@.h"'), "common.in", "pgm1.in"],
)
subst.Substfile(
'pgm2.c',
[Value('#include "@foo@.h"'), Value('#include "@bar@.h"'), "common.in", "pgm2.in"],
)
Tar(), env.Tar()
env.Tar('src.tar', 'src')
# Create the stuff.tar file.
env.Tar('stuff', ['subdir1', 'subdir2'])
# Also add "another" to the stuff.tar file.
env.Tar('stuff', 'another')
# Set TARFLAGS to create a gzip-filtered archive.
env = Environment(TARFLAGS = '-c -z')
env.Tar('foo.tar.gz', 'foo')
# Also set the suffix to .tgz.
env = Environment(TARFLAGS = '-c -z',
TARSUFFIX = '.tgz')
env.Tar('foo')
Textfile(), env.Textfile()
پیشوند و پسوند مشخصشده توسط متغیرهای ساخت $TEXTFILEPREFIX و $TEXTFILESUFFIX (بهطور پیشفرض به ترتیب یک رشتهٔ خالی و .txt) در صورتی که از قبل وجود نداشته باشند، بهطور خودکار به هدف اضافه میشوند.
بهطور پیشفرض، کدبندی فایل هدف "utf-8" است و میتواند با $FILE_ENCODING تغییر کند. مثالها:
# builds/writes foo.txt
env.Textfile(target='foo.txt', source=['Goethe', 42, 'Schiller'])
# builds/writes bar.txt
env.Textfile(target='bar', source=['lalala', 'tanteratei'], LINESEPARATOR='|*')
# nested lists are flattened automatically
env.Textfile(target='blob', source=['lalala', ['Goethe', 42, 'Schiller'], 'tanteratei'])
# files may be used as input by wrapping them in File()
env.Textfile(
target='concat', # concatenate files with a marker between
source=[File('concat1'), File('concat2')],
LINESEPARATOR='====================\n',
)
نتایج:
foo.txt
Goethe 42 Schiller
bar.txt
lalala|*tanteratei
blob.txt
lalala Goethe 42 Schiller tanteratei
Translate(), env.Translate()
مثال ۱. سادهترین راه، تعیین فایلهای ورودی و زبانهای خروجی بهصورت درونخطی در یک اسکریپت SCons هنگام فراخوانی Translate است:
# SConscript in 'po/' directory env = Environment(tools=["default", "gettext"]) env['POAUTOINIT'] = True env.Translate(['en', 'pl'], ['../a.cpp', '../b.cpp'])
مثال ۲. در صورت تمایل، میتوانید به سبک مرسوم شناختهشده از autotools نیز پایبند باشید، یعنی استفاده از فایلهای POTFILES.in و LINGUAS برای مشخص کردن هدفها و مبدأها:
# LINGUAS en pl # end
# POTFILES.in a.cpp b.cpp # end
# SConscript env = Environment(tools=["default", "gettext"]) env['POAUTOINIT'] = True env['XGETTEXTPATH'] = ['../'] env.Translate(LINGUAS_FILE=True, XGETTEXTFROM='POTFILES.in')
رویکرد آخر احتمالاً روش توصیهشده است. این رویکرد امکان تفکیک آسان بینالمللیسازی/محلیسازی را در اسکریپتهای جداگانهٔ SCons فراهم میکند؛ بهگونهای که یک اسکریپت در درخت مبدأ مسئول ترجمهها (از فایلهای مبدأ به فایلهای PO) است و اسکریپت(ها) در دایرکتوریهای متغیر (variant directories) مسئول کامپایل فایلهای PO به فایلهای MO و همچنین نصب فایلهای MO هستند. در این حالت «عامل پیونددهنده» که این دو اسکریپت را همگام میکند، محتوای فایل LINGUAS است. توجه داشته باشید که فایلهای بهروزشدهٔ POT و PO معمولاً قرار است به مخزن ثبت (commit) شوند، بنابراین باید در داخل دایرکتوری مبدأ بهروز شوند (و نه در دایرکتوریهای متغیر). علاوه بر این، فهرست فایلهای دایرکتوری po/ شامل فایل LINGUAS است، بنابراین درخت مبدأ برای مترجمان آشنا به نظر میرسد و آنها میتوانند به شیوهٔ معمول خود با پروژه کار کنند.
مثال ۳. بیایید یک درخت توسعه را بهصورت زیر آماده کنیم:
project/
+ SConstruct
+ build/
+ src/
+ po/
+ SConscript
+ SConscript.i18n
+ POTFILES.in
+ LINGUAS
که در آن build دایرکتوری متغیر باشد. اسکریپت سطح بالای SConstruct را بهصورت زیر بنویسید:
# SConstruct
env = Environment(tools=["default", "gettext"])
VariantDir('build', 'src', duplicate=False)
env['POAUTOINIT'] = True
SConscript('src/po/SConscript.i18n', exports='env')
SConscript('build/po/SConscript', exports='env')
اسکریپت src/po/SConscript.i18n بهصورت:
# src/po/SConscript.i18n
Import('env')
env.Translate(LINGUAS_FILE=True, XGETTEXTFROM='POTFILES.in', XGETTEXTPATH=['../'])
و اسکریپت src/po/SConscript
# src/po/SConscript
Import('env')
env.MOFiles(LINGUAS_FILE=True)
چنین پیکربندیای فایلهای POT و PO را در درخت مبدأ در src/po/ و فایلهای باینری MO را در درخت متغیر در build/po/ تولید میکند. بدینترتیب فایلهای POT و PO از سایر فایلهای خروجی که نباید به مخازن مبدأ بازگردانده (کامیت) شوند (مانند فایلهای MO) تفکیک میشوند.
نکته
در مثال بالا، هنگام اجرای دستور scons .، فایلهای PO بهطور خودکار بهروزرسانی یا ایجاد نمیشوند. این فایلها باید بهصورت دستی از طریق scons po-update بهروزرسانی (ایجاد) شوند و سپس میتوان با اجرای scons . فایلهای MO را کامپایل کرد.
TypeLibrary(), env.TypeLibrary()
env.TypeLibrary(source="foo.idl")
فایلهای foo.tlb، foo.h، foo_i.c، foo_p.c و foo_data.c را ایجاد خواهد کرد.
Zip(), env.Zip()
env.Zip('src.zip', 'src')
# Create the stuff.zip file.
env.Zip('stuff', ['subdir1', 'subdir2'])
# Also add "another" to the stuff.tar file.
env.Zip('stuff', 'another')
توابع SCons و متدهای محیط ساخت (SCons Functions and Environment Methods)
SCons مجموعهای از متدهای محیط ساخت و توابع سراسری را برای دستکاری پیکربندی ساخت فراهم میکند. اغلب برای راحتی کار، یک متد محیط ساخت و یک تابع سراسری با نامی یکسان وجود دارند. در این بخش، در صورتی که تابعی بتواند به هر دو صورت فراخوانی شود، هر دو حالت نشان داده شدهاند. سبک مستندسازی برای این موارد به صورت زیر است:
Function(arguments, [optional arguments, ...]) # Global function env.Function(arguments, [optional arguments, ...]) # Environment method
در این امضاهای توابع، آرگومانهای درون قلاب ([]) اختیاری هستند و علامت سهنقطه (...) نشاندهنده تکرار احتمالی است. تفاوت میان آرگومانهای مکانی (positional) و کلیدواژهای (keyword) معمولاً در متنِ توضیحات شرح داده شده است، نه در خودِ امضا. نشانگرهای پایتونیِ فقط-مکانی (/) و فقط-کلیدواژهای (*) در اینجا استفاده نشدهاند.
هنگامی که سبک keyword=value پایتون نمایش داده میشود، میتواند دو معنا داشته باشد. اگر آرگومان کلیدواژهای برای تابع شناختهشده باشد، مقدار دادهشده در صورت حذف آرگومان، مقدار پیشفرض آن خواهد بود. اگر کلیدواژه برای تابع ناشناخته باشد، برخی متدها آن را به عنوان انتساب به یک متغیر ساخت (construction variable) در نظر میگیرند؛ در غیر این صورت برای یک آرگومان ناشناخته، استثنا (exception) صادر میشود.
یک تابع سراسری و یک متد محیط ساختِ همنام، کارکرد پایه یکسانی دارند، با دو تفاوت کلیدی:
توابع سراسری به طور خودکار در حوزه دید (scope) درون فایلهای SConscript قرار دارند. اگر پروژه شما ماژولهای Python اضافه میکند که آنها را از طریق دستور import پایتون در یک فایل SConscript فراخوانی میکنید، چنین کدهایی باید این توابع را به طور صریح به حوزه دید سراسری آن ماژول بیفزایند. این کار را میتوانید با افزودن عبارت import زیر به ماژول Python انجام دهید: from SCons.Script import *.
SCons متدهای محیط ساخت و توابع سراسری زیر را فراهم میکند. این فهرست را میتوان به صورت مجزا برای هر پروژه با استفاده از AddMethod گسترش داد.
Action(action, [output, [var, ...]] [key=value, ...]), env.Action(action, [output, [var, ...]] [key=value, ...])
توجه داشته باشید که شکل فراخوانی env.Action متغیرهای ساخت را در تمام رشتههای آرگومان، از جمله آرگومان action، در هنگام فراخوانی با استفاده از متغیرهای ساخت در همان محیط ساختی که env.Action از طریق آن فراخوانی شده است، بسط میدهد. شکل تابع سراسری Action تمام بسطهای متغیر را تا زمانی که شیء Action واقعاً مورد استفاده قرار گیرد به تعویق میاندازد.
AddMethod(object, function, [name]), env.AddMethod(function, [name])
هنگامی که تابع سراسری AddMethod فراخوانی میشود، شیئی که قرار است متد به آن افزوده شود باید به عنوان نخستین آرگومان ارسال گردد؛ معمولاً این شیء Environment خواهد بود تا متدی ایجاد شود که بر تمام محیطهای ساختی که پس از آن ساخته میشوند اعمال گردد. هنگامی که با استفاده از شکل env.AddMethod فراخوانی شود، متد فقط به همان محیط ساختِ مشخصشده افزوده میشود. متدهای افزوده شده از طریق فراخوانیهای env.Clone نیز انتشار مییابند.
نمونههای بیشتر:
# Function to add must accept an instance argument.
# The Python convention is to call this 'self'.
def my_method(self, arg):
print("my_method() got", arg)
# Use the global function to add a method to the Environment class:
AddMethod(Environment, my_method)
env = Environment()
env.my_method('arg')
# Use the optional name argument to set the name of the method:
env.AddMethod(my_method, 'other_method_name')
env.other_method_name('another arg')
AddOption(opt_str, ..., attr=value, ...)
علاوه بر آرگومانها و مقادیر پشتیبانیشده توسط متد add_option در optparse، AddOption امکان تنظیم مقدار کلیدواژهٔ nargs به یک رشتهٔ '?' (علامت سوال) را میدهد تا نشان دهد که آرگومان گزینه برای آن رشتهٔ گزینه میتواند حذف شود. اگر رشتهٔ گزینه در خط فرمان وجود داشته باشد اما هیچ آرگومان گزینهٔ منطبقی نداشته باشد، مقدار آرگومان کلیدواژهای const بهعنوان مقدار گزینه تولید میشود. اگر رشتهٔ گزینه از خط فرمان حذف شود، طبق معمول مقدار آرگومان کلیدواژهای default تولید میشود؛ اگر هیچ آرگومان کلیدواژهای default در فراخوانی AddOption وجود نداشته باشد، None تولید میشود.
optparse مخففهای نامهای گزینههای طولانی را تا زمانی که بتوان آنها را بهطور یکتا و بدون ابهام تشخیص داد، شناسایی میکند. برای نمونه، اگر add_option برای تعریف گزینهٔ --devicename فراخوانی شود، --device، --dev و غیره را نیز تا زمانی که هیچ گزینهٔ دیگری نتواند با همان مخفف مطابقت داشته باشد، تشخیص میدهد. گزینههای افزودهشده از طریق AddOption از تشخیص خودکار مخففها پشتیبانی نمیکنند. در عوض، برای مجاز کردن مخففهای خاص، آنها را به عنوان مترادف در خود فراخوانی AddOption بگنجانید.
پس از اضافه شدن یک گزینهٔ خط فرمان جدید با AddOption، مقدار گزینه را میتوان با استفاده از GetOption یا env.GetOption دریافت کرد. اگر آرگومان settable=True در فراخوانی AddOption داده شده باشد، در صورتی که شرایط در یک فایل SConscript نیاز به بازنویسی مقدار پیشفرض داشته باشد، میتوان مقدار را بعداً با استفاده از SetOption یا env.SetOption نیز تنظیم کرد. با این حال توجه داشته باشید مقداری که در خط فرمان مشخص شده باشد همیشه مقداری را که در یک فایل SConscript تنظیم شده بازنویسی خواهد کرد.
تغییر یافته در نسخهٔ 4.8.0: آرگومان کلیدواژهای settable اضافه شد تا امکان تنظیم یک گزینهٔ افزودهشده از طریق SetOption فراهم شود.
متن راهنما برای یک گزینه، ترکیبی از رشتهٔ ارائهشده در آرگومان کلیدواژهای help به AddOption و اطلاعات جمعآوریشده از سایر آرگومانهای کلیدواژهای است. چنین راهنمایی در صورت استفاده از گزینهٔ خط فرمان -h نمایش داده میشود (اما نه با -H). راهنمای همهٔ گزینههای محلی ذیل عنوان مجزای Local Options نمایش داده میشود. گزینهها مرتبنشده هستند - آنها در متن راهنما به همان ترتیبی که فراخوانیهای AddOption رخ میدهند ظاهر خواهند شد.
مثال:
AddOption(
'--prefix',
dest='prefix',
nargs=1,
type='string',
action='store',
metavar='DIR',
help='installation prefix',
)
env = Environment(PREFIX=GetOption('prefix'))
برای این مثال، متن راهنمای زیر تولید خواهد شد:
Local Options: --prefix=DIR installation prefix
در صورتی که تابع Help فراخوانی شده باشد، ممکن است متن راهنما برای گزینههای محلی در دسترس نباشد؛ برای جزئیات به مستندات Help مراجعه کنید.
نکته
پیش از نسخهٔ 4.11.0، رفتار برنامه هنگامی که گزینههای اضافهشده توسط AddOption با نویسههای فاصله (whitespace) مشخص میشدند، تعریفنشده بود و استفاده از آن توصیه نمیشد. چنین کاربردی هم شامل استفاده از فاصله به عنوان جداکننده (--opt arg در برابر --opt=arg) و هم مواردی بود که در آنها تعداد آرگومانهای گزینه (nargs) بیشتر از یک مشخص میشد. اگرچه این مشکل برطرف شده است، توسعهدهندگان باید در صورتی که پروژه با نسخهٔ قدیمیتر SCons ساخته میشود، از آن مطلع باشند.
AddPostAction(target, action), env.AddPostAction(target, action)
هنگامی که چند هدف ارائه شود، ممکن است کنش چندین بار فراخوانی شود؛ یک بار پس از هر کنشی که یک یا چند هدف از فهرست را تولید میکند.
foo = Program('foo.c')
# remove execute permission from binary:
AddPostAction(foo, Chmod('$TARGET', "a-x"))
اگر یک target یک Alias باشد، action در صورت مشخص بودن، به کنش آن نام مستعار پیوند مییابد.
AddPreAction(target, action), env.AddPreAction(target, action)
هنگامی که چندین هدف مشخص شده باشند، کنش(ها) ممکن است چندین بار فراخوانی شوند؛ یک بار پیش از هر کنشی که یک یا چند هدف از فهرست را تولید میکند.
توجه داشته باشید که اگر هر یک از هدفها در چند مرحله ساخته شوند، کنش درست پیش از مرحلهای فراخوانی میشود که مشخصاً هدف(های) تعیینشده را تولید میکند. شاید همیشه آشکار نباشد که یک فرایند چندمرحلهای است یا خیر - برای نمونه، اگر از سازندهٔ Program برای ساخت یک برنامهٔ اجرایی از یک فایل مبدأ .c استفاده کنید، scons ابتدا یک فایل شیء واسط میسازد؛ پیشکنش (pre-action) پس از این مرحله و درست پیش از دستور پیوند (link) برای تولید دودویی برنامه اجرایی فراخوانی میشود. مثال:
foo = Program('foo.c')
AddPreAction(foo, 'echo "Running pre-action"')
$ scons -Q gcc -o foo.o -c foo.c echo "Running pre-action" Running pre-action gcc -o foo foo.o
اگر یک target یک Alias باشد، action به کنشِ آن نام مستعار (در صورت تعیین شدن) مرتبط میشود.
Alias(alias, [source, [action]]), env.Alias(alias, [source, [action]])
alias و source هر یک میتوانند یک رشته یا شیء Node، یا فهرستی از رشتهها یا اشیاء Node باشند؛ اگر برای alias از شیء Node استفاده شود، باید گرههای Alias باشند. اگر source حذف شود، نام مستعار ایجاد میشود اما مرجعی نخواهد داشت؛ اگر برای ساخت انتخاب شود، این وضعیت به پیام “Nothing to be done.” منجر خواهد شد. یک نام مستعار خالی میتواند برای تعریف نام مستعار در مکانی مشخص از پروژه به کار رود؛ سپس میتوان در یک فایل SConscript فرعی، هدف(های) واقعی را برای ارجاع به آن اضافه کرد. پارامتر اختیاری action یک کنش یا فهرستی از کنشها را تعیین میکند که هرگاه هر یک از اهداف نام مستعار قدیمی (out-of-date) باشند، اجرا خواهند شد.
Alias میتواند برای یک نام مستعار از پیش موجود فراخوانی شود، که آرگومانهای alias و/یا action را به فهرستهای موجود برای آن نام مستعار اضافه میکند.
فهرستی از اشیاء Alias Node را برمیگرداند که بیانگر نام(های) مستعار هستند و خارج از هر سیستمفایل فیزیکی وجود دارند. فضای نامِ نامهای مستعار از فضای نام اهداف ملموس جدا است؛ برای جلوگیری از سردرگمی، نام اهداف را مجدداً به عنوان نام مستعار به کار نبرید.
مثالها:
Alias('install')
Alias('install', '/usr/bin')
Alias(['install', 'install-lib'], '/usr/local/lib')
env.Alias('install', ['/usr/local/bin', '/usr/local/lib'])
env.Alias('install', ['/usr/local/man'])
env.Alias('update', ['file1', 'file2'], "update_database $SOURCES")
AllowSubstExceptions([exception, ...])
اگر AllowSubstExceptions چندین بار فراخوانی شود، هر فراخوانی بهطور کامل فهرست قبلی استثناهای نادیدهگرفتهشده را بازنویسی میکند. فراخوانی آن بدون هیچ آرگومانی بدان معناست که هیچ استثنایی نادیده گرفته نخواهد شد.
مثال:
# Requires that all construction variable names exist.
# (You may wish to do this if you want to enforce strictly
# that all construction variables must be defined before use.)
AllowSubstExceptions()
# Also allow a string containing a zero-division expansion
# like '${1 / 0}' to evaluate to ''.
AllowSubstExceptions(IndexError, NameError, ZeroDivisionError)
AlwaysBuild(target, ...), env.AlwaysBuild(target, ...)
env.Append(key=val, [...])
توضیحات زیر هم برای متدهای Append و Prepend و هم برای گونههای Unique آنها صدق میکند، با این تفاوت که نقطه درج مقادیر افزوده شده و مجاز بودن یا نبودن تکرار با هم تفاوت دارد.
val تقریباً میتواند از هر نوعی باشد. اگر env متغیر ساختی به نام key نداشته باشد، آنگاه key صرفاً با مقدار val ذخیره میشود. در غیر این صورت، val با مقدار موجود ترکیب میشود، و احتمالاً به نوع مناسبی که بتواند محتوای بسطیافته را نگهداری کند تبدیل میشود. چند حالت خاص وجود دارد که باید به آنها توجه کرد. در حالت عادی، هنگامی که دو رشته ترکیب میشوند، نتیجه یک رشته جدید حاوی الحاق آنها است (و شما مسئول فراهم کردن هرگونه فاصلهگذاری مورد نیاز هستید)؛ با این حال، محتویات $CPPDEFINES هنگام تولید خط فرمان با افزودن یک پیشوند و/یا پسوند به هر مدخل پسپردازش میشود، بنابراین SCons آنها را جدا نگه میدارد - افزودن یک رشته منجر به یک مدخل رشتهای جداگانه میشود، نه یک رشته ترکیبشده. برای $CPPDEFINES و همچنین $LIBS و متغیرهای گوناگون *PATH، دستور SCons متغیر را با ارائه نحو خاص کامپایلر اصلاح خواهد کرد (برای نمونه با پیشوند قرار دادن -D یا /D برای $CPPDEFINES)، بنابراین هنگام افزودن مقادیر به این متغیرها باید از ذکر این نحو خودداری کنید. مثالها (نحو gcc در بسط CPPDEFINES نشان داده شده است):
env = Environment(CXXFLAGS="-std=c11", CPPDEFINES="RELEASE")
print(f"CXXFLAGS = {env['CXXFLAGS']}, CPPDEFINES = {env['CPPDEFINES']}")
# notice including a leading space in CXXFLAGS addition
env.Append(CXXFLAGS=" -O", CPPDEFINES="EXTRA")
print(f"CXXFLAGS = {env['CXXFLAGS']}, CPPDEFINES = {env['CPPDEFINES']}")
print("CPPDEFINES will expand to", env.subst('$_CPPDEFFLAGS'))
$ scons -Q CXXFLAGS = -std=c11, CPPDEFINES = RELEASE CXXFLAGS = -std=c11 -O, CPPDEFINES = deque(['RELEASE', 'EXTRA']) CPPDEFINES will expand to -DRELEASE -DEXTRA scons: `.' is up to date.
از آنجا که $CPPDEFINES برای تعیین ماکروهای پیشپردازنده C/C++ در خط فرمان در نظر گرفته شده است، هنگام افزودن به آن نحوهای بیشتری پذیرفته میشود. پیشپردازنده آرگومانهایی را برای پیشتعریف نام یک ماکرو به تنهایی میپذیرد (برای بیشتر کامپایلرها -DFOO و برای Microsoft C++ به صورت /DFOO) که به آن مقدار ضمنی 1 میدهد، یا میتواند همراه با یک مقدار جایگزین ارائه شود (-DBAR=TEXT). SCons هنگام افزودن به $CPPDEFINES از این قوانین پیروی میکند:
مثالها:
env = Environment(CPPDEFINES="FOO")
print("CPPDEFINES =", env['CPPDEFINES'])
env.Append(CPPDEFINES="BAR=1")
print("CPPDEFINES =", env['CPPDEFINES'])
env.Append(CPPDEFINES=[("OTHER", 2)])
print("CPPDEFINES =", env['CPPDEFINES'])
env.Append(CPPDEFINES={"EXTRA": "arg"})
print("CPPDEFINES =", env['CPPDEFINES'])
print("CPPDEFINES will expand to", env.subst('$_CPPDEFFLAGS'))
$ scons -Q
CPPDEFINES = FOO
CPPDEFINES = deque(['FOO', 'BAR=1'])
CPPDEFINES = deque(['FOO', 'BAR=1', ('OTHER', 2)])
CPPDEFINES = deque(['FOO', 'BAR=1', ('OTHER', 2), ('EXTRA', 'arg')])
CPPDEFINES will expand to -DFOO -DBAR=1 -DOTHER=2 -DEXTRA=arg
scons: `.' is up to date.
مثالهایی از افزودن چندین ماکرو:
env = Environment()
env.Append(CPPDEFINES=[("ONE", 1), "TWO", ("THREE", )])
print("CPPDEFINES =", env['CPPDEFINES'])
env.Append(CPPDEFINES={"FOUR": 4, "FIVE": None})
print("CPPDEFINES =", env['CPPDEFINES'])
print("CPPDEFINES will expand to", env.subst('$_CPPDEFFLAGS'))
$ scons -Q
CPPDEFINES = [('ONE', 1), 'TWO', ('THREE',)]
CPPDEFINES = deque([('ONE', 1), 'TWO', ('THREE',), ('FOUR', 4), ('FIVE', None)])
CPPDEFINES will expand to -DONE=1 -DTWO -DTHREE -DFOUR=4 -DFIVE
scons: `.' is up to date.
تغییریافته در نسخه 4.5: استفاده از تاپلها در برابر سایر انواع شفافسازی شد، اکنون نحوه رفتار در سراسر چهار تابع سازگار است.
env = Environment()
env.Append(CPPDEFINES=("MACRO1", "MACRO2"))
print("CPPDEFINES =", env['CPPDEFINES'])
env.Append(CPPDEFINES=[("MACRO3", "MACRO4")])
print("CPPDEFINES =", env['CPPDEFINES'])
print("CPPDEFINES will expand to", env.subst('$_CPPDEFFLAGS'))
$ scons -Q
CPPDEFINES = ('MACRO1', 'MACRO2')
CPPDEFINES = deque(['MACRO1', 'MACRO2', ('MACRO3', 'MACRO4')])
CPPDEFINES will expand to -DMACRO1 -DMACRO2 -DMACRO3=MACRO4
scons: `.' is up to date.
برای جزئیات بیشتر $CPPDEFINES را ببینید.
افزودن یک رشته val به یک متغیر ساخت از نوع دیکشنری، val را به عنوان کلید در دیکشنری و None را به عنوان مقدار آن وارد میکند. استفاده از نوع تاپل برای فراهم کردن یک جفت کلید-مقدار تنها برای مورد خاص $CPPDEFINES که در بالا توضیح داده شد کار میکند.
اگرچه بیشتر ترکیبهای انواع بدون نیاز به دانستن جزئیات کار میکنند، برخی ترکیبها معنادار نیستند و Python یک استثنا (exception) ایجاد میکند.
هنگام استفاده از env.Append برای تغییر متغیرهای ساختی که مشخصکننده مسیر هستند (طبق قرارداد، نام این متغیرها به PATH ختم میشود)، توصیه میشود مقادیر را به عنوان فهرستی از رشتهها اضافه کنید، حتی اگر فقط یک رشته تکی را اضافه میکنید. همین موضوع در مورد افزودن نام کتابخانهها به $LIBS نیز صدق میکند.
env.Append(CPPPATH=["#/include"])
همچنین ببینید: env.AppendUnique، env.Prepend و env.PrependUnique.
env.AppendENVPath(name, newpath, [envname, sep, delete_existing=False])
مسیرها تنها یکبار ظاهر خواهند شد. مسیرهای تکراری در newpath حذف میشوند و آخرین مورد برای حفظ ترتیب مسیر نگهداشته میشود. اگر delete_existing برابر با درست (true) باشد (پیشفرض)، موارد تکراری موجود پیش از الحاق حذف میشوند، در غیر این صورت، از موارد تکراری جدید صرفنظر میشود. هنگام مقایسهها، مسیرها نرمالسازی میشوند تا از بروز مشکلات ناشی از تفاوت بزرگی و کوچکی حروف (در فایلسیستمهای غیرحساس به حروف بزرگ و کوچک) و مسیرهای نسبی که ممکن است به همان دایرکتوری بازگردند جلوگیری شود. مقادیر ذخیرهشده توسط این فرآیند تغییر نمیکنند.
مثال:
print('before:', env['ENV']['INCLUDE'])
include_path = '/foo/bar:/foo'
env.AppendENVPath('INCLUDE', include_path)
print('after:', env['ENV']['INCLUDE'])
خروجی:
before: /foo:/biz after: /biz:/foo/bar:/foo
همچنین ببینید: env.PrependENVPath.
env.AppendUnique(key=val, [...], [delete_existing=False])
مثال:
env.AppendUnique(CCFLAGS='-g', FOO=['foo.yyy'])
همچنین ببینید: env.Append، env.Prepend و env.PrependUnique.
Builder(action, [arguments]), env.Builder(action, [arguments])
توجه داشته باشید که فرم فراخوانی env.Builder() متغیرهای ساخت را در تمام رشتههای آرگومان، از جمله آرگومان action، در زمان فراخوانی با استفاده از متغیرهای ساخت در محیط ساخت env که env.Builder از طریق آن فراخوانی شده است، بسط میدهد. فرم Builder بسط متغیرها را تا پس از فراخوانی واقعی شیء Builder به تعویق میاندازد.
CacheDir(cache_dir, custom_class=None), env.CacheDir(cache_dir, custom_class=None)
متد محیطی env.CacheDir حافظه موقت را تنها برای هدفهایی اعمال میکند که از طریق آن محیط ساخت خاص ساخته شده باشند. تابع سراسری CacheDir یک مقدار پیشفرض تعیین میکند که بر همه اهداف اعمال میشود مگر آنکه با فراخوانی مختص به محیط بازنویسی شود.
رفتار حافظه موقت را میتوان با ارسال زیرکلاسی از SCons.CacheDir.CacheDir به عنوان پارامتر اختیاری custom_class سفارشیسازی کرد. اگر حذف شود یا روی None تنظیم گردد، SCons از کلاس پیشفرض استفاده میکند.
هنگامی که حافظه موقت فعال است و scons نیاز دارد یک فایل مشتقشده را دوباره بسازد، ابتدا حافظه موقت را برای یک امضای ساخت (build signature) تطبیقپذیر بررسی میکند (که نشاندهنده ورودیها و کنشهای ساخت یکسان است). در صورت یافتن، فایل از حافظه موقت بازیابی میشود. در غیر این صورت، scons فایل را میسازد و رونوشتی از آن را تحت امضای ساخت خود در حافظه موقت ذخیره میکند.
به طور پیشفرض، scons هنگام برخورد موفق در حافظه موقت (cache hits)، عبارت Retrieved `file' from cache را گزارش میدهد. از گزینه --cache-show برای پنهان کردن دخالت حافظه موقت و نمایش رشته ساخت عادی در عوض آن، جهت یکدستی خروجی لاگ، استفاده کنید.
کش کردن را برای یک فراخوانی مشخص با گزینه --cache-disable غیرفعال کنید. برای مجاز کردن بازیابی اما جلوگیری از بهروزرسانیها، از --cache-readonly استفاده کنید.
گزینه --cache-force همه فایلهای مشتقشده را در حافظه موقت کپی میکند، حتی فایلهایی که از قبل وجود دارند. این کار به پر کردن یک حافظه موقت تازه یا بهروزرسانی آن پس از ساخت با بهروزرسانی حافظه موقت غیرفعال شده (--cache-disable یا --cache-readonly) کمک میکند.
از NoCache برای مستثنی کردن فایلهای خاص از قرارگیری در حافظه موقت استفاده کنید، مانند مواردی با ورودیها یا خروجیهای غیرقابلپیشبینی، یا فایلهای خروجی بیش از اندازه بزرگ.
SCons ابزارهای توکاری برای مدیریت حافظه موقت ارائه نمیدهد. شما باید پاکسازی (pruning)، انقضا، کنترل دسترسی و سایر وظایف نگهداری را به صورت دستی مدیریت کنید.
Clean(targets, files), env.Clean(targets, files)
متد مرتبط NoClean اولویت بالاتری دارد: هر هدفی که برای NoClean مشخص شود، پاکسازی نخواهد شد حتی اگر به عنوان پارامتر files به Clean داده شده باشد.
مثالها:
Clean('foo', ['bar', 'baz'])
Clean('dist', env.Program('hello', 'hello.c'))
Clean(['foo', 'bar'], 'something_else_to_clean')
ابزار SCons دایرکتوریها را مستقیماً به عنوان هدف ردیابی نمیکند - آنها در صورت نیاز ایجاد میشوند و در حالت پاکسازی معمولاً حذف نمیشوند. در این مثال، نصب پروژه یک زیردایرکتوری برای مستندات ایجاد میکند. فراخوانی Clean تضمین میکند که در صورت حذف نصب پروژه، این زیردایرکتوری حذف شود.
Clean(docdir, os.path.join(docdir, projectname))
env.Clone([key=val, ...])
مثال:
env2 = env.Clone() env3 = env.Clone(CCFLAGS='-g')
مشابه سازنده Environment، میتوان فهرستی از tools و یک toolpath را مشخص کرد:
def MyTool(env):
env['FOO'] = 'bar'
env4 = env.Clone(tools=['msvc', MyTool])
آرگومان کلیدواژهای parse_flags نیز شناخته میشود، تا ادغام آرگومانهای به سبک خط فرمان در متغیرهای ساخت مربوطه امکانپذیر شود (نگاه کنید به env.MergeFlags).
# create an environment for compiling programs that use wxWidgets wx_env = env.Clone(parse_flags='!wx-config --cflags --cxxflags')
آرگومان کلیدواژهای variables نیز شناخته میشود تا امکان مقداردهی (مجدد) متغیرهای ساخت از روی یک شیء Variables فراهم گردد.
تغییریافته در نسخه 4.8.0: پارامتر variables اضافه شد.
Command(target, source, action, [key=val, ...]), env.Command(target, source, action, [key=val, ...])
تابع Command آرگومانهای کلیدواژهای source_scanner و target_scanner را میپذیرد که برای تعیین اسکنرهای سفارشی برای مبداها یا اهداف مشخصشده به کار میروند. مقدار باید یک شیء Scanner باشد. برای نمونه، میتوان از شیء سراسری DirScanner استفاده کرد اگر هر یک از مبداها دایرکتوریهایی باشند که باید روی دیسک برای تغییرات فایلهایی که قبلاً در سایر Builderها یا فراخوانیهای توابع مشخص نشدهاند، اسکن شوند.
تابع Command همچنین آرگومانهای کلیدواژهای source_factory و target_factory را میپذیرد که برای مشخص کردن توابع کارخانهای جهت ساخت گرههای SCons از هر مبدا یا هدف مشخصشده به عنوان رشته استفاده میشوند. اگر هر مبدا یا هدفی از قبل شیء Node باشد، حتی در صورت تعیین یک کارخانه برای آنها، دگرگونی بیشتری نخواهند یافت. پیشفرض برای هر کدام، کارخانه Entry است.
این چهار آرگومان در صورت مشخص شدن، در ایجاد Builder به کار گرفته میشوند. سایر آرگومانهای کلیدواژهای مختص Builder به عنوان چنین مواردی شناخته نمیشوند. برای اطلاعات بیشتر درباره نحوه کار این آرگومانها در یک Builder، به بخش «اشیای سازنده» (Builder Objects) در صفحه راهنما مراجعه کنید.
هر آرگومان کلیدواژهای باقیمانده، هنگام فراخوانی به سازنده ایجادشده منتقل میشود و طبق آنچه در بخش «متدهای سازنده» (Builder Methods) در صفحه راهنما توضیح داده شده عمل میکند؛ به طور خلاصه: آرگومانهای شناختهشده معانی مشخص خود را دارند، در حالی که باقی آنها برای بازنویسی هر متغیر ساخت همنام موجود از محیط ساخت استفاده میشوند.
پارامتر action میتواند یک دستور خارجی (مشخصشده به عنوان یک رشته) یا یک شیء قابل فراخوانی Python باشد؛ برای اطلاعات کاملتر به بخش «اشیای اقدام» (Action Objects) در صفحه راهنما مراجعه کنید. همچنین توجه داشته باشید که قبل از رشته مشخصکننده دستور خارجی میتواند یک علامت اتساین (@) برای جلوگیری از چاپ دستور مربوطه، یا یک خط تیره (-) برای نادیده گرفتن وضعیت خروج (exit status) دستور خارجی قرار گیرد.
مثالها:
env.Command(
target='foo.out',
source='foo.in',
action="$FOO_BUILD < $SOURCES > $TARGET"
)
env.Command(
target='bar.out',
source='bar.in',
action=["rm -f $TARGET", "$BAR_BUILD < $SOURCES > $TARGET"],
ENV={'PATH': '/usr/local/bin/'},
)
import os
def rename(env, target, source):
os.rename('.tmp', target[0])
env.Command(
target='baz.out',
source='baz.in',
action=["$BAZ_BUILD < $SOURCES > .tmp", rename],
)
توجه داشته باشید که تابع Command معمولاً به طور پیشفرض فرض میکند که اهداف و/یا مبداهای مشخصشده فایل هستند، اگر بخش دیگری از پیکربندی نوع ورودیهای آنها را مشخص نکند. در صورت نیاز، میتوانید با استفاده از توابع Dir یا env.Dir صراحتاً مشخص کنید که گرههای هدف یا مبدا باید به عنوان دایرکتوری در نظر گرفته شوند.
مثالها:
env.Command('ddd.list', Dir('ddd'), 'ls -l $SOURCE > $TARGET')
env['DISTDIR'] = 'destination/directory'
env.Command(env.Dir('$DISTDIR')), None, make_distdir)
همچنین توجه داشته باشید که SCons معمولاً هر دایرکتوری لازم برای نگهداری یک فایل هدف را به طور خودکار ایجاد میکند، بنابراین معمولاً نیازی ندارید که دایرکتوریها را به صورت دستی ایجاد کنید.
Configure(env, [custom_tests, conf_dir, log_file, config_h]), env.Configure([custom_tests, conf_dir, log_file, config_h])
DebugOptions([json])
DebugOptions(json='#/build/output/scons_stats.json')
جدید در نسخهٔ 4.6.0.
Decider(function), env.Decider(function)
"content"
تغییریافته در نسخهٔ 4.1: نام تصمیمگیرنده به content تغییر یافت چرا که تابع هش اکنون قابل انتخاب است. نام پیشین، MD5، همچنان میتواند به عنوان مترادف استفاده شود، اما منسوخ شده است.
"content-timestamp"
تغییریافته در نسخهٔ 4.1: نام تصمیمگیرنده به content-timestamp تغییر یافت چرا که تابع هش اکنون قابل انتخاب است. نام پیشین، MD5-timestamp، همچنان میتواند به عنوان مترادف استفاده شود، اما منسوخ شده است.
"timestamp-newer"
"timestamp-match"
مثالها:
# Use exact timestamp matches by default.
Decider('timestamp-match')
# Use hash content signatures for any targets built
# with the attached construction environment.
env.Decider('content')
علاوه بر توابع از پیش موجود بالا، آرگومان function میتواند یک تابع Python باشد که شما ارائه میدهید. چنین تابعی باید چهار آرگومان زیر را بپذیرد:
dependency
target
prev_ni
repo_node
تابع function باید در صورتی که dependency از زمان آخرین ساخت target «تغییر» کرده باشد، مقداری را برگرداند که برابر با True ارزیابی شود (که نشان میدهد هدف باید بازسازی شود)، و در غیر این صورت مقداری که برابر با False ارزیابی شود (که نشان میدهد هدف نباید بازسازی شود). توجه داشته باشید که این تصمیمگیری میتواند با استفاده از هر معیار مناسبی انجام شود. نادیده گرفتن برخی یا همهٔ آرگومانهای تابع کاملاً طبیعی است.
مثال:
def my_decider(dependency, target, prev_ni, repo_node=None):
return not os.path.exists(str(target))
env.Decider(my_decider)
Default(target[, ...]), env.Default(target[, ...])
target میتواند یک یا چند رشته، فهرستی از رشتهها، یک NodeList برگشتی از یک Builder، یا None باشد. یک رشتهی target میتواند نام یک فایل یا دایرکتوری باشد، یا هدفی که پیشتر با فراخوانی Alias تعریف شده است (تعریف نام مستعار پس از آن همچنان نام مستعار را ایجاد میکند، اما به عنوان پیشفرض شناخته نخواهد شد). فراخوانیهای Default تجمیعی هستند. مقدار None برای target هرگونه فهرست اهداف پیشفرض موجود را پاک میکند؛ فراخوانیهای بعدی Default طبق معمول به فهرست اهداف پیشفرض (که اکنون خالی است) اضافه خواهند شد.
هر دو شکل این فراخوانی بر همان فهرست سراسری اهداف پیشفرض اثر میگذارند؛ متد محیط ساخت، بسط متغیرهای ساخت را روی اهداف اعمال میکند.
فهرست فعلی اهداف اضافهشده با استفاده از Default در فهرست DEFAULT_TARGETS در دسترس است (پایین را ببینید).
مثالها:
Default('foo', 'bar', 'baz')
env.Default(['a', 'b', 'c'])
hello = env.Program('hello', 'hello.c')
env.Default(hello)
DefaultEnvironment([key=value, ...])
در نخستین فراخوانی، آرگومانها مانند تابع Environment تفسیر میشوند. محیط پیشفرض یک شیء یگانه (singleton) است؛ فراخوانیهای بعدی DefaultEnvironment شیء ساختهشدهی پیشین را برمیگردانند، و هرگونه آرگومان کلیدواژهای بدون اعلام نادیده گرفته میشود.
محیط پیشفرض را میتوان پس از نمونهسازی، مشابه سایر محیطهای ساخت تغییر داد، هرچند ممکن است برخی از متدهای محیط ساخت در دسترس نباشند. تغییر محیط پیشفرض هیچ اثری بر سایر محیطهای ساخت، چه موجود و چه نوساخته، ندارد.
نیازی به فراخوانی صریح DefaultEnvironment نیست. SCons چنانچه تاکنون انجام نشده باشد، در زمان آغاز فاز ساخت، محیط پیشفرض را به طور خودکار نمونهسازی میکند. با این حال، فراخوانی صریح آن این فرصت را فراهم میآورد تا محتویات آن را تحت تأثیر قرار داده و بررسی کنید. به دلیل استفادههای داخلی، نمونهسازی حتی اگر به نظر برسد چیزی در سامانه ساخت از آن استفاده نمیکند نیز رخ میدهد.
اگر فایلهای SConscript پروژه از توابع سراسری یا Builderها استفاده نمیکنند، ممکن است با فراخوانی DefaultEnvironment با یک فهرست ابزار خالی (DefaultEnvironment(tools=[])) سود اندکی در عملکرد حاصل شود. این کار از هزینه مقداردهی اولیهی ابزارها برای محیط پیشفرض جلوگیری میکند، که عمدتاً در مجموعهی آزمون که scons در آن به طور مکرر در یک بازه زمانی کوتاه اجرا میشود اهمیت دارد.
Depends(target, dependency), env.Depends(target, dependency)
مثال:
env.Depends('foo', 'other-input-file-for-foo')
mylib = env.Library('mylib.c')
installed_lib = env.Install('lib', mylib)
bar = env.Program('bar.c')
# Arrange for the library to be copied into the installation
# directory before trying to build the "bar" program.
# (Note that this is for example only. A "real" library
# dependency would normally be configured through the $LIBS
# and $LIBPATH variables, not using an env.Depends() call.)
env.Depends(bar, installed_lib)
env.Detect(progs)
env.Dictionary([var, ...], [as_dict=])
مثال:
cvars = env.Dictionary()
cc_values = env.Dictionary('CC', 'CCFLAGS', 'CCCOM')
نکته
شیء بازگرداندهشده توسط env.Dictionary باید به عنوان یک نمای فقطخواندنی به متغیرهای ساخت در نظر گرفته شود. برخی از متغیرهای ساخت نیازمند رسیدگی داخلی ویژهای هستند، و تغییر آنها از طریق شیء env.Dictionary میتواند آن سازوکار را دور زده و باعث ناهماهنگی در دادهها شود. کاربرد اصلی env.Dictionary برای مقاصد عیبیابی است - این متد به طور گسترده در آزمونها دقیقاً به این دلیل استفاده میشود که رسیدگی ویژه را دور میزند تا رفتار سامانه قابل راستیآزمایی باشد.
Dir(name, [directory]), env.Dir(name, [directory])
اگر name یک مسیر منفرد باشد، گره متناظر بازگردانده میشود. اگر name یک فهرست باشد، SCons فهرستی از گرهها را بازمیگرداند. متغیرهای ساخت در name بسط داده میشوند.
گرههای دایرکتوری را میتوان در هر جایی که یک رشته به عنوان نام دایرکتوری به یک متد سازنده (Builder) یا تابع تحویل داده میشود، استفاده کرد. گرههای دایرکتوری دارای مشخصهها و متدهایی هستند که در موقعیتهای بسیاری کاربردیاند؛ برای اطلاعات بیشتر بخش "Filesystem Nodes" در صفحهٔ راهنما را ببینید.
env.Dump([var, ...], [format=TYPE])
رشتهٔ اختیاری format قالب سریالسازی را تعیین میکند:
pretty
json
تغییر یافته در 4.9.0: بیش از یک key میتواند مشخص شود. رشتهٔ بازگرداندهشده همواره مانند یک dict (یا معادل آن در سایر قالبها) خواهد بود؛ پیش از این، یک کلید تکی فقط مقدار را سریالسازی میکرد، نه کلید را به همراه مقدار.
مثالها: این SConstruct
env = Environment()
print(env.Dump('CCCOM'))
print(env.Dump('CC', 'CCFLAGS', format='json'))
چیزی شبیه به این چاپ خواهد کرد:
{'CCCOM': '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES'}
{
"CC": "gcc",
"CCFLAGS": []
}
در حالی که این SConstruct:
env = Environment() print(env.Dump())
چیزی شبیه به این چاپ خواهد کرد:
{ 'AR': 'ar',
'ARCOM': '$AR $ARFLAGS $TARGET $SOURCES\n$RANLIB $RANLIBFLAGS $TARGET',
'ARFLAGS': ['r'],
'AS': 'as',
'ASCOM': '$AS $ASFLAGS -o $TARGET $SOURCES',
'ASFLAGS': [],
...
EnsurePythonVersion(major, minor)
مثال:
EnsurePythonVersion(2,2)
EnsureSConsVersion(major, minor, [revision])
مثالها:
EnsureSConsVersion(0,14) EnsureSConsVersion(0,96,90)
Environment([key=value, ...]), env.Environment([key=value, ...])
Execute(action, [actionargs ...]), env.Execute(action, [actionargs ...])
Execute(Copy('file.out', 'file.in'))
دستور Execute کنش خود را فوراً، به عنوان بخشی از مرحلهٔ خواندن SConscript انجام میدهد. در فراخوانی Execute هیچ منبع یا هدفی اعلان نمیشود، بنابراین هر شیئی که توسط آن دستکاری شود، به عنوان بخشی از گراف وابستگی SCons ردیابی نخواهد شد. در مثال بالا، نه file.out و نه file.in اشیاء ردیابیشده نخواهند بود.
Execute مقدار خروج دستور یا مقدار بازگشتی تابع Python را برمیگرداند. اگر action اجراشده ناموفق باشد (با یک مقدار غیرصفر خارج شود یا مقداری غیرصفر برگرداند)، scons پیام خطایی چاپ میکند، با این وجود ساخت را برای چنین شکستی بهطور خودکار متوقف نمیکند. اگر میخواهید فرآیند ساخت در واکنش به شکست فراخوانی Execute متوقف شود، باید صراحتاً مقدار بازگشتی غیرصفر را بررسی کنید:
if Execute("mkdir sub/dir/ectory"):
# The mkdir failed, don't try to build.
Exit(1)
Exit([value])
Export([vars...], [key=value...]), env.Export([vars...], [key=value...])
یک آرگومان vars همچنین میتواند یک دیکشنری یا آرگومانهای کلیدواژهای جداگانه باشد؛ طبق قواعد نحوی Python، آرگومانهای کلیدواژهای باید پس از هرگونه آرگومان غیرکلیدواژهای بیایند. شکل دیکشنری/کلیدواژهای را میتوان برای نگاشت نام محلی یک متغیر به نامی متفاوت جهت استفاده برای وارد کردنها به کار برد. برای نمایشی از این نحو، مثالها را ببینید.
فراخوانیهای Export تجمعی هستند. مشخص کردن متغیری که پیشتر صادر شده است، مقدار قبلی آن را در مجموعه جایگزین خواهد کرد. هم متغیرهای محلی و هم متغیرهای سراسری را میتوان صادر کرد.
برای استفاده از یک متغیر صادرشده، یک SConscript باید Import را فراخوانی کند تا آن را به دامنهٔ خود وارد کند. وارد کردن، یک ارجاع اضافی به شیئی ایجاد میکند که در ابتدا صادر شده بود؛ بنابراین اگر آن شیء تغییرپذیر (mutable) باشد، تغییرات اعمالشده برای سایر استفادهکنندگان آن شیء نمایان خواهد بود.
مثالها:
env = Environment()
# Make env available for all SConscript files to Import().
Export("env")
package = 'my_name'
# Make env and package available for all SConscript files:.
Export("env", "package")
# Make env and package available for all SConscript files:
Export(["env", "package"])
# Make env available using the name debug:
Export(debug=env)
# Make env available using the name debug:
Export({"debug": env})
توجه داشته باشید که تابع SConscript همچنین از آرگومان exports پشتیبانی میکند که امکان صادر کردن یک یا چند متغیر را (تنها) به فایلهای SConscript فراخوانیشده توسط آن فراخوانی فراهم میکند. برای جزئیات بیشتر به توضیحات آن تابع مراجعه کنید.
File(name, [directory]), env.File(name, [directory])
اگر name یک نام مسیر تکی باشد، گره متناظر بازگردانده میشود. اگر name یک فهرست باشد، SCons فهرستی از گرهها را بازمیگرداند. متغیرهای ساخت (Construction variables) در name بسط داده میشوند.
از File Nodeها میتوان در هر جایی که یک رشته به عنوان نام فایل به یک متد یا تابع Builder داده میشود استفاده کرد. File Nodeها ویژگیها و متدهایی دارند که در بسیاری از شرایط مفید هستند؛ برای اطلاعات بیشتر بخش "Filesystem Nodes" در این صفحهٔ راهنما را ببینید.
FindFile(file, dirs), env.FindFile(file, dirs)
مثال:
# Searches for 'foo' in 'dir1' and 'dir2', returning the node if found
foo = env.FindFile('foo', ['dir1', 'dir2'])
FindInstalledFiles(), env.FindInstalledFiles()
مثال:
Install('/bin', ['executable_a', 'executable_b'])
# Returns the file node list
# ['/bin/executable_a', '/bin/executable_b']
FindInstalledFiles()
Install('/lib', ['some_library'])
# Returns the file node list
# ['/bin/executable_a', '/bin/executable_b', '/lib/some_library']
FindInstalledFiles()
FindPathDirs(variable)
استفاده از FindPathDirs عموماً نسبت به نوشتن path_function شخصی ترجیح داده میشود، زیرا موارد معمول پویش در SCons را به درستی و به طور کارآمد مدیریت میکند: (۱) هنگامی که از یک دایرکتوری متغیر (variant directory) استفاده میشود تمام دایرکتوریهای مناسب را از درختهای منبع، و هنگامی که Repository یا گزینهٔ -Y/--repository فعال است از مخازن برمیگرداند. (۲) تشخیص میدهد چه زمانی مقادیر مختلف variable به فهرست دایرکتوری یکسانی منتهی میشوند و به جای پویش مجدد همان دایرکتوریها، از آن نتیجه دوباره استفاده میکند که از انجام کارهای تکراری جلوگیری مینماید.
مثال:
def my_scan(node, env, path, arg):
# Code to scan file contents goes here...
return include_files
scanner = Scanner(
name='myscanner', function=my_scan, path_function=FindPathDirs('MYPATH')
)
FindSourceFiles([node]), env.FindSourceFiles([node])
مثال:
Program('src/main_a.c')
Program('src/main_b.c')
Program('main_c.c')
# returns ['main_c.c', 'src/main_a.c', 'SConstruct', 'src/main_b.c']
FindSourceFiles()
# returns ['src/main_b.c', 'src/main_a.c' ]
FindSourceFiles('src')
توجه داشته باشید که فایلهای پشتیبان ساخت موجود در درخت (مانند SConstruct در مثال بالا) نیز بازگردانده میشوند.
Flatten(sequence), env.Flatten(sequence)
مثالها:
foo = Object('foo.c')
bar = Object('bar.c')
# از آنجا که `foo' و `bar' لیستهای بازگرداندهشده توسط سازنده ()Object هستند،
# `objects' لیستی شامل لیستهای تودرتو خواهد بود:
objects = ['f1.o', foo, 'f2.o', bar, 'f3.o']
# ارسال چنین لیستی به سازندهای دیگر مشکلی ندارد زیرا
# سازنده لیست را به طور خودکار مسطح میکند:
Program(source = objects)
# اگر نیاز دارید لیست را مستقیماً با استفاده از Python دستکاری کنید، باید
# خودتان ()Flatten را فراخوانی کنید، یا به شکل دیگری لیستهای تودرتو را مدیریت نمایید:
for object in Flatten(objects):
print(str(object))
GetBuildFailures()
.node گرهای که هنگام رخ دادن شکست ساخت، در حال ساخته شدن بود.
.status وضعیت خروج عددی بازگرداندهشده توسط دستور یا تابع Python که هنگام تلاش برای ساخت Node مشخصشده شکست خورد.
.errstr رشته خطای SCons که شکست ساخت را توصیف میکند. (این اغلب یک پیام عمومی مانند "Error 2" است تا نشان دهد دستور اجرا شده با وضعیت ۲ خارج شده است.)
.filename نام فایل یا دایرکتوری که در واقع باعث بروز شکست شده است. این مقدار ممکن است با ویژگی .node متفاوت باشد. به عنوان مثال، اگر تلاشی برای ساخت هدفی به نام sub/dir/target شکست بخورد زیرا دایرکتوری sub/dir نتوانست ایجاد شود، در این صورت ویژگی .node برابر sub/dir/target خواهد بود اما ویژگی .filename برابر sub/dir خواهد بود.
.executor شیء Executor در SCons برای Node هدفی که در حال ساخته شدن بود. این میتواند برای بازیابی محیط ساخت مورد استفاده برای اقدام شکستخورده به کار رود.
.action شیء واقعی Action در SCons که شکست خورده است. این شیء یک اقدام مشخص از میان فهرست اقدامات ممکنی خواهد بود که قرار بود برای ساخت هدف اجرا شوند.
.command دستور گسترشیافته واقعی که اجرا شد و شکست خورد، پس از بسط متغیرهای ساخت $TARGET، $SOURCE و سایر متغیرهای ساخت.
توجه داشته باشید که تابع GetBuildFailures همواره تا زمانی که هیچ شکست ساختی رخ نداده باشد یک لیست خالی برمیگرداند، به این معنی که GetBuildFailures در حین خوانده شدن فایلهای SConscript همیشه یک لیست خالی برمیگرداند. کاربرد اصلی در نظر گرفتهشده برای آن در توابعی است که با ارسال به تابع استاندارد atexit.register در Python، پیش از خروج SCons اجرا خواهند شد. مثال:
import atexit
def print_build_failures():
from SCons.Script import GetBuildFailures
for bf in GetBuildFailures():
print("%s failed: %s" % (bf.node, bf.errstr))
atexit.register(print_build_failures)
GetBuildPath(file, [...]), env.GetBuildPath(file, [...])
GetLaunchDir()
GetOption(name), env.GetOption(name)
| نام استعلام | آرگومان خط فرمان | یادداشتها |
| cache_debug | --cache-debug | رشته (نام فایل) |
| cache_disable | --cache-disable, --no-cache | بولی |
| cache_force | --cache-force, --cache-populate | بولی |
| cache_readonly | --cache-readonly | بولی |
| cache_show | --cache-show | بولی |
| clean | -c, --clean, --remove | بولی |
| climb_up | -D, -U, -u, --up, --search_up | عدد صحیح. 1 یعنی -u داده شده است، 2 یعنی -D، 3 یعنی -U است. |
| config | --config | رشته |
| debug | --debug | لیست |
| directory | -C, --directory | لیست (مسیرها) |
| diskcheck | --diskcheck | لیست |
| duplicate | --duplicate | رشته |
| enable_virtualenv | --enable-virtualenv | بولی |
| experimental | --experimental | مجموعه. از نسخه 4.2. |
| file | -f, --file, --makefile, --sconstruct | لیست (نام فایلها) |
| hash_chunksize | --hash-chunksize | عدد صحیح. جایگزین md5_chunksize شده است. از نسخه 4.2 |
| hash_format | --hash-format | رشته. از نسخه 4.2 |
| help | -h, --help | بولی |
| ignore_errors | -i, --ignore-errors | بولی |
| ignore_virtualenv | --ignore-virtualenv | بولی |
| implicit_cache | --implicit-cache | بولی |
| implicit_deps_changed | --implicit-deps-changed | بولی |
| implicit_deps_unchanged | --implicit-deps-unchanged | بولی |
| include_dir | -I, --include-dir | لیست (مسیرها) |
| install_sandbox | --install-sandbox | رشته (نام فایل). تنها در صورتی در دسترس است که ابزار install فراخوانی شده باشد |
| keep_going | -k, --keep-going | بولی |
| max_drift | --max-drift | عدد صحیح |
| md5_chunksize | --hash-chunksize | عدد صحیح. با hash_chunksize جایگزین شده است. از نسخه 4.2 منسوخ شده است |
| no_exec | -n, --no-exec, --just-print, --dry-run, --recon | بولی |
| no_progress | -Q | بولی |
| num_jobs | -j, --jobs | عدد صحیح |
| package_type | --package-type | رشته. تنها در صورتی در دسترس است که ابزار packaging فراخوانی شده باشد |
| profile_file | --profile | رشته (نام فایل) |
| question | -q, --question | بولی |
| random | --random | بولی |
| repository | -Y, --repository, --srcdir | لیست (مسیرها) |
| silent | -s, --silent, --quiet | بولی |
| site_dir | --site-dir, --no-site-dir | رشته (مسیر)، False یا None |
| stack_size | --stack-size | عدد صحیح |
| taskmastertrace_file | --taskmastertrace | رشته (نام فایل) |
| tree_printers | --tree | لیست |
| warn | --warn, --warning | لیست |
GetSConsVersion()
Glob(pattern, [ondisk=True, source=False, strings=False, exclude=None]), env.Glob(pattern, [ondisk=True, source=False, strings=False, exclude=None])
pattern میتواند شامل نویسههای عام شل با سبک POSIX برای تطابق باشد:
| الگو | مفهوم |
| * | با همهچیز مطابقت مییابد |
| ? | با هر نویسهٔ تکی مطابقت مییابد |
| [seq] | با هر نویسهای در seq مطابقت مییابد (میتواند یک فهرست یا یک بازه باشد). |
| [!seq] | با هر نویسهای خارج از seq مطابقت مییابد |
برای یک تطابق دقیق، نویسهٔ عام را در قلاب قرار دهید تا از رفتار عادی آن صرفنظر شود. برای مثال، '[?]' با نویسهٔ '?' مطابقت مییابد.
با نامهای فایلی که با نقطه شروع میشوند بهطور خاص رفتار میشود - آنها فقط با الگوهایی مطابقت مییابند که با یک نقطه آغاز شوند (یا بلافاصله پس از یک نویسهٔ جداکنندهٔ مسیر یا ممیز، یک نقطه داشته باشند)، و توسط نویسههای عام مطابقت داده نمیشوند. تطابقهای نویسهٔ عام همچنین شامل جداکنندههای دایرکتوری نمیشوند.
Glob مخازن (به تابع Repository مراجعه کنید) و دایرکتوریهای منبع (به تابع VariantDir مراجعه کنید) را تشخیص میدهد و اگر یک Node منطبق در هر کجای مخزن یا دایرکتوری منبع متناظر پیدا شود، یک Node (یا در صورت پیکربندی، رشته) منطبق در دایرکتوری محلی (SConscript) برمیگرداند.
اگر آرگومان اختیاری ondisk نادرست (false) ارزیابی شود، جستجو برای تطابقها روی دیسک غیرفعال میشود و تنها تطابقهای حاصل از Nodeهای File یا Dir که از قبل پیکربندی شدهاند بازگردانده میشوند. مقدار پیشفرض این است که Nodeهای حاصل از تطابق روی دیسک نیز برگردانده شوند.
اگر آرگومان اختیاری source درست (true) ارزیابی شود، و دایرکتوری محلی یک دایرکتوری مشتق (variant directory) باشد، آنگاه Glob بهجای دایرکتوری محلی، Nodeها را از دایرکتوری منبع متناظر برمیگرداند.
اگر آرگومان اختیاری strings درست (true) ارزیابی شود، Glob تطابقها را بهجای Nodeها در قالب رشته برمیگرداند. رشتههای برگشتی نسبت به دایرکتوری محلی (SConscript) خواهند بود. (توجه داشته باشید که گرچه این امر ممکن است انجام دستکاریهای دلخواه روی نامهای فایل را آسانتر کند، زمینهای را که SCons در Node نگه میداشت از بین میبرد؛ بنابراین اگر رشتههای برگشتی به یک فایل SConscript دیگر فرستاده شوند، هرگونه تبدیل Node در آنجا نسبت به دایرکتوری آن SConscript خواهد بود، نه نسبت به دایرکتوری SConscript اصلی.)
آرگومان اختیاری exclude میتواند روی یک الگو یا فهرستی از الگوها تنظیم شود که فایلها یا دایرکتوریها را برای حذف از فهرست تطابق شرح میدهند. عناصری که حداقل با یکی از الگوهای مشخصشده مطابقت داشته باشند حذف خواهند شد. این الگوها از همان ساختار نحوی pattern استفاده میکنند.
مثالها:
Program("foo", Glob("*.c"))
Zip("/tmp/everything", Glob(".??*") + Glob("*"))
sources = Glob("*.cpp", exclude=["os_*_specific_*.cpp"]) \
+ Glob("os_%s_specific_*.cpp" % currentOS)
Help(text, append=False, local_only=False), env.Help(text, append=False, local_only=False)
در نخستین فراخوانی Help، اگر append برابر False (پیشفرض) باشد، هرگونه متن راهنمای موجود دور ریخته میشود. متن راهنمای پیشفرض شامل راهنمای خودِ دستور scons بهعلاوهٔ راهنماهای جمعآوریشده از فراخوانیهای محلی پروژهٔ AddOption است. این همان راهنمایی است که اگر Help هرگز فراخوانی نشده باشد، چاپ میشود. اگر append برابر True باشد، text به متن راهنمای موجود الحاق میشود. اگر local_only نیز True باشد (پیشفرض False است)، راهنمای محلی پروژه از فراخوانیهای AddOption در پیام راهنما حفظ میشود اما راهنمای دستور scons حذف خواهد شد.
فراخوانیهای بعدی Help آرگومانهای کلیدواژهای append و local_only را نادیده میگیرند و همواره به متن راهنمای موجود اضافه میکنند.
در نسخهٔ 4.6.0 تغییر یافت: local_only اضافه شد.
Ignore(target, dependency), env.Ignore(target, dependency)
از Ignore همچنین میتوان برای حذف یک هدف از ساخت پیشفرض استفاده کرد؛ با مشخص کردن دایرکتوریای که هدف در آن ساخته میشود بهعنوان target و فایلی که میخواهید از انتخاب برای ساخت کنار گذاشته شود بهعنوان dependency. توجه داشته باشید که این کار تنها هدف را از الگوریتم انتخاب هدف پیشفرض حذف میکند: اگر آن فایل وابستگی شیء دیگری باشد که در حال ساخت است، SCons همچنان آن را طبق روال معمول میسازد. مثالهای سوم و چهارم در ادامه را ببینید.
مثالها:
env.Ignore('foo', 'foo.c')
env.Ignore('bar', ['bar1.h', 'bar2.h'])
env.Ignore('.', 'foobar.obj')
env.Ignore('bar', 'bar/foobar.obj')
Import(vars...), env.Import(vars...)
اگر متغیرِ واردشده تغییرپذیر باشد، تغییرات اعمالشده به صورت محلی در شیئی که متغیر به آن مقید شده است بازتاب خواهد یافت. این امر به فایلهای SConscript فرعی اجازه میدهد تا به عنوان مثال در شکلدهی یک محیط ساخت مشارکت داشته باشند.
مثالها:
Import("env")
Import("env", "variable")
Import(["env", "variable"])
Import("*")
Literal(string), env.Literal(string)
Local(targets), env.Local(targets)
env.MergeFlags(arg, [unique])
اگر unique برابر با true (پیشفرض) باشد، مقادیر تکراری حفظ نمیشوند. در صورت وجود موارد تکراری، هر نام متغیر ساختی که به PATH ختم شود، چپترین مقدار را نگه میدارد تا ترتیب جستجوی مسیر تغییر نکند. همهٔ دیگر متغیرهای ساخت، راستترین مقدار را نگه میدارند. اگر unique برابر با false باشد، مقادیر حتی در صورت تکراری بودن الحاق میشوند.
مثالها:
# Add an optimization flag to $CCFLAGS.
env.MergeFlags({'CCFLAGS': '-O3'})
# Combine the flags returned from running pkg-config with an optimization
# flag and merge the result into the construction variables.
env.MergeFlags(['!pkg-config gtk+-2.0 --cflags', '-O3'])
# Combine an optimization flag with the flags returned from running pkg-config
# for two distinct packages and merge into the construction variables.
env.MergeFlags(
[
'-O3',
'!pkg-config gtk+-2.0 --cflags --libs',
'!pkg-config libpng12 --cflags --libs',
]
)
NoCache(target, ...), env.NoCache(target, ...)
چندین فایل را میتوان یا به عنوان آرگومانهای مجزا برای متد NoCache یا به صورت یک لیست مشخص کرد. NoCache همچنین مقدار بازگشتی هر یک از متدهای سازنده (Builder) در محیط ساخت را میپذیرد.
فراخوانی NoCache روی دایرکتوریها و دیگر انواع گرههای غیرفایلی هیچ اثری ندارد، زیرا تنها گرههای فایلی در حافظه پنهان ذخیره میشوند.
مثالها:
NoCache('foo.elf')
NoCache(env.Program('hello', 'hello.c'))
NoClean(targets, ...), env.NoClean(targets, ...)
فراخوانی NoClean برای یک هدف، بر فراخوانی Clean برای همان هدف اولویت دارد؛ بنابراین هر هدفی که به هر دو تابع داده شود در حالت پاکسازی حذف نخواهد شد.
مثالها:
NoClean('foo.elf')
NoClean(env.Program('hello', 'hello.c'))
env.ParseConfig(command, [function, unique])
command با استفاده از محیط اجرای SCons (یعنی متغیر ساخت $ENV در محیط ساخت فعلی) اجرا میشود. اگر command برای عملکرد صحیح به اطلاعات بیشتری نیاز داشته باشد، آن اطلاعات باید در محیط اجرا تنظیم شوند. برای مثال، pkg-config ممکن است به تنظیم یک مقدار سفارشی در متغیر محیطی PKG_CONFIG_PATH نیاز داشته باشد.
env.MergeFlags برای توزیع خروجی تولیدشده توسط command بین متغیرهای ساخت مناسب، باید ساختار آن را درک کند. env.MergeFlags برای انجام این پردازش از تابع مجزایی استفاده میکند - برای جزئیات بیشتر، از جمله جدول گزینهها و متغیرهای ساخت متناظر، به env.ParseFlags مراجعه کنید. برای ارائه پردازش سفارشی روی خروجی command، میتوانید یک function دلخواه تعریف کنید که باید سه آرگومان را بپذیرد: محیط ساخت برای تغییر، یک آرگومان رشتهای حاوی خروجی حاصل از اجرای command، و پرچم اختیاری unique.
ParseDepends(filename, [must_exist, only_one]), env.ParseDepends(filename, [must_exist, only_one])
به طور پیشفرض، عدم وجود filename خطا محسوب نمیشود. آرگومان اختیاری must_exist میتواند روی True تنظیم شود تا در صورتی که فایل وجود نداشته باشد یا به هر دلیلی غیرقابل دسترسی باشد، SCons یک استثنا صادر کند.
آرگومان اختیاری only_one میتواند روی True تنظیم شود تا در صورتی که فایل حاوی اطلاعات وابستگی برای بیش از یک هدف باشد، SCons یک استثنا صادر کند. این قابلیت میتواند یک اعتبارسنجی اولیه برای فایلهایی فراهم کند که برای نمونه قرار است توسط پرچم gcc -M تولید شوند؛ پرچمی که معمولاً باید اطلاعات وابستگی را فقط برای یک فایل خروجی در فایل متناظر .d بنویسد.
filename و تمامی فایلهای فهرستشده در آن نسبت به دایرکتوری فایل SConscript فراخواننده تابع ParseDepends تفسیر خواهند شد.
env.ParseFlags(flags, ...)
اگر نخستین نویسه در هر رشته یک علامت تعجب (!) باشد، باقیمانده رشته به عنوان یک دستور اجرا میشود و خروجی حاصل از دستور به عنوان پرچمهای خط فرمان زنجیره ابزار GCC تجزیه شده و به دیکشنری حاصل افزوده میشود. این قابلیت میتواند برای فراخوانی دستورهای *-config رایج در محیط برنامهنویسی POSIX (برای نمونه، pkg-config) استفاده شود. توجه داشته باشید که چنین دستوری با استفاده از محیط اجرای SCons اجرا میشود؛ در صورتی که دستور به اطلاعات بیشتری نیاز داشته باشد، آن اطلاعات باید صریحاً ارائه شود. برای جزئیات بیشتر به ParseConfig مراجعه کنید.
مقادیر پرچمها بر اساس پیشوند یافتشده ترجمه شده و به متغیرهای ساخت زیر افزوده میشوند:
-arch CCFLAGS, LINKFLAGS -D CPPDEFINES -framework FRAMEWORKS -frameworkdir= FRAMEWORKPATH -fmerge-all-constants CCFLAGS, LINKFLAGS -fopenmp CCFLAGS, LINKFLAGS -fsanitize CCFLAGS, LINKFLAGS -include CCFLAGS -imacros CCFLAGS -isysroot CCFLAGS, LINKFLAGS -isystem CCFLAGS -iquote CCFLAGS -idirafter CCFLAGS -I CPPPATH -l LIBS -L LIBPATH -mno-cygwin CCFLAGS, LINKFLAGS -mwindows LINKFLAGS -openmp CCFLAGS, LINKFLAGS -pthread CCFLAGS, LINKFLAGS -std= CFLAGS -stdlib= CXXFLAGS -Wa, ASFLAGS, CCFLAGS -Wl,-rpath= RPATH -Wl,-R, RPATH -Wl,-R RPATH -Wl, LINKFLAGS -Wp, CPPFLAGS - CCFLAGS + CCFLAGS, LINKFLAGS
هر رشته دیگری که به گزینهها مرتبط نباشد، به عنوان نام کتابخانهها در نظر گرفته شده و به متغیر ساخت $LIBS اضافه میشود.
مثالها (که همگی نتیجه یکسانی ایجاد میکنند):
dict = env.ParseFlags('-O2 -Dfoo -Dbar=1')
dict = env.ParseFlags('-O2', '-Dfoo', '-Dbar=1')
dict = env.ParseFlags(['-O2', '-Dfoo -Dbar=1'])
dict = env.ParseFlags('-O2', '!echo -Dfoo -Dbar=1')
Platform(plat), env.Platform(plat)
مثال:
env = Environment(platform=Platform('win32'))
هنگامی که به عنوان متدی از یک محیط فراخوانی شود، شیء پلتفرم مشخصشده توسط plat را برای بهروزرسانی آن محیط فراخوانی میکند.
env.Platform('posix')
برای جزئیات بیشتر به بخش "Construction Environments" در صفحه راهنما مراجعه کنید.
Precious(target, ...), env.Precious(target, ...)
env.Prepend(key=val, [...])
مثال:
env.Prepend(CCFLAGS='-g ', FOO=['foo.yyy'])
همچنین ببینید: env.Append، env.AppendUnique و env.PrependUnique.
env.PrependENVPath(name, newpath, [envname, sep, delete_existing=True])
مسیرها تنها یک بار ظاهر خواهند شد. مسیرهای تکراری در newpath حذف میشوند و نخستین رخداد برای حفظ ترتیب مسیر نگه داشته میشود. اگر delete_existing درست باشد (پیشفرض)، تکرارهای موجود پیش از افزودن به ابتدا حذف میشوند؛ در غیر این صورت، از تکرارهای جدید صرفنظر میشود. در طول مقایسهها، مسیرها نرمالسازی میشوند تا از بروز مشکل با تفاوت حروف بزرگ و کوچک (در سامانههای فایلی غیرحساس به بزرگی و کوچکی حروف) و مسیرهای نسبی که ممکن است به همان دایرکتوری اشاره کنند، جلوگیری شود. مقادیر ذخیرهشده توسط این فرآیند تغییر نمیکنند.
مثال:
print('before:', env['ENV']['INCLUDE'])
include_path = '/foo/bar:/foo'
env.PrependENVPath('INCLUDE', include_path)
print('after:', env['ENV']['INCLUDE'])
نتیجه میدهد:
before: /biz:/foo after: /foo/bar:/foo:/biz
همچنین ببینید env.AppendENVPath.
env.PrependUnique(key=val, [...], [delete_existing=False])
مثال:
env.PrependUnique(CCFLAGS='-g', FOO=['foo.yyy'])
همچنین ببینید env.Append، env.AppendUnique و env.Prepend.
Progress(callable, [interval]), Progress(string, [interval, file, overwrite]), Progress(list_of_strings, [interval, file, overwrite])
اگر نخستین آرگومان تعیینشده یک فراخوانپذیر (callable) در Python باشد (یک تابع یا شیئی که متد __call__ دارد)، تابع به ازای هر interval بار ارزیابی یک گره، یک بار فراخوانی میشود (پیشفرض 1 است). گره ارزیابیشده به عنوان تنها آرگومان به فراخوانپذیر ارسال میشود. (برای سازگاری با آینده، ایده خوبی است که *args و **kwargs را نیز به عنوان آرگومان به امضای تابع یا متد خود اضافه کنید. این کار در صورتی که SCons در آینده واسط را برای فراخوانی تابع با آرگومانهای اضافی تغییر دهد، از شکستهشدن کد جلوگیری میکند.)
نمونهای از یک تابع پیشرفت سفارشی ساده که به ازای هر ۱۰ گره، رشتهای شامل نام گره را چاپ میکند:
def my_progress_function(node, *args, **kwargs):
print('Evaluating node %s!' % node)
Progress(my_progress_function, interval=10)
نمونهای پیچیدهتر از یک شیء سفارشی نمایش پیشرفت که به ازای هر ۱۰۰ گره ارزیابیشده، رشتهای شامل یک شمارنده را چاپ میکند. به استفاده از \r (بازگشت به ابتدای سطر) در انتها توجه کنید تا رشته خودش را روی صفحه نمایش بازنویسی کند:
import sys
class ProgressCounter(object):
count = 0
def __call__(self, node, *args, **kw):
self.count += 100
sys.stderr.write('Evaluated %s nodes\r' % self.count)
Progress(ProgressCounter(), interval=100)
اگر آرگومان نخست برای Progress یک رشته یا فهرستی از رشتهها باشد، به عنوان متنی در نظر گرفته میشود که به ازای هر interval گره ارزیابیشده نمایش داده شود. اگر آرگومان نخست فهرستی از رشتهها باشد، آنگاه هر رشته در فهرست به صورت چرخشی به ازای هر interval گره ارزیابیشده نمایش داده خواهد شد.
پیشفرض، چاپ رشته در خروجی استاندارد است. یک جریان خروجی جایگزین را میتوان با آرگومان کلیدواژهای file مشخص کرد، که فراخواننده باید آن را از قبل بازشده ارسال کند.
کد زیر مجموعهای از نقطهها را در خروجی خطا چاپ میکند، یک نقطه به ازای هر ۱۰۰ گره ارزیابیشده:
import sys
Progress('.', interval=100, file=sys.stderr)
اگر رشته دقیقاً حاوی زیررشته $TARGET; باشد، با گره جایگزین خواهد شد. توجه داشته باشید که به دلایل کارایی، این not یک جایگزینی معمول متغیر SCons نیست، بنابراین نمیتوانید از متغیرهای دیگر یا از آکولادها استفاده کنید. مثال زیر نام هر گره ارزیابیشده را چاپ میکند، با استفاده از بازگشت به ابتدای سطر (\r) تا هر خط توسط خط بعدی بازنویسی شود، و آرگومان کلیدواژهای overwrite (پیشفرض False) برای اطمینان از اینکه نام فایل چاپشدهٔ قبلی با نویسههای فاصله بازنویسی شود:
import sys
Progress('$TARGET\r', overwrite=True)
میتوان از فهرستی از رشتهها برای پیادهسازی یک نشانگر چرخان (spinner) بر روی صفحه نمایش کاربر به شرح زیر استفاده کرد که به ازای هر پنج گره ارزیابیشده تغییر میکند:
Progress(['-\r', '\\\r', '|\r', '/\r'], interval=5)
Pseudo(target, ...), env.Pseudo(target, ...)
Pseudo ممکن است همراه با یک فراخوانی سازنده (مانند Command) مفید باشد که هیچ هدف فیزیکی تولید نمیکند، و اگر هدف بهطور تصادفی از قبل وجود داشته باشد، رفتار آن نادرست خواهد بود. این مفهوم مشابه هدف .PHONY در GNU make است. همچنین SCons یک قابلیت قدرتمند نام مستعار هدف (به Alias مراجعه کنید) ارائه میدهد که ممکن است در بسیاری از موقعیتها هنگام تعریف نامهای هدفی که مستقیماً ساخته نمیشوند، انعطافپذیری بیشتری فراهم کند.
PyPackageDir(modulename), env.PyPackageDir(modulename)
هنگامی که یک ماژول ابزار (Tool) که به عنوان یک ماژول Python نصب شده استفاده میشود، باید یک آرگومان toolpath را به Tool، Environment یا Clone مشخص کنید، زیرا در غیر این صورت ابزارهای خارج از مکانهای استاندارد پروژه (site_scons/site_tools) پیدا نخواهند شد. استفاده از PyPackageDir اجازه میدهد این مسیر به جای درج ثابت در کد (hardcode)، در زمان اجرا کشف شود.
مثال:
env = Environment(
tools=["default", "ExampleTool"],
toolpath=[PyPackageDir("example_tool")]
)
env.Replace(key=val, [...])
مثال:
env.Replace(CCFLAGS='-g', FOO='foo.xxx')
Repository(directory), env.Repository(directory)
در scons، یک مخزن، یک نسخه جزئی یا کامل از درخت منبع از بالاترین سطح دایرکتوری به پایین است که شامل فایلهای منبعی است که میتوانند برای ساخت اهداف در درخت کاری (worktree) فعلی استفاده شوند. مخازن همچنین میتوانند حاوی فایلهای اشتقاقی (derived files) باشند. یک نمونه میتواند درخت منبع رسمی باشد که توسط یک یکپارچهساز نگهداری میشود. اگر مخزنی حاوی فایلهای اشتقاقی باشد، آنها باید نتیجه ساخت با SCons باشند، تا پایگاه داده امضا (sconsign) در مخزن وجود داشته باشد و تصمیمگیری بهتری در مورد بهروز بودن یا نبودن آنها امکانپذیر شود.
توجه داشته باشید که اگر یک فایل اشتقاقی بهروز از قبل در یک مخزن موجود باشد، scons نسخهای از آن را در درخت دایرکتوری محلی ایجاد نخواهد کرد. اگر نیاز دارید که یک کپی محلی ساخته شود، از متد Local استفاده کنید.
Requires(target, prerequisite), env.Requires(target, prerequisite)
مثال:
env.Requires('foo', 'file-that-must-be-built-before-foo')
Return([vars..., stop=True])
بهطور پیشفرض Return پردازش SConscript فعلی را متوقف کرده و بلافاصله بازمیگردد. آرگومان کلیدواژهای اختیاری stop میتواند روی یک مقدار نادرست (False) تنظیم شود تا پردازش ادامه فایل SConscript پس از فراخوانی Return ادامه یابد (این رفتار پیشفرض قبل از SCons 0.98 بود). با این حال، مقادیر بازگرداندهشده همچنان مقادیر متغیرهای نامبرده در vars در نقطه فراخوانی Return هستند.
مثالها:
# هیچ مقداری برنمیگرداند (ارزیابی نادرست / False)
Return()
# مقدار متغیر پایتونی 'foo' را برمیگرداند.
Return("foo")
# مقادیر متغیرهای پایتونی 'foo' و 'bar' را برمیگرداند.
Return("foo", "bar")
# مقادیر متغیرهای پایتونی 'val1' و 'val2' را برمیگرداند.
Return('val1 val2')
Scanner(function, [name, argument, skeys, path_function, node_class, node_factory, scan_check, recursive]), env.Scanner(function, [name, argument, skeys, path_function, node_class, node_factory, scan_check, recursive])
SConscript(scriptnames, [exports, variant_dir, duplicate, must_exist]), env.SConscript(scriptnames, [exports, variant_dir, duplicate, must_exist]), SConscript(dirs=subdirs, [name=scriptname, exports, variant_dir, duplicate, must_exist]), env.SConscript(dirs=subdirs, [name=scriptname, exports, variant_dir, duplicate, must_exist])
روش نخست فراخوانی، ارائه یک یا چند نام فایل SConscript به عنوان اولین آرگومان موضعی است که میتواند یک رشته یا فهرستی از رشتهها باشد. اگر آرگومان موضعی دومی وجود داشته باشد، با آن به گونهای رفتار میشود که گویی آرگومان کلیدواژهای exports داده شده است (به ادامه مطلب مراجعه کنید). مثالها:
SConscript('SConscript') # run SConscript in the current directory
SConscript('src/SConscript') # run SConscript in the src directory
SConscript(['src/SConscript', 'doc/SConscript'])
SConscript(Split('src/SConscript doc/SConscript'))
config = SConscript('MyConfig.py')
روش دوم فراخوانی، حذف آرگومان موضعیِ نامگذاری اسکریپت و در عوض تعیین نام دایرکتوریها با استفاده از آرگومان کلیدواژهای dirs است. مقدار میتواند یک رشته یا فهرستی از رشتهها باشد. در این حالت، scons یک فایل پیکربندی فرعی به نام SConscript (بهطور پیشفرض) را در هر یک از دایرکتوریهای مشخصشده اجرا خواهد کرد. میتوانید با ارائه یک آرگومان کلیدواژهای اختیاری name=scriptname نامی غیر از SConscript را تعیین کنید. سه مثال نخست زیر اثری مشابه سه مثال نخست بالا دارند:
SConscript(dirs='.') # run SConscript in the current directory SConscript(dirs='src') # run SConscript in the src directory SConscript(dirs=['src', 'doc']) SConscript(dirs=['sub1', 'sub2'], name='MySConscript')
آرگومان کلیدواژهای اختیاری exports متغیرهایی را مشخص میکند تا برای استفاده در SConscriptهای فراخوانیشده در دسترس قرار گیرند؛ این اسکریپتها در محیطی ایزوله ارزیابی میشوند و در غیر این صورت به متغیرهای محلی SConscript فراخواننده دسترسی ندارند. این مقدار میتواند یک رشته یا فهرستی از رشتهها شامل نام متغیرها باشد، یا یک دیکشنری که نامهای محلی را به نامهایی نگاشت میکند که میتوانند با آنها وارد شوند. در روش فراخوانی نخست (scriptnames)، دومین آرگومان موضعی نیز به عنوان exports تفسیر خواهد شد؛ روش فراخوانی دوم (دایرکتوری) هیچ آرگومان موضعی را نمیپذیرد و باید از فرم کلیدواژهای استفاده کند. این متغیرها تنها برای فایل(های) SConscript فراخوانیشده بهطور محلی صادر (export) میشوند، و نسبت به هر متغیر همنام در مخزن سراسری که توسط تابع Export مدیریت میشود، اولویت دارند. فایلهای فرعی SConscript باید از تابع Import برای وارد کردن متغیرها به حوزه محلی خود استفاده کنند. مثالها:
foo = SConscript('sub/SConscript', exports='env')
SConscript('dir/SConscript', exports=['env', 'variable'])
SConscript(dirs='subdir', exports='env variable')
SConscript(dirs=['one', 'two', 'three'], exports='shared_info')
اگر آرگومان اختیاری variant_dir وجود داشته باشد، اثری معادل با تابع VariantDir ایجاد میکند، اما فقط در حوزه فراخوانی SConscript معتبر است. آرگومان variant_dir نسبت به دایرکتوریِ فایل SConscript فراخواننده تفسیر میشود. دایرکتوری مبدا، دایرکتوریای است که فایل SConscript فراخوانیشده در آن قرار دارد و فایل SConscript به گونهای ارزیابی میشود که گویی در دایرکتوری variant_dir قرار دارد. بنابراین:
SConscript('src/SConscript', variant_dir='build')
معادل است با:
VariantDir('build', 'src')
SConscript('build/SConscript')
اگر فایلهای مبدا در همان دایرکتوریِ SConstruct باشند،
SConscript('SConscript', variant_dir='build')
معادل است با:
VariantDir('build', '.')
SConscript('build/SConscript')
آرگومان اختیاری duplicate همانند VariantDir تفسیر میشود. اگر آرگومان variant_dir حذف شود، آرگومان duplicate نادیده گرفته خواهد شد. برای جزئیات و محدودیتهای بیشتر، به توضیحات VariantDir مراجعه کنید.
اگر مقدار اختیاری must_exist برابر True باشد (پیشفرض)، در صورت پیدا نشدن فایل SConscript درخواستی، یک استثنا ایجاد میشود. برای نادیدهگرفتن خاموش اسکریپتهای ناموجود (رفتار پیشفرض پیش از نسخه 3.1 SCons)، مقدار must_exist=False را در فراخوانی SConscript پاس دهید.
تغییریافته در 4.6.0: اکنون مقدار پیشفرض must_exist برابر True است.
در اینجا چند مثال ترکیبی آورده شده است:
# collect the configuration information and use it to build src and doc
shared_info = SConscript('MyConfig.py')
SConscript('src/SConscript', exports='shared_info')
SConscript('doc/SConscript', exports='shared_info')
# build debugging and production versions. SConscript
# can use Dir('.').path to determine variant.
SConscript('SConscript', variant_dir='debug', duplicate=0)
SConscript('SConscript', variant_dir='prod', duplicate=0)
# build debugging and production versions. SConscript
# is passed flags to use.
opts = { 'CPPDEFINES' : ['DEBUG'], 'CCFLAGS' : '-pgdb' }
SConscript('SConscript', variant_dir='debug', duplicate=0, exports=opts)
opts = { 'CPPDEFINES' : ['NODEBUG'], 'CCFLAGS' : '-O' }
SConscript('SConscript', variant_dir='prod', duplicate=0, exports=opts)
# build common documentation and compile for different architectures
SConscript('doc/SConscript', variant_dir='build/doc', duplicate=0)
SConscript('src/SConscript', variant_dir='build/x86', duplicate=0)
SConscript('src/SConscript', variant_dir='build/ppc', duplicate=0)
SConscript مقادیر هر متغیری را که توسط فایل(های) SConscript اجراشده در آرگومانهای تابع Return تعیین شده باشد، بازمیگرداند. اگر یک فراخوانیِ تکگانه SConscript باعث اجرای چندین اسکریپت شود، مقدار بازگشتی یک چندتایی (tuple) شامل مقادیر بازگشتی هر یک از اسکریپتها خواهد بود. اگر یک اسکریپت اجراشده صراحتاً تابع Return را فراخوانی نکند، None بازمیگرداند.
SConscriptChdir(value)
مثال:
SConscriptChdir(False)
SConscript('foo/SConscript') # به foo تغییر دایرکتوری نخواهد داد
SConscriptChdir(True)
SConscript('bar/SConscript') # به bar تغییر دایرکتوری خواهد داد
SConsignFile([name, dbm_module]), env.SConsignFile([name, dbm_module])
آرگومان اختیاری name نام پایهٔ فایل(های) پایگاهداده است. پایگاهداده نسبت به دایرکتوری حاوی فایل سطح بالای SConstruct قرار میگیرد، مگر اینکه name یک مسیر مطلق باشد. مقدار پیشفرض .sconsign است. فایل(های) واقعی پایگاهداده که روی دیسک ذخیره میشوند ممکن است پسوند مناسبی داشته باشند که توسط dbm_module انتخابی اضافه شده است، و همچنین ممکن است شامل نام قالب هش نیز باشند (نگاه کنید به --hash-format).
آرگومان اختیاری dbm_module مشخص میکند که از کدام ماژول پایگاهدادهٔ Python برای خواندن/نوشتن فایل استفاده شود. ماژول ابتدا باید وارد (import) شود؛ سپس نام ماژول واردشده به عنوان آرگومان ارسال میگردد. پیشفرض، یک ماژول سفارشی SCons.dblite است که از ساختارهای دادهٔ serializeشدهٔ Python (به کمک pickle) استفاده میکند و روی تمام نسخههای Python کار میکند. برای مشاهدهٔ سایر انواع موجود، به مستندات ماژول dbm در Python مراجعه کنید.
در صورت فراخوانی بدون آرگومان، پایگاهداده بهطور پیشفرض در .sconsign.dblite در دایرکتوری اصلی پروژه قرار خواهد گرفت، که در صورت فراخوانی نشدن SConsignFile نیز همین رفتار پیشفرض است.
این تنظیم بهصورت سراسری است، بنابراین تنها تفاوت بین تابع سراسری و حالت متد محیطی، بسط متغیرها روی name است. در یک پیکربندی ساخت مشخص، تنها باید یک فراخوانی فعال از این تابع/متد وجود داشته باشد.
اگر name روی None تنظیم شود، scons امضاهای فایل را در یک فایل .sconsign مجزا در هر دایرکتوری ذخیره خواهد کرد، نه در یک فایل پایگاهدادهٔ تجمیعی واحد. این تمهیدی برای سازگاری عقبرو بهمنظور پشتیبانی از رفتاری است که قبل از SCons 0.97 (یعنی قبل از سال ۲۰۰۸) پیشفرض بود. استفاده از این حالت منسوخ شده است و نباید در پروژههای جدید استفاده شود.
از نسخهٔ 4.11.0 منسوخ شده است: حالت یک فایل امضا به ازای هر دایرکتوری منسوخ شده است و در انتشارهای آینده حذف خواهد شد.
مثالها:
# بهطور صریح امضاها را در ".sconsign.dblite"
# در دایرکتوری سطح بالای SConstruct ذخیره میکند (رفتار پیشفرض).
SConsignFile()
# امضاها را در فایل "etc/scons-signatures"
# نسبت به دایرکتوری سطح بالای SConstruct ذخیره میکند.
# SCons یک پسوند پایگاهداده به این نام اضافه خواهد کرد.
SConsignFile("etc/scons-signatures")
# امضاها را در نام فایل مطلق مشخصشده ذخیره میکند.
# SCons یک پسوند پایگاهداده به این نام اضافه خواهد کرد.
SConsignFile("/home/me/SCons/signatures")
# امضاها را در یک فایل .sconsign جداگانه
# در هر دایرکتوری ذخیره میکند.
SConsignFile(None)
# امضاها را در یک فایل .sconsign با قالب GNU dbm ذخیره میکند
import dbm.gnu
SConsignFile(dbm_module=dbm.gnu)
env.SetDefault(key=val, [...])
env.SetDefault(FOO='foo')
if 'FOO' not in env:
env['FOO'] = 'foo'
SetOption(name, value), env.SetOption(name, value)
رفتار گزینهها در مدخل مربوط به گزینهٔ خط فرمان مرتبط در صفحهٔ راهنما (manpage) شرح داده شده است. پارامتر value اجباری است؛ برای مقادیر گزینههای بولی (در مواردی که گزینهٔ خط فرمان آرگومان دریافت نمیکند)، از یک value استفاده کنید که به مقدار درست (مانند True، 1) یا نادرست (مانند False، 0) ارزیابی شود.
گزینههایی که بر خواندن و پردازش فایلهای SConscript تأثیر میگذارند با استفاده از SetOption قابل تنظیم نیستند، زیرا آن فایلها در وهلهٔ اول باید خوانده شوند تا فراخوانی SetOption یافت شود.
برای گزینههای خاص پروژه (که گاهی گزینههای محلی نامیده میشوند) که از طریق فراخوانی AddOption اضافه شدهاند، استفاده از SetOption تنها پس از پایان موفقیتآمیز فراخوانی AddOption مجاز است، و فقط در صورتی که آن فراخوانی شامل آرگومان کلیدواژهای settable=True بوده باشد.
متغیرهای قابل تنظیم به همراه گزینههای خط فرمان متناظر با آنها عبارتند از:
| نام قابل تنظیم | آرگومان خط فرمان | یادداشتها |
| clean | -c, --clean, --remove | بولی |
| diskcheck | --diskcheck | لیست |
| duplicate | --duplicate | رشته |
| experimental | --experimental | مجموعه. از 4.2. |
| hash_chunksize | --hash-chunksize | عدد صحیح. جایگزین md5_chunksize شده است. از 4.2 |
| hash_format | --hash-format | رشته. از 4.2 |
| help | -h, --help | بولی |
| implicit_cache | --implicit-cache | بولی |
| implicit_deps_changed | --implicit-deps-changed | بولی. همچنین implicit_cache را تنظیم میکند. از 4.2 قابل تنظیم است |
| implicit_deps_unchanged | --implicit-deps-unchanged | بولی. همچنین implicit_cache را تنظیم میکند. از 4.2 قابل تنظیم است |
| max_drift | --max-drift | عدد صحیح |
| md5_chunksize | --hash-chunksize | عدد صحیح. با hash_chunksize جایگزین شده است. از 4.2 منسوخ شده است |
| no_exec | -n, --no-exec, --just-print, --dry-run, --recon | بولی |
| no_progress | -Q | بولی. نگاه کنید به [6] |
| num_jobs | -j, --jobs | عدد صحیح |
| random | --random | بولی |
| silent | -s, --silent, --quiet | بولی |
| stack_size | --stack-size | عدد صحیح |
| warn | --warn | لیست |
| ---- [a] اگر no_progress از طریق SetOption در یک فایل SConscript تنظیم شود (اما نه در صورت تنظیم در یک فایل site_init.py)، همچنان یک پیام وضعیت اولیه دربارهٔ خواندن فایلهای SConscript وجود خواهد داشت، چرا که SCons باید ابتدا خواندن آنها را آغاز کند تا فراخوانی SetOption را ببیند. | ||
مثال:
SetOption('max_drift', 0)
SideEffect(side_effect, target), env.SideEffect(side_effect, target)
از آنجا که چندین دستور ساخت ممکن است یک فایل اثر جانبی یکسان را بهروزرسانی کنند، به طور پیشفرض هنگام حذف target توسط گزینه -c، هدف side_effect به طور خودکار حذف نمیشود. (البته توجه داشته باشید که ممکن است side_effect به عنوان بخشی از پاکسازی دایرکتوریای که در آن قرار دارد حذف شود.) اگر میخواهید مطمئن شوید هر زمان که یک target خاص پاکسازی میشود، side_effect نیز پاکسازی شود، باید این مورد را صراحتاً با تابع Clean یا env.Clean مشخص کنید.
این تابع فهرستی از شیءهای Node اثر جانبی را که با موفقیت اضافه شدهاند برمیگرداند. اگر فهرست اثرات جانبی شامل مواردی باشد که از قبل اضافه شدهاند، آنها اضافه نشده و در فهرست بازگرداندهشده قرار نمیگیرند.
Split(arg), env.Split(arg)
مثال:
files = Split("f1.c f2.c f3.c")
files = env.Split("f4.c f5.c f6.c")
files = Split("""
f7.c
f8.c
f9.c
""")
env.subst(input, [raw, target, source, conv])
به طور پیشفرض، فاصلههای خالی ابتدا و انتهای نتیجه حذف خواهند شد و تمام توالیهای فاصلههای خالی به یک نویسه فاصله فشرده میشوند. علاوه بر این، هرگونه توالی نویسهای $( و $) از رشته بازگرداندهشده حذف خواهد شد. آرگومان اختیاری raw اگر میخواهید فاصلههای خالی و توالیهای $(-$) حفظ شوند، میتواند روی 1 تنظیم شود. همچنین اگر بخواهید علاوه بر این تمام نویسههای بین هر جفت $( و $) نیز دور ریخته شوند (همانطور که برای محاسبه امضا انجام میشود)، آرگومان raw میتواند روی 2 تنظیم شود.
اگر input یک توالی (لیست یا تاپل) باشد، تکتک عناصر توالی بسط داده شده و نتایج به عنوان یک لیست بازگردانده میشوند.
اگر میخواهید $TARGET، $TARGETS، $SOURCE و $SOURCES برای بسط در دسترس باشند، آرگومانهای اختیاری کلیدواژهای target و source باید به ترتیب روی فهرستهایی از گرههای هدف و منبع تنظیم شوند. این کار معمولاً زمانی لازم است که شما env.subst را از داخل یک تابع Python که به عنوان یک عمل (action) در SCons استفاده شده فراخوانی میکنید.
مقادیر رشتهای بازگرداندهشده یا عناصر توالی به طور پیشفرض به نمایش رشتهایشان تبدیل میشوند. آرگومان اختیاری conv میتواند یک تابع تبدیل را مشخص کند که به جای حالت پیشفرض استفاده خواهد شد. به عنوان مثال، اگر میخواهید شیءهای Python (شامل گرههای SCons) به عنوان شیءهای Python بازگردانده شوند، میتوانید از یک عبارت lambda در Python استفاده کنید تا تابعی بینام را ارسال کنید که صرفاً آرگومانِ تبدیلنشده خود را برمیگرداند.
مثال:
print(env.subst("The C compiler is: $CC"))
def compile(target, source, env):
sourceDir = env.subst(
"${SOURCE.srcdir}",
target=target,
source=source
)
source_nodes = env.subst('$EXPAND_TO_NODELIST', conv=lambda x: x)
Tag(node, tags)
مثالها:
# اطمینان حاصل میکند که کتابخانه ساختهشده با حالت دسترسی فایل 644 نصب خواهد شد
Tag(Library('lib.c'), UNIX_ATTR="0o644")
# فایل file2.txt را به عنوان یک فایل مستندات نشانهگذاری میکند
Tag('file2.txt', DOC)
Tool(name, [toolpath, key=value, ...]), env.Tool(name, [toolpath, key=value, ...])
ماژول ابزار در مسیرهای جستجوی ابزار (برای جزئیات به بخش Tools در صفحه راهنما مراجعه کنید) و در هر مسیری که توسط پارامتر اختیاری toolpath مشخص شده باشد، جستجو میشود؛ این پارامتر باید فهرستی از رشتهها باشد. اگر toolpath مشخص نشود، از toolpath ارائهشده هنگام ایجاد محیط (در صورت وجود) استفاده میشود.
هر آرگومان کلیدواژهای باقیمانده در شیء ابزار ذخیره شده، و هنگام فراخوانی واقعی شیء ابزار به تابع generate ماژول ابزار ارسال خواهد شد. تابع generate میتواند محیط ساخت را با متغیرهای ساخت بهروزرسانی کند و هرگونه مقداردهی اولیه دیگری که برای استفاده از سازوکارهای توصیفشده توسط ابزار لازم است را ترتیب دهد، و میتواند از این آرگومانهای اضافی برای هدایت اقدامات خود بهره ببرد.
تغییریافته در نسخه 4.2: اکنون env.Tool شیء ابزار را برمیگرداند؛ پیش از این مقداری برنمیگرداند (یعنی None برمیگرداند).
مثالها:
env.Tool('gcc')
env.Tool('opengl', toolpath=['build/tools'])
شیء ابزارِ بازگرداندهشده میتواند به عنوان بخشی از آرگومان کلیدواژهای tools به یک فراخوانی Environment یا Clone ارسال شود، که در این حالت ابزار به محیطِ در حال ساخت اعمال میشود؛ یا میتواند مستقیماً فراخوانی شود، که در این حالت باید یک محیط ساخت برای بهروزرسانی به عنوان آرگومان به آن ارسال گردد. هر یک از این دو روش، متغیر ساخت $TOOLS را نیز بهروزرسانی خواهد کرد.
مثالها:
env = Environment(tools=[Tool('msvc')])
env = Environment()
msvctool = Tool('msvc')
msvctool(env) # مقدار 'msvc' را به متغیر TOOLS اضافه میکند
gltool = Tool('opengl', toolpath = ['tools'])
gltool(env) # مقدار 'opengl' را به متغیر TOOLS اضافه میکند
ValidateOptions([throw_exception=False])
این تابع باید تنها پس از آخرین فراخوانی AddOption در منطق SConscript شما فراخوانی شود. توجه داشته باشید که برخی از ابزارها AddOption را فراخوانی میکنند؛ اگر برای آرگومانهایی که آنها اضافه میکنند پیام خطا دریافت میکنید، باید اطمینان حاصل کنید که آن ابزارها پیش از فراخوانی ValidateOptions بارگذاری شده باشند.
اگر گزینه ناشناختهای در خط فرمان وجود داشته باشد، ValidateOptions یک پیام خطا چاپ کرده و با وضعیت خروج خطا خارج میشود. اگر آرگومان اختیاری throw_exception برابر با True باشد (پیشفرض False است)، یک SConsBadOptionError صادر میشود (raise)، که به منطق SConscript این امکان را میدهد تا آن استثنا را دریافت کرده و گزینههای نامعتبر را به شکل مناسب مدیریت کند. توجه داشته باشید که این نام استثنا باید وارد (import) شود (به مثال زیر مراجعه کنید).
یک مشکل رایج در ساخت، اشتباهات تایپی (یا اشتباهات لپی و سهوی) است - کاربر گزینهای را وارد میکند که اندکی با مقدار مورد انتظار تفاوت دارد، یا شاید واژهای دیگر با معنای مشابه باشد. متوقف کردن ساخت پیش از پیشروی بیش از حد در مسیری نادرست میتواند مفید باشد. برای مثال:
$ scons --complier=mingw # پرچم درست --compiler است
در اینجا ممکن بود SCons به کار خود ادامه دهد و مجموعهای از مراحل پیکربندی (configure) را با استفاده از مقدار پیشفرض --compiler اجرا کند، چرا که گزینه دارای غلط املایی باعث میشود مقدار مدنظر به آن عرضه نشود؛ امری که زمان توسعهدهنده را برای ردیابی این که چرا منطق پیکربندی گزینههای «اشتباه» را انتخاب کرده تلف میکند. این مثال گرفتن و مدیریت این وضعیت را نشان میدهد:
from SCons.Script.SConsOptions import SConsBadOptionError
AddOption(
'--compiler',
dest='compiler',
action='store',
default='gcc',
type='string',
)
# ... سایر منطقهای SConscript ...
try:
ValidateOptions(throw_exception=True)
except SConsBadOptionError as e:
print(f"ValidateOptions detects a fail: ", e.opt_str)
Exit(3)
جدید در نسخه 4.5.0
Value(value, [built_value], [name]), env.Value(value, [built_value], [name])
آرگومان اختیاری built_value را میتوان هنگام ایجاد گره Value مشخص کرد تا نشان دهد که این Node باید از قبل «ساختهشده» در نظر گرفته شود.
پارامتر اختیاری name میتواند به عنوان نامی جایگزین برای گره Value حاصل ارائه شود؛ در صورتی که پارامتر value نتواند به یک رشته تبدیل شود، استفاده از این پارامتر توصیه میشود.
گرههای Value متدی به نام write دارند که میتوان با تنظیم مقداری جدید، از آن برای «ساختن» یک گره Value استفاده کرد. متد متناظرِ read مقدار ساختهشدهٔ Node را برمیگرداند.
تغییریافته در نسخهٔ 4.0: پارامتر name اضافه شد.
مثالها:
env = Environment()
def create(target, source, env):
"""Action function to create a file from a Value.
Writes 'prefix=$SOURCE' into the file name given as $TARGET.
"""
with open(target[0], 'wb') as f:
f.write(b'prefix=' + source[0].get_contents() + b'\n')
# Fetch the prefix= argument, if any, from the command line.
# Use /usr/local as the default.
prefix = ARGUMENTS.get('prefix', '/usr/local')
# Attach builder named Config to the construction environment
# using the 'create' action function above.
env['BUILDERS']['Config'] = Builder(action=create)
env.Config(target='package-config', source=Value(prefix))
def build_value(target, source, env):
"""Action function to "build" a Value.
Writes contents of $SOURCE into $TARGET, thus updating if it existed.
"""
target[0].write(source[0].get_contents())
output = env.Value('before')
input = env.Value('after')
# Attach a builder named UpdateValue to the construction environment
# using the 'build_value' action function above.
env['BUILDERS']['UpdateValue'] = Builder(action=build_value)
env.UpdateValue(target=Value(output), source=Value(input))
VariantDir(variant_dir, src_dir, [duplicate]), env.VariantDir(variant_dir, src_dir, [duplicate])
توجه داشته باشید که اگرچه variant_dir میتواند هر مکان مناسبی باشد، اما اگر زیر دایرکتوری اصلی پروژه نباشد، قواعد معمول انتخاب هدف، هدفهای موجود در دایرکتوری متغیر را انتخاب نخواهند کرد مگر اینکه به صورت صریح مشخص شوند.
هنگامی که به فایلهای درون variant_dir ارجاع داده میشود، SCons فایلهای ناموجود را بر حسب نیاز از src_dir تأمین میکند تا یک درخت ساخت کامل ایجاد کند. به طور پیشفرض، SCons فایلهای منبع، فایلهای فرعی SConscript و هر ساختار دایرکتوری مورد نیاز را به طور فیزیکی در دایرکتوری متغیر تکثیر میکند. این کار ساخت در دایرکتوری متغیر را معادل ساخت در درخت منبع میسازد، حتی در شرایطی که فایلهای منبع میانی تولید میشوند، اسکنرها فایلهای ضمیمهشده را با استفاده از مسیرهای نسبی نسبت به منبع جستجو میکنند، یا ابزارها طوری کدگذاری ثابت شدهاند که فایلهای اشتقاقی را در کنار منابعشان ایجاد کنند. تنها فایلهایی که SCons تشخیص دهد برای ساخت لازم هستند در variant_dir تکثیر میشوند. در صورت امکان، تکثیر به جای کپی کردن از طریق پیوند دادن (linking) انجام میگیرد. راهبرد تکثیر را میتوان با استفاده از گزینهٔ خط فرمان --duplicate یا SetOption تنظیم کرد.
اگر آرگومان duplicate روی False تنظیم شود، SCons فایلهای منبع را تکثیر نمیکند. در عوض، سازندهها را با استفاده از مسیرهای اصلی منبع در src_dir و مسیرهای فایلهای اشتقاقی در variant_dir به صورت خودکار فراخوانی میکند. این روش کارآمدتر از تکثیر است و برای اغلب ساختها ایمن میباشد؛ اگر مشکلی ایجاد کرد، از duplicate=True (پیشفرض) استفاده کنید.
نکته
هنگام تغییر حالت یک دایرکتوری متغیر موجود از تکثیرشونده به غیرتکثیرشونده، فایلهای منبعی که پیشتر تکثیر شدهاند به طور خودکار حذف نمیشوند. SCons همچنان استفاده از این نسخههای بیاتشده را به جای منابع اصلی ترجیح میدهد، که این امر ممکن است مانع از تشخیص تغییرات در فایلهای اصلی شود. برای جلوگیری از این مشکل، پیش از تغییر حالت، درخت ساخت را پاکسازی (clean) کنید. پس از این تغییر، SCons دیگر فایلهای تکثیرشده در دایرکتوری متغیر را ردیابی نکرده و در حین پاکسازی آنها را حذف نخواهد کرد.
مثالها:
# use names in the build directory, not the source directory
VariantDir('build', 'src', duplicate=False)
Program('build/prog', 'build/source.c')
# this builds both the source and docs in a separate subtree
VariantDir('build', '.', duplicate=False)
SConscript(dirs=['build/src', 'build/doc'])
# same as previous example, but only uses SConscript
SConscript(dirs='src', variant_dir='build/src', duplicate=False)
SConscript(dirs='doc', variant_dir='build/doc', duplicate=False)
VariantDir هنگامی که به همراه یک فایل فرعی SConscript به کار رود، طبیعیترین رفتار را دارد. فایل فرعی SConscript باید به گونهای فراخوانی شود که گویی در variant_dir قرار دارد، صرفنظر از اینکه مقدار duplicate چه باشد. از آرگومان کلیدواژهای exports برای ارسال پارامترها یا یک شیء محیطیِ پیکربندیشده استفاده کنید تا SConscript فرعی بتواند تنظیمات مناسب آن ساخت متغیر را به کار گیرد. فایل SConscript باید پیش از استفاده از این مقادیر صادرشده، آنها را با Import وارد کند.
env1 = Environment(...settings for variant1...)
env2 = Environment(...settings for variant2...)
# run src/SConscript by using the variant dir paths
VariantDir('build/variant1', 'src')
SConscript('build/variant1/SConscript', exports={"env": env1})
VariantDir('build/variant2', 'src')
SConscript('build/variant2/SConscript', exports={"env": env2})
Virtualenv()
WhereIs(program, [path, pathext, reject]), env.WhereIs(program, [path, pathext, reject])
هنگامی که به عنوان یک متدِ محیط ساخت (construction environment) فراخوانی شود، مسیرهای موجود در آرگومان کلیدواژهایِ path یا در صورت None بودن (پیشفرض)، مسیرهای فهرستشده در محیط ساخت (env['ENV']['PATH']) را جستجو میکند. در صورتی که کلید env['ENV']['PATH'] وجود نداشته باشد، از فهرست مسیرهای محیط خارجی (os.environ['PATH']) به عنوان جایگزین استفاده میشود.
در سیستمهای Windows، به دنبال برنامههای اجرایی با هر یک از پسوندهای فایل فهرستشده در آرگومان کلیدواژهایِ pathext میگردد، یا در صورت None بودن (پیشفرض)، پسوندهای نام مسیر فهرستشده در محیط ساخت (env['ENV']['PATHEXT']). در صورتی که کلید env['ENV']['PATHEXT'] وجود نداشته باشد، از فهرست پسوندهای نام مسیر محیط خارجی (os.environ['PATHEXT']) به عنوان جایگزین استفاده میشود.
هنگامی که به عنوان یک تابع سراسری فراخوانی شود، در صورتی که path و pathext برابر None باشند، به ترتیب از مسیر محیط خارجی os.environ['PATH'] و پسوندهای مسیر os.environ['PATHEXT'] استفاده میکند.
هیچیک از نام مسیرها یا نامهای موجود در فهرست اختیاریِ reject را انتخاب نخواهد کرد.
متغیرهای SConscript (SConscript Variables)
علاوه بر توابع و متدهای سراسری، scons از تعدادی متغیر پشتیبانی میکند که میتوان از آنها برای پرسوجوهای زمان اجرا در فایلهای SConscript جهت اثرگذاری بر نحوه اجرای ساخت استفاده کرد.
ARGLIST
print("first variable, value =", ARGLIST[0][0], ARGLIST[0][1])
print("second variable, value =", ARGLIST[1][0], ARGLIST[1][1])
var, value = ARGLIST[2]
print("third variable, value =", var, value)
for var, value in ARGLIST:
# process variable and value
مقادیر بهدستآمده از ARGLIST (یا از ARGUMENTS) همواره رشته هستند، زیرا از خارج فرایند SCons سرچشمه میگیرند. به عنوان «دادههای غیرقابل اعتماد»، آنها باید پیش از استفاده اعتبارسنجی شوند و ممکن است نیاز به تبدیل به یک نوع مناسب داشته باشند.
ARGUMENTS
مثال:
if ARGUMENTS.get("debug", ""):
env = Environment(CCFLAGS="-g")
else:
env = Environment()
همچنین ببینید: ARGLIST.
BUILD_TARGETS
عناصر این فهرست ممکن است رشته یا گره (Node) باشند، بنابراین باید فهرست را از طریق تابع str در Python پردازش کنید تا مطمئن شوید هرگونه نام مسیر Node به رشته تبدیل میشود.
از آنجا که این فهرست ممکن است از فهرست هدفهای مشخصشده با استفاده از تابع Default گرفته شده باشد، محتویات فهرست ممکن است با هر بار فراخوانی متوالیِ Default تغییر کند. برای اطلاعات تکمیلی، DEFAULT_TARGETS را ببینید.
مثال:
if 'foo' in BUILD_TARGETS:
print("Don't forget to test the `foo' program!")
if 'special/program' in BUILD_TARGETS:
SConscript('special')
COMMAND_LINE_TARGETS
مثال:
if 'foo' in COMMAND_LINE_TARGETS:
print("Don't forget to test the `foo' program!")
if 'special/program' in COMMAND_LINE_TARGETS:
SConscript('special')
DEFAULT_TARGETS
مثال:
print(str(DEFAULT_TARGETS[0]))
if 'foo' in [str(t) for t in DEFAULT_TARGETS]:
print("Don't forget to test the `foo' program!")
محتوای فهرست DEFAULT_TARGETS با هر بار فراخوانی متوالی تابع Default تغییر میکند:
print([str(t) for t in DEFAULT_TARGETS]) # originally []
Default('foo')
print([str(t) for t in DEFAULT_TARGETS]) # now a node ['foo']
Default('bar')
print([str(t) for t in DEFAULT_TARGETS]) # now a node ['foo', 'bar']
Default(None)
print([str(t) for t in DEFAULT_TARGETS]) # back to []
در نتیجه، مطمئن شوید که از DEFAULT_TARGETS تنها پس از انجام تمام فراخوانیهای Default() خود استفاده کنید، یا در غیر این صورت صرفاً مراقب ترتیب این دستورها در فایلهای SConscript خود باشید تا قبل از اینکه یک هدف پیشفرض خاص واقعاً به فهرست اضافه شود، به دنبال آن نگردید.
این متغیرها از طریق ماژولهای سفارشی Python که در یک فایل SConscript وارد (import) میکنید، با افزودن عبارت زیر به ماژول Python قابل دسترسی خواهند بود:
from SCons.Script import *
متغیرهای ساخت (Construction Variables)
«متغیرهای ساخت» (Construction Variables) جفتهای کلید-مقداری هستند که برای ذخیره اطلاعات در یک «محیط ساخت» (construction environment) مورد استفاده قرار میگیرند؛ اطلاعاتی که برای انجام ساختها با استفاده از آن محیط ضروری هستند. نامگذاری متغیرهای ساخت باید از همان قواعد نامگذاری شناسهها در Python پیروی کند: نویسه نخست باید یک زیرخط (_) یا حرف باشد و به دنبال آن هر تعداد زیرخط، حرف یا رقم قرار گیرد. قرارداد معمول این است که تمامی حروف بزرگ نوشته شوند تا تشخیص بصری آنها آسانتر باشد.
متغیرهای ساخت برای نگهداری انواع مختلفی از اطلاعات به کار میروند. به عنوان مثال، متغیر $CPPDEFINES روشی برای آگاه کردن کامپایلر C/C++ از ماکروهای پیشپردازندهای است که برای ساخت خود نیاز دارید. شناسایی ابزاری که توسط SCons انجام میشود باعث میشود که متغیر $CXX نام کامپایلر C++ را (در صورت شناسایی روی سیستم) در خود نگه دارد، اما میتوانید به آن مقدار متفاوتی بدهید تا اجرای دستوری با نامی دیگر برای کامپایلر تحمیل شود. برخی از متغیرها شامل فهرستی از پسوندهای نام فایل هستند که توسط یک زنجیره کامپایلر خاص شناخته میشوند. $BUILDERS شامل نگاشتی از نامهای پیکربندیشده Builder (مانند Textfile) به نمونه واقعی Builder است که در هنگام استفاده از آن Builder باید فراخوانی شود. متغیرهای ساخت ممکن است شامل ارجاع به سایر متغیرهای ساخت باشند: همان ابزاری که کامپایلر C/C++ را برپا کرده است، یک «رشته اقدام» (action string) را نیز در $CXXCOM تنظیم میکند که نحوه فراخوانی آن کامپایلر را شرح میدهد و با نحو $VARIABLE شامل سایر متغیرهای ساخت است. این ارجاعها در هنگام استفاده، بسط یافته و جایگزین میشوند (بخش Variable Substitution را ببینید).
به متغیرهای ساخت بهگونهای ارجاع داده میشود که گویی کلیدها و مقادیر موجود در یک دیکشنری Python هستند:
env["CC"] = "cc"
flags = env.get("CPPDEFINES", [])
متغیرهای ساخت همچنین میتوانند با استفاده از متد Dictionary محیط ساخت، برای ایجاد یک دیکشنری واقعی، دریافت و تنظیم شوند:
cvars = env.Dictionary() cvars["CC"] = "cc"
در مثال پیشین، از آنجا که cvars یک کپی بیرونی است، مقدار $CC در خود محیط ساخت با این مقداردهی تغییر نمیکند.
متغیرهای ساخت را میتوان هنگام ایجاد یک محیط ساخت جدید با ارسال آنها به عنوان آرگومانهای کلیدواژهای تنظیم کرد:
env = Environment(CC="cc")
یا هنگام کپی کردن یک محیط ساخت با استفاده از متد Clone:
env2 = env.Clone(CC="cl.exe")
متغیرهای ساخت همچنین میتوانند به عنوان آرگومانهای کلیدواژهای به یک Builder داده شوند؛ در این صورت، این تنظیمات تنها بر کاری که توسط آن فراخوانی Builder انجام میشود اثر میگذارند و کل محیط ساخت را تحت تأثیر قرار نمیدهند. این مفهوم، بازنویسی (override) نامیده میشود:
env.Program('hello', 'hello.c', LIBS=['gl', 'glut'])
بسیاری از متغیرهای ساخت کاربردی به طور خودکار توسط SCons و متناسب با پلتفرم مورد استفاده تعریف میشوند و شما میتوانید آنها را تغییر دهید یا متغیرهای ساخت اضافی را برای استفاده در Builderها، Scannerها و سایر ابزارهای خود تعریف کنید. مراقب باشید مواردی را که SCons از آنها استفاده میکند رونویسی نکنید. در ادامه فهرستی از متغیرهای ساخت پیشتعریفشده آمده است. توجه داشته باشید که آیا مقادیر مواردی هستند که انتظار میرود شما آنها را تنظیم کنید یا مواردی هستند که توسط ابزارهای داخلی و سایر مقداردهیهای اولیه بر روی مقادیر مورد انتظار تنظیم شدهاند و احتمالاً نباید تغییر داده شوند.
توجه داشته باشید که فهرست واقعی موجود در زمان اجرا هرگز شامل تمام این موارد نخواهد بود، زیرا مواردی که تشخیص داده شود قابل اعمال نیستند (پلتفرم نادرست، عدم نصب دستور یا فایلهای خارجی لازم و غیره) راهاندازی نخواهند شد. پیکربندیهای ساخت صحیح باید در برابر نبود احتمالی برخی از متغیرهای ساخت پیش از استفاده از آنها مقاوم باشند؛ برای مثال با استفاده از متد get دیکشنری Python برای بازیابی مقدار و انجام اقدامی جایگزین در صورتی که نتیجه نشاندهنده تنظیمنشده بودن متغیر باشد. برای بررسی متغیرهای ساخت تنظیمشده در یک محیط خاص، میتوان متد env.Dump را فراخوانی کرد.
__LDMODULEVERSIONFLAGS
__SHLIBVERSIONFLAGS
APPLELINK_COMPATIBILITY_VERSION
مقدار به صورت X[.Y[.Z]] مشخص میشود که در آن X عددی بین 1 و 65535 است، Y میتواند حذف شود یا بین 1 و 255 باشد، و Z میتواند حذف شود یا بین 1 و 255 باشد. در صورت عدم تعیین، این مقدار از $SHLIBVERSION مشتق خواهد شد. کمارزشترین رقم حذف شده و با یک 0 جایگزین میشود.
اگر $APPLELINK_NO_COMPATIBILITY_VERSION تنظیم شده باشد، هیچ -compatibility_version در خروجی قرار نخواهد گرفت.
برای جزئیات بیشتر به صفحه راهنمای ld در MacOS مراجعه کنید.
_APPLELINK_COMPATIBILITY_VERSION
APPLELINK_CURRENT_VERSION
مقدار به صورت X[.Y[.Z]] مشخص میشود که در آن X عددی بین 1 و 65535 است، Y میتواند حذف شود یا بین 1 و 255 باشد، و Z میتواند حذف شود یا بین 1 و 255 باشد. در صورت عدم تعیین، این مقدار برابر با $SHLIBVERSION تنظیم خواهد شد.
اگر $APPLELINK_NO_CURRENT_VERSION تنظیم شده باشد، هیچ -current_version در خروجی قرار نخواهد گرفت.
برای جزئیات بیشتر به صفحه راهنمای ld در MacOS مراجعه کنید.
_APPLELINK_CURRENT_VERSION
APPLELINK_NO_COMPATIBILITY_VERSION
این متغیر بر $APPLELINK_COMPATIBILITY_VERSION اولویت دارد.
APPLELINK_NO_CURRENT_VERSION
این متغیر بر $APPLELINK_CURRENT_VERSION اولویت دارد.
AR
ARCHITECTURE
سازنده Package را ببینید.
ARCOM
ARCOMSTR
env = Environment(ARCOMSTR = "Archiving $TARGET")
ARFLAGS
AS
ASCOM
ASCOMSTR
env = Environment(ASCOMSTR = "Assembling $TARGET")
ASFLAGS
ASPPCOM
ASPPCOMSTR
env = Environment(ASPPCOMSTR = "Assembling $TARGET")
ASPPFLAGS
BIBTEX
BIBTEXCOM
BIBTEXCOMSTR
env = Environment(BIBTEXCOMSTR = "Generating bibliography $TARGET")
BIBTEXFLAGS
BUILDERS
فهرستی پیشفرض و وابسته به پلتفرم از سازندهها مانند Program، Library و غیره، هنگام مقداردهی اولیهٔ محیط ساخت بر اساس وجود یا عدم وجود ابزارهایی که این سازندهها به آنها وابستهاند، برای مقداردهی به این متغیر ساخت استفاده میشود. $BUILDERS میتواند بررسی شود تا مشخص گردد کدام سازندهها در زمان اجرا واقعاً در دسترس خواهند بود.
توجه داشته باشید که اگر این متغیر ساخت را هنگام ایجاد محیط ساخت از طریق انتساب مقداردهی اولیه کنید، آن مقدار برای $BUILDERS جایگزین مقادیر پیشفرض خواهد شد:
bld = Builder(action='foobuild < $SOURCE > $TARGET')
env = Environment(BUILDERS={'NewBuilder': bld})
برای استفاده از یک شیء Builder جدید در کنار سازندههای پیشفرض، شیء Builder جدید خود را به این صورت اضافه کنید:
env = Environment()
env.Append(BUILDERS={'NewBuilder': bld})
یا به این صورت:
env = Environment() env['BUILDERS']['NewBuilder'] = bld
CACHEDIR_CLASS
CC
CCCOM
CCCOMSTR
env = Environment(CCCOMSTR = "Compiling static object $TARGET")
CCDEPFLAGS
این متغیر فقط توسط کامپایلرهایی که از این قابلیت پشتیبانی میکنند تنظیم میشود. (در حال حاضر gcc، clang و msvc)
CCFLAGS
CCPCHFLAGS
CCPDBFLAGS
گزینه کامپایلر Microsoft Visual C++ که SCons بهطور پیشفرض برای تولید اطلاعات PDB استفاده میکند، /Z7 است. این گزینه بهدرستی با ساختهای موازی (-j) کار میکند زیرا اطلاعات اشکالزدایی را در فایلهای شیء واسط جاسازی میکند، بر خلاف به اشتراک گذاشتن یک فایل PDB واحد بین چندین فایل شیء. این همچنین تنها روش برای جاسازی اطلاعات اشکالزدایی در یک کتابخانه استاتیک است. استفاده از /Zi در عوض ممکن است کارایی زمان پیوند را بهبود بخشد، هرچند ساختهای موازی دیگر کار نخواهند کرد.
میتوانید با بازنویسی متغیر پیشفرض $CCPDBFLAGS به صورت زیر، فایلهای PDB را با سوئیچ /Zi تولید کنید:
env['CCPDBFLAGS'] = ['${(PDB and "/Zi /Fd%s" % File(PDB)) or ""}']
یک راهکار جایگزین، استفاده از /Zi برای قرار دادن اطلاعات اشکالزدایی در یک فایل .pdb جداگانه برای هر فایل شیء از طریق بازنویسی متغیر $CCPDBFLAGS به صورت زیر است:
env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb'
CCVERSION
CFILESUFFIX
CFLAGS
CHANGE_SPECFILE
سازنده Package را ببینید.
CHANGED_SOURCES
CHANGED_TARGETS
CHANGELOG
سازنده Package را ببینید.
COMPILATIONDB_COMSTR
COMPILATIONDB_PATH_FILTER
مقدار پیشفرض یک رشتهٔ خالی '' است که فیلتر کردن را غیرفعال میکند.
COMPILATIONDB_USE_ABSPATH
مقدار پیشفرض False است (استفاده از مسیرهای نسبی).
_concat
env['_CPPINCFLAGS'] = '${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}'
CONFIGUREDIR
اگر دایرکتوریهای گونه (variant directories) در حال استفاده باشند و نتایج بررسی configure نباید بین گونهها به اشتراک گذاشته شوند، میتوانید $CONFIGUREDIR و $CONFIGURELOG را طوری تنظیم کنید که به ازای هر دایرکتوری گونه یکتا باشند.
CONFIGURELOG
اگر دایرکتوریهای گونه در حال استفاده باشند و نتایج بررسی configure نباید بین گونهها به اشتراک گذاشته شوند، میتوانید $CONFIGUREDIR و $CONFIGURELOG را طوری تنظیم کنید که به ازای هر دایرکتوری گونه یکتا باشند.
_CPPDEFFLAGS
CPPDEFINES
# Adds -Dxyz to POSIX compiler command lines, # and /Dxyz to Microsoft Visual C++ command lines. env = Environment(CPPDEFINES='xyz')
# Adds -DB=2 -DA to POSIX compiler command lines,
# and /DB=2 /DA to Microsoft Visual C++ command lines.
env = Environment(CPPDEFINES=[('B', 2), 'A'])
# Adds -DA -DB=2 to POSIX compiler command lines,
# or /DA /DB=2 to Microsoft Visual C++ command lines.
env = Environment(CPPDEFINES={'B':2, 'A':None})
بسته به نحوهٔ افزودن محتویات به $CPPDEFINES، ممکن است به یک نوع مرکب تبدیل شود؛ برای نمونه فهرستی حاوی رشتهها، چندتاییها و/یا فرهنگلغتها. SCons میتواند چنین نوع مرکبی را بهدرستی بسط دهد.
توجه داشته باشید که SCons ممکن است کامپایلر را از طریق یک شل فراخوانی کند. اگر تعریف یک ماکرو حاوی نویسههایی مانند فاصلهها باشد که برای شل معنای خاصی دارند، یا در نظر باشد که یک مقدار رشتهای باشد، ممکن است لازم باشد از نحو نقلقول (quoting) شل استفاده کنید تا پیش از دیدهشدن توسط پیشپردازنده، توسط شل تفسیر نشود. ماکروهای تابعگونه (function-like) از طریق این سازوکار پشتیبانی نمیشوند (و برخی کامپایلرها حتی چنین قابلیتی را از طریق خط فرمان پیادهسازی نمیکنند). هنگام استفاده از نقلقول، توجه داشته باشید که یک جفت نویسهٔ نقلقول برای تعریف یک رشته در Python استفاده میشود و نقلقولهای جاسازیشده در درون آن، مگر اینکه گریز داده شده باشند (escaped)، توسط شل مصرف خواهند شد. این مثالها ممکن است به درک موضوع کمک کنند:
env = Environment(CPPDEFINES=['USE_ALT_HEADER=\\"foo_alt.h\\"'])
env = Environment(CPPDEFINES=[('USE_ALT_HEADER', '\\"foo_alt.h\\"')])
:تغییریافته در نسخهٔ 4.5: SCons دیگر مقادیر $CPPDEFINES که در قالب فرهنگلغت وارد شدهاند را مرتبسازی نمیکند. Python اکنون کلیدهای فرهنگلغت را به ترتیبی که وارد شدهاند نگهداری میکند، بنابراین برای تضمین یک خط فرمان پایدار دیگر نیازی به مرتبسازی آنها نیست.
CPPDEFPREFIX
CPPDEFSUFFIX
CPPFLAGS
_CPPINCFLAGS
CPPPATH
نکته: نامهای دایرکتوری در $CPPPATH هنگامی که در یک دستور به کار میروند، نسبت به دایرکتوری فایل SConscript جستجو خواهند شد. برای وادار کردن scons به جستجوی یک دایرکتوری نسبت به ریشهٔ درخت منبع، از پیشوند # استفاده کنید:
env = Environment(CPPPATH='#/include')
همچنین میتوان جستجوی دایرکتوری را با استفاده از تابع Dir اجبار کرد:
include = Dir('include')
env = Environment(CPPPATH=include)
فهرست دایرکتوریها از طریق متغیر ساخت تولیدشده بهطور خودکارِ $_CPPINCFLAGS به خطوط فرمان اضافه میشود؛ این متغیر با افزودن مقادیر متغیرهای ساخت $INCPREFIX و $INCSUFFIX به ترتیب به ابتدا و انتهای هر دایرکتوری در $CPPPATH ساخته میشود. هر خط فرمانی که تعریف میکنید و به فهرست دایرکتوریهای $CPPPATH نیاز دارد باید شامل $_CPPINCFLAGS باشد:
env = Environment(CCCOM="my_compiler $_CPPINCFLAGS -c -o $TARGET $SOURCE")
CPPSUFFIXES
[".c", ".C", ".cxx", ".cpp", ".c++", ".cc", ".h", ".H", ".hxx", ".hpp", ".hh", ".F", ".fpp", ".FPP", ".m", ".mm", ".S", ".spp", ".SPP"]
CXX
CXXCOM
CXXCOMSTR
env = Environment(CXXCOMSTR = "Compiling static object $TARGET")
CXXFILESUFFIX
CXXFLAGS
CXXVERSION
DC
DCOM
DCOMSTR
DDEBUG
DDEBUGPREFIX
DDEBUGSUFFIX
DESCRIPTION
سازنده Package را ببینید.
DESCRIPTION_lang
سازنده Package را ببینید.
DFILESUFFIX
DFLAGPREFIX
DFLAGS
DFLAGSUFFIX
DI_FILE_DIR
DI_FILE_DIR_PREFIX
DI_FILE_DIR_SUFFFIX
DI_FILE_SUFFIX
DINCPREFIX
DINCSUFFIX
Dir
Dirs
DLIB
DLIBCOM
DLIBDIRPREFIX
DLIBDIRSUFFIX
DLIBFLAGPREFIX
DLIBFLAGS
DLIBFLAGSUFFIX
DLIBLINKPREFIX
DLIBLINKSUFFIX
DLINK
DLINKCOM
DLINKFLAGPREFIX
DLINKFLAGS
DLINKFLAGSUFFIX
DOCBOOK_DEFAULT_XSL_EPUB
DOCBOOK_DEFAULT_XSL_HTML
DOCBOOK_DEFAULT_XSL_HTMLCHUNKED
DOCBOOK_DEFAULT_XSL_HTMLHELP
DOCBOOK_DEFAULT_XSL_MAN
DOCBOOK_DEFAULT_XSL_PDF
DOCBOOK_DEFAULT_XSL_SLIDESHTML
DOCBOOK_DEFAULT_XSL_SLIDESPDF
DOCBOOK_FOP
DOCBOOK_FOPCOM
DOCBOOK_FOPCOMSTR
DOCBOOK_FOPFLAGS
DOCBOOK_XMLLINT
DOCBOOK_XMLLINTCOM
DOCBOOK_XMLLINTCOMSTR
DOCBOOK_XMLLINTFLAGS
DOCBOOK_XSLTPROC
DOCBOOK_XSLTPROCCOM
DOCBOOK_XSLTPROCCOMSTR
DOCBOOK_XSLTPROCFLAGS
DOCBOOK_XSLTPROCPARAMS
DPATH
DRPATHPREFIX
DRPATHSUFFIX
DSUFFIXES
DVERPREFIX
DVERSIONS
DVERSUFFIX
DVIPDF
DVIPDFCOM
DVIPDFCOMSTR
DVIPDFFLAGS
DVIPS
DVIPSFLAGS
ENV
توجه داشته باشید که بهطور پیشفرض، SCons محیط فعال در زمان اجرای scons («محیط شل») را به محیط اجرا منتقل نمیکند. این امر بدان جهت است که صرفنظر از متغیرهای محیطی تنظیمشده در زمان فراخوانی scons، تکرارپذیری ساخت تضمین شود. اگر میخواهید متغیری از محیط شل را به دستورهای اجراشده برای ساخت فایلهای هدف منتقل کنید، باید صریحاً این کار را انجام دهید. یک مثال متداول، متغیر محیطی سیستمی PATH است تا scons بتواند برنامهها و ابزارها را همانند شل فراخوان (یا فرآیندهای دیگر) پیدا کند:
import os
env = Environment(ENV={'PATH': os.environ['PATH']})
هرچند معمولاً توصیه نمیشود، اما میتوانید کل محیط شل را یکباره منتقل کنید:
import os env = Environment(ENV=os.environ.copy())
ESCAPE
F03
F03COM
F03COMSTR
F03FILESUFFIXES
F03FLAGS
_F03INCFLAGS
F03PATH
env = Environment(F03PATH='#/include')
جستجوی دایرکتوری را میتوان با استفاده از تابع Dir() نیز اجبار کرد:
include = Dir('include')
env = Environment(F03PATH=include)
فهرست دایرکتوریها از طریق متغیر ساخت خودکار تولیدشدهی $_F03INCFLAGS به خطوط فرمان افزوده خواهد شد، که با الحاق مقادیر متغیرهای ساخت $INCPREFIX و $INCSUFFIX به ابتدا و انتهای هر دایرکتوری در $F03PATH ساخته میشود. هر خط فرمانی که تعریف میکنید و به فهرست دایرکتوری F03PATH نیاز دارد، باید شامل $_F03INCFLAGS باشد:
env = Environment(F03COM="my_compiler $_F03INCFLAGS -c -o $TARGET $SOURCE")
F03PPCOM
F03PPCOMSTR
F03PPFILESUFFIXES
F08
F08COM
F08COMSTR
F08FILESUFFIXES
F08FLAGS
_F08INCFLAGS
F08PATH
env = Environment(F08PATH='#/include')
جستجوی دایرکتوری همچنین میتواند با استفاده از تابع Dir() اجبار شود:
include = Dir('include')
env = Environment(F08PATH=include)
فهرست دایرکتوریها از طریق متغیر ساخت خودکار تولیدشدهی $_F08INCFLAGS به خطوط دستور اضافه خواهد شد؛ این متغیر با افزودن مقادیر متغیرهای ساخت $INCPREFIX و $INCSUFFIX به ابتدا و انتهای هر دایرکتوری در $F08PATH ساخته میشود. هر خط دستوری که تعریف میکنید و به فهرست دایرکتوریهای F08PATH نیاز دارد، باید شامل $_F08INCFLAGS باشد:
env = Environment(F08COM="my_compiler $_F08INCFLAGS -c -o $TARGET $SOURCE")
F08PPCOM
F08PPCOMSTR
F08PPFILESUFFIXES
F77
F77COM
F77COMSTR
F77FILESUFFIXES
F77FLAGS
_F77INCFLAGS
F77PATH
env = Environment(F77PATH='#/include')
جستجوی دایرکتوری همچنین میتواند با استفاده از تابع Dir() اجبار شود:
include = Dir('include')
env = Environment(F77PATH=include)
فهرست دایرکتوریها از طریق متغیر ساخت خودکار تولیدشدهی $_F77INCFLAGS به خطوط دستور اضافه خواهد شد؛ این متغیر با افزودن مقادیر متغیرهای ساخت $INCPREFIX و $INCSUFFIX به ابتدا و انتهای هر دایرکتوری در $F77PATH ساخته میشود. هر خط دستوری که تعریف میکنید و به فهرست دایرکتوریهای F77PATH نیاز دارد، باید شامل $_F77INCFLAGS باشد:
env = Environment(F77COM="my_compiler $_F77INCFLAGS -c -o $TARGET $SOURCE")
F77PPCOM
F77PPCOMSTR
F77PPFILESUFFIXES
F90
F90COM
F90COMSTR
F90FILESUFFIXES
F90FLAGS
_F90INCFLAGS
F90PATH
env = Environment(F90PATH='#/include')
همچنین جستجوی دایرکتوری میتواند با استفاده از تابع Dir() اجبار شود:
include = Dir('include')
env = Environment(F90PATH=include)
فهرست دایرکتوریها از طریق متغیر ساخت خودکار ایجادشده $_F90INCFLAGS به خطوط فرمان اضافه میشود؛ متغیری که با الصاق مقادیر متغیرهای ساخت $INCPREFIX و $INCSUFFIX به ابتدا و انتهای هر دایرکتوری در $F90PATH ساخته میشود. هر خط فرمانی که تعریف میکنید و به فهرست دایرکتوری F90PATH نیاز دارد باید شامل $_F90INCFLAGS باشد:
env = Environment(F90COM="my_compiler $_F90INCFLAGS -c -o $TARGET $SOURCE")
F90PPCOM
F90PPCOMSTR
F90PPFILESUFFIXES
F95
F95COM
F95COMSTR
F95FILESUFFIXES
F95FLAGS
_F95INCFLAGS
F95PATH
env = Environment(F95PATH='#/include')
همچنین میتوان جستجوی دایرکتوری را با استفاده از تابع Dir() اجبار کرد:
include = Dir('include')
env = Environment(F95PATH=include)
فهرست دایرکتوریها از طریق متغیر ساخت بهطور خودکار تولید شدهی $_F95INCFLAGS به خطوط فرمان اضافه خواهد شد که با الحاق مقادیر متغیرهای ساخت $INCPREFIX و $INCSUFFIX به ابتدا و انتهای هر دایرکتوری در $F95PATH ساخته میشود. هر خط فرمانی که تعریف میکنید و به فهرست دایرکتوریهای F95PATH نیاز دارد باید شامل $_F95INCFLAGS باشد:
env = Environment(F95COM="my_compiler $_F95INCFLAGS -c -o $TARGET $SOURCE")
F95PPCOM
F95PPCOMSTR
F95PPFILESUFFIXES
File
FILE_ENCODING
جدید در نگارش 4.5.0.
FORTRAN
FORTRANCOM
FORTRANCOMMONFLAGS
جدید در نگارش 4.4.
FORTRANCOMSTR
FORTRANFILESUFFIXES
FORTRANFLAGS
_FORTRANINCFLAGS
FORTRANMODDIR
FORTRANMODDIRPREFIX
FORTRANMODDIRSUFFIX
_FORTRANMODFLAG
FORTRANMODPREFIX
FORTRANMODSUFFIX
FORTRANPATH
env = Environment(FORTRANPATH='#/include')
جستجوی دایرکتوری را میتوان با استفاده از تابع Dir() نیز اجبار کرد:
include = Dir('include')
env = Environment(FORTRANPATH=include)
فهرست دایرکتوریها از طریق متغیر ساخت تولیدشده به صورت خودکار $_FORTRANINCFLAGS به خطوط فرمان اضافه خواهد شد؛ این متغیر با افزودن مقادیر متغیرهای ساخت $INCPREFIX و $INCSUFFIX به ترتیب به ابتدا و انتهای هر دایرکتوری در $FORTRANPATH ساخته میشود. هر خط فرمانی که تعریف میکنید و به فهرست دایرکتوریهای FORTRANPATH نیاز دارد، باید شامل $_FORTRANINCFLAGS باشد:
env = Environment(FORTRANCOM="my_compiler $_FORTRANINCFLAGS -c -o $TARGET $SOURCE")
FORTRANPPCOM
FORTRANPPCOMSTR
FORTRANPPFILESUFFIXES
FORTRANSUFFIXES
[".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP", ".f77", ".F77", ".f90", ".F90", ".f95", ".F95"]
FRAMEWORKPATH
env.AppendUnique(FRAMEWORKPATH='#myframeworkdir')
عبارت
... -Fmyframeworkdir
را به خطوط فرمان کامپایلر و پیونددهنده اضافه خواهد کرد.
_FRAMEWORKPATH
FRAMEWORKPATHPREFIX
FRAMEWORKPREFIX
FRAMEWORKS
env.AppendUnique(FRAMEWORKS=Split('System Cocoa SystemConfiguration'))
_FRAMEWORKS
FRAMEWORKSFLAGS
GS
GSCOM
GSCOMSTR
GSFLAGS
HOST_ARCH
در پلتفرم win32، اگر کامپایلر Microsoft Visual C++ در دسترس باشد، راهاندازی ابزار msvc با استفاده از $HOST_ARCH و $TARGET_ARCH انجام میشود. تغییر دادن این مقادیر در زمانهای بعدی باعث مقداردهی اولیه مجدد ابزار نخواهد شد. مقادیر معتبر معماری میزبان عبارتند از x86 و arm برای میزبانهای ۳۲ بیتی، و amd64، arm64 و x86_64 برای میزبانهای ۶۴ بیتی.
باید تغییرناپذیر در نظر گرفته شود. $HOST_ARCH در حال حاضر توسط سایر پلتفرمها استفاده نمیشود، اما این گزینه برای استفاده در آینده محفوظ است.
HOST_OS
باید تغییرناپذیر در نظر گرفته شود. $HOST_OS در حال حاضر توسط SCons استفاده نمیشود، اما این گزینه برای استفاده در آینده محفوظ است.
IDLSUFFIXES
[".idl", ".IDL"]
IMPLIBNOVERSIONSYMLINKS
IMPLIBPREFIX
IMPLIBSUFFIX
IMPLIBVERSION
IMPLICIT_COMMAND_DEPENDENCIES
اگر $IMPLICIT_COMMAND_DEPENDENCIES روی یک مقدار نادرست ("none" یا "false" یا "no" یا "off" یا "0" یا عدد صحیح 0) تنظیم شود، هیچ وابستگی ضمنی از رشتههای کنش اضافه نمیشود. اگر روی یک مقدار عددی صحیح بزرگتر از 1 یا روی "all" تنظیم شود، آرگومانهای خط فرمان اضافی بررسی میشوند. مقدار عددی N تعداد N آرگومان اول را بررسی میکند، در حالی که "all" تمام آرگومانها را بررسی میکند. یک آرگومان بررسیشده فراتر از آرگومان نخست، در صورتی که یک مسیر مطلق باشد یا به فایلی موجود در سیستم فایل اشاره کند، به عنوان یک وابستگی افزوده میشود؛ برخلاف نخستین آرگومان، این آرگومانهای اضافی با استفاده از مسیر جستجوی محیط اجرا جستجو نمیشوند. با سایر مقادیر $IMPLICIT_COMMAND_DEPENDENCIES مانند حالت پیشفرض رفتار میشود. مقدار $IMPLICIT_COMMAND_DEPENDENCIES پیش از استفاده مشمول جایگزینی است، بنابراین میتواند شامل ارجاعی به یک متغیر ساخت باشد.
رشتههای کنش ممکن است با یک عملگر AND منطقی (&&) بخشبندی شده باشند، که نشان میدهد هر بخش به صورت ترتیبی اجرا میشود، اما تنها در صورتی که بخش قبلی با موفقیت به پایان رسیده باشد. اگر $IMPLICIT_COMMAND_DEPENDENCIES روی "all" یا یک عدد صحیح بزرگتر از 1 تنظیم شده باشد، هر بخش برای محاسبهٔ وابستگیها به عنوان یک خط فرمان مجزا در نظر گرفته میشود؛ در غیر این صورت، تنها بخش نخست بررسی میشود.
INCPREFIX
INCSUFFIX
INSTALL
def install(dest, source, env):
dest نام مسیر فایل مقصد است. source نام مسیر فایل منبع است. env محیط ساخت (دیکشنریای از مقادیر ساخت) است که برای نصب این فایل اعمال میشود.
INSTALLSTR
Install file: "$SOURCE" as "$TARGET"
INTEL_C_COMPILER_VERSION
JAR
JARCHDIR
JARCOM
JARCOMSTR
env = Environment(JARCOMSTR="JARchiving $SOURCES into $TARGET")
JARFLAGS
JARSUFFIX
JAVABOOTCLASSPATH
این مقدار از طریق گزینه -bootclasspath به خطوط فرمان JDK اضافه خواهد شد، که نیازمند جداکننده مسیر جستجوی وابسته به سیستم است. در صورتی که $JAVABOOTCLASSPATH به صورت فهرست ارائه شده باشد، این مقدار در صورت نیاز هنگام ساخت خط فرمان توسط SCons تأمین خواهد شد. اگر $JAVABOOTCLASSPATH یک رشته منفرد حاوی نویسههای جداکننده مسیر جستجو باشد (: برای سیستمهای POSIX یا ; برای Windows)، اصلاح نخواهد شد؛ و از این رو ذاتاً وابسته به سیستم است؛ برای ارائه مسیر به روشی مستقل از سیستم، در عوض $JAVABOOTCLASSPATH را به صورت فهرستی از مسیرها مشخص کنید.
نکته
فقط هنگام کامپایل برای نسخههای پیش از JDK 9 قابل استفاده است.
JAVAC
JAVACCOM
JAVACCOMSTR
env = Environment(JAVACCOMSTR="Compiling class files $TARGETS from $SOURCES")
JAVACFLAGS
JAVACLASSDIR
JAVACLASSPATH
این مقدار از طریق گزینه -classpath به خطوط فرمان JDK افزوده خواهد شد، که نیازمند جداکننده مسیر جستجوی مختص به سیستم است. این مورد در صورت نیاز توسط SCons هنگام ساخت خط فرمان، در صورتی که $JAVACLASSPATH به شکل فهرست ارائه شده باشد، تأمین میشود. اگر $JAVACLASSPATH یک رشته تکی حاوی نویسههای جداکننده مسیر جستجو (: برای سیستمهای POSIX یا ; برای Windows) باشد، به منظور پایش وابستگیها بر اساس جداکننده به فهرستی از مسیرهای مجزا تقسیم میشود. این رشته برای استفاده در خط فرمان JDK تغییر نخواهد کرد، بنابراین چنین رشتهای ذاتا وابسته به سیستم است؛ برای مشخص کردن مسیر به روشی مستقل از سیستم، به جای آن $JAVACLASSPATH را به صورت فهرستی از مسیرها ارائه دهید.
نکته
SCons همیشه هنگام فراخوانی کامپایلر جاوا javac، صرفنظر از تنظیمات $JAVASOURCEPATH، یک -sourcepath ارائه میدهد؛ چرا که مسیر(های) منبع(های) ارائهشده در فراخوانی سازنده Java را از طریق -sourcepath ارسال میکند. طبق مستندات جعبهابزار استاندارد Java برای javac: “در صورت کامپایل نکردن کد برای ماژولها، اگر گزینه --source-path یا -sourcepath مشخص نشده باشد، مسیر کلاس کاربر نیز برای فایلهای منبع جستجو میشود.” از آنجا که -sourcepath همیشه ارائه میشود، javac هنگام جستجوی منابع از محتوای مقدار $JAVACLASSPATH استفاده نخواهد کرد.
JAVACLASSSUFFIX
JAVAH
JAVAHCOM
JAVAHCOMSTR
env = Environment(JAVAHCOMSTR="Generating header/stub file(s) $TARGETS from $SOURCES")
JAVAHFLAGS
JAVAINCLUDES
JAVAPROCESSORPATH
این مقدار از طریق گزینه -processorpath به خطوط فرمان JDK افزوده خواهد شد، که نیازمند جداکننده مسیر جستجوی مختص به سیستم است. این مورد در صورت نیاز توسط SCons هنگام ساخت خط فرمان، در صورتی که $JAVAPROCESSORPATH به صورت فهرست ارائه شده باشد، تأمین میشود. اگر $JAVAPROCESSORPATH یک رشته تکی حاوی نویسههای جداکننده مسیر جستجو (: برای سیستمهای POSIX یا ; برای Windows) باشد، تغییر داده نخواهد شد؛ بنابراین ذاتا وابسته به سیستم است؛ برای تعیین مسیر به روشی مستقل از سیستم، به جای آن $JAVAPROCESSORPATH را به صورت فهرستی از مسیرها ارائه دهید.
جدید در نسخه 4.5.0
JAVASOURCEPATH
این مقدار از طریق گزینه -sourcepath به خطوط فرمان JDK اضافه خواهد شد، که نیازمند یک جداکننده مسیر جستجوی مختص به سیستم است. این مورد در صورت نیاز توسط SCons هنگام ایجاد خط فرمان، در صورتی که $JAVASOURCEPATH به صورت فهرست ارائه شده باشد، تأمین میشود. اگر $JAVASOURCEPATH یک رشته تکی حاوی نویسههای جداکننده مسیر جستجو (: برای سیستمهای POSIX یا ; برای Windows) باشد، تغییر نخواهد کرد و در نتیجه ذاتا وابسته به سیستم است؛ برای ارائه مسیر به شیوهای مستقل از سیستم، به جای آن $JAVASOURCEPATH را به صورت فهرستی از مسیرها تعیین کنید.
توجه داشته باشید که دایرکتوریهای مشخصشده تنها از طریق گزینه -sourcepath به خط فرمان افزوده میشوند. SCons در حال حاضر دایرکتوریهای $JAVASOURCEPATH را برای فایلهای وابسته .java جستجو نمیکند.
JAVASUFFIX
JAVAVERSION
اگرچه این متغیر در درجه اول برای انتخاب یک نسخه از کامپایلر Java در برابر نسخهای دیگر در نظر گرفته نشده است، اما در بستر Windows چنین تأثیری دارد. رویکرد دقیقتر این است که در صورتی که کامپایلر مد نظر شما کامپایلر پیشفرض نیست، $JAVAC (و متغیرهای ساخت مربوطه برای ابزارهای مرتبط) را روی مسیر کامپایلر Java خاصی که میخواهید تنظیم کنید. در بسترهای غیر از Windows، سامانهٔ alternatives ممکن است روشی برای تنظیم کامپایلر پیشفرض Java بدون نیاز به مشخص کردن صریح مسیرها فراهم کند.
LATEX
LATEXCOM
LATEXCOMSTR
env = Environment(LATEXCOMSTR = "Building $TARGET from LaTeX input $SOURCES")
LATEXFLAGS
LATEXRETRIES
LATEXSUFFIXES
[".tex", ".ltx", ".latex"]
LDMODULE
LDMODULECOM
LDMODULECOMSTR
LDMODULEEMITTER
LDMODULEFLAGS
LDMODULENOVERSIONSYMLINKS
LDMODULEPREFIX
_LDMODULESONAME
LDMODULESUFFIX
LDMODULEVERSION
_LDMODULEVERSIONFLAGS
LDMODULEVERSIONFLAGS
LEX
LEX_HEADER_FILE
LEX_TABLES_FILE
LEXCOM
LEXCOMSTR
env = Environment(LEXCOMSTR="Lex'ing $TARGET from $SOURCES")
LEXFLAGS
توجه داشته باشید که فایلهای مشخصشده توسط --header-file= و --tables-file= ممکن است در همه شرایط به درستی توسط SCons مدیریت نشوند. در عوض، استفاده از $LEX_HEADER_FILE و $LEX_TABLES_FILE را مد نظر قرار دهید.
LEXUNISTD
_LIBDIRFLAGS
LIBDIRPREFIX
LIBDIRSUFFIX
LIBEMITTER
_LIBFLAGS
LIBLINKPREFIX
LIBLINKSUFFIX
LIBLITERALPREFIX
env.Append(LIBS=":libmylib.a")
به پیونددهنده اجازه میدهد در صورت یافتن آن نام کتابخانهٔ خاص (ایستا) در مسیر جستجوی کتابخانه، آن را انتخاب کند. این روش با استفاده از یک شیء File برای تعیین کتابخانهٔ ایستا متفاوت است، زیرا دومی مسیر جستجوی کتابخانه را بهطور کامل دور میزند.
LIBPATH
دستورهای جستجوی کتابخانه را مستقیماً در $LINKFLAGS یا $SHLINKFLAGS قرار ندهید، چرا که نتیجه غیرقابلحمل (non-portable) خواهد بود.
نکته: نامهای دایرکتوری در $LIBPATH هنگامی که در یک فرمان استفاده میشوند، نسبت به دایرکتوری فایل SConscript جستجو خواهند شد. برای وادار کردن scons به جستجوی دایرکتوری نسبت به ریشهٔ درخت کد منبع، از پیشوند # استفاده کنید:
env = Environment(LIBPATH='#/libs')
همچنین میتوان جستجوی دایرکتوری را با استفاده از تابع Dir اجبار کرد:
libs = Dir('libs')
env = Environment(LIBPATH=libs)
فهرست دایرکتوریها از طریق متغیر ساخت خودکار تولیدشدهٔ $_LIBDIRFLAGS به خطوط فرمان اضافه خواهد شد، که با افزودن مقادیر متغیرهای ساخت $LIBDIRPREFIX و $LIBDIRSUFFIX به ترتیب به ابتدا و انتهای هر دایرکتوری در $LIBPATH ایجاد میشود. هر خط فرمانی که تعریف میکنید و به فهرست دایرکتوریهای $LIBPATH نیاز دارد، باید شامل $_LIBDIRFLAGS باشد:
env = Environment(LINKCOM="my_linker $_LIBDIRFLAGS $_LIBFLAGS -o $TARGET $SOURCE")
LIBPREFIX
LIBPREFIXES
LIBS
برای سازگاری و حملپذیری، نام کتابخانهای که به صورت رشته باشد باید تنها شامل نام پایهٔ کتابخانه باشد، بدون پیشوندهایی مانند lib یا پسوندهایی چون .so یا .dll. SCons تلاش خواهد کرد که پیشوندها را از فهرست $LIBPREFIXES و پسوندها را از فهرست $LIBSUFFIXES حذف کند، اما تکیه بر این رفتار قابلیت حمل ساخت را کاهش میدهد: برای مثال، در یک سیستم POSIX، هیچ تلاشی برای حذف پسوندی مانند .dll صورت نخواهد گرفت. رشتههای نام کتابخانه در $LIBS نباید شامل جزء مسیر (path component) باشند: در عوض از $LIBPATH استفاده کنید تا کامپایلر را هدایت کند که علاوه بر هر مسیر پیشفرضی که پیونددهنده (linker) جستجو میکند، در آن مسیرها نیز به دنبال کتابخانهها بگردد. اگر $LIBLITERALPREFIX روی یک رشتهٔ غیرخالی تنظیم شده باشد، آنگاه مدخلی در $LIBS که با مقدار رشتهای $LIBLITERALPREFIX شروع شود، باعث خواهد شد که باقیماندهٔ آن مدخل بدون تغییر اما با رعایت مسیرهای جستجوی عادی کتابخانه جستجو شود (این یک استثنا بر راهنمای بالا در خصوص حذف پیشوند/پسوند از نام کتابخانه است).
اگر یک مدخل $LIBS یک شیء Node باشد (خواه خروجی فراخوانی قبلی یک سازنده (Builder) باشد، یا نتیجهٔ فراخوانی صریح File)، نام مسیر برگرفته از آن Node به صورت دستنخورده به $_LIBFLAGS، و در نتیجه به خط پیوند اضافه خواهد شد - بدون افزودن $LIBLINKPREFIX یا $LIBLINKSUFFIX. چنین مدخلهایی به صورت لفظی (عین کلمه، شامل هر جزء مسیر) جستجو میشوند؛ و از مسیرهای جستجوی کتابخانه استفاده نخواهد شد. برای مثال:
env.Append(LIBS=File('/tmp/mylib.so'))
به ازای هر فراخوانی Builder که منجر به پیوند با کتابخانهها میشود، SCons کتابخانههای موجود در تنظیمات $LIBS را که در آن لحظه فعال است، به عنوان وابستگیهای هدفی که در حال تولید است به گراف وابستگی اضافه خواهد کرد.
فهرست کتابخانهها از طریق متغیر ساخت خودکار تولیدشدهٔ $_LIBFLAGS به آرگومانهای خط فرمان تبدیل میشود؛ این متغیر به ترتیب با افزودن مقادیر متغیرهای ساخت $LIBLINKPREFIX و $LIBLINKSUFFIX به ابتدا و انتهای نام هر کتابخانه ایجاد میگردد.
هر خط فرمانی که خودتان تعریف میکنید و به کتابخانههای موجود در $LIBS نیاز دارد، به جای $LIBS باید شامل $_LIBFLAGS (و همچنین $_LIBDIRFLAGS) باشد. برای مثال:
env = Environment(LINKCOM="my_linker $_LIBDIRFLAGS $_LIBFLAGS -o $TARGET $SOURCE")
LIBSUFFIX
LIBSUFFIXES
LICENSE
سازندهٔ Package را ببینید.
LINESEPARATOR
LINGUAS_FILE
LINK
در سامانههای POSIX (آنهایی که از ابزار link استفاده میکنند)، در حالت عادی نباید این مقدار را تغییر دهید، زیرا بهطور پیشفرض روی یک ابزار پیونددهنده «هوشمند» تنظیم شده است که راهانداز کامپایلر متناسب با نوع فایلهای منبعِ در حال استفاده را انتخاب میکند. بنابراین برای نمونه، اگر $CXX را روی نام یک کامپایلر مشخص تنظیم کنید و در حال کامپایل منابع C++ باشید، تابع smartlink بهطور خودکار همان کامپایلر را برای پیوند دادن انتخاب خواهد کرد.
LINKCOM
LINKCOMSTR
env = Environment(LINKCOMSTR = "Linking $TARGET")
LINKFLAGS
M4
M4COM
M4COMSTR
M4FLAGS
MAKEINDEX
MAKEINDEXCOM
MAKEINDEXCOMSTR
MAKEINDEXFLAGS
MAXLINELENGTH
MIDL
MIDLCOM
MIDLCOMSTR
MIDLFLAGS
MOSUFFIX
MSGFMT
MSGFMTCOM
MSGFMTCOMSTR
MSGFMTFLAGS
MSGINIT
MSGINITCOM
MSGINITCOMSTR
MSGINITFLAGS
_MSGINITLOCALE
ابزار msginit و سازندهٔ POInit را ببینید.
MSGMERGE
MSGMERGECOM
MSGMERGECOMSTR
MSGMERGEFLAGS
MSSDK_DIR
MSSDK_VERSION
MSVC_BATCH
MSVC_NOTFOUND_POLICY
متغیر $MSVC_NOTFOUND_POLICY رفتار scons را در زمانی که هیچ نسخهای از msvc شناسایی نشود یا نسخهٔ درخواستی msvc پیدا نشود، تعیین میکند.
مقادیر معتبر برای $MSVC_NOTFOUND_POLICY و رفتار متناظر scons عبارتند از:
'Error' یا 'Exception'
'Warning' یا 'Warn'
'Ignore' یا 'Suppress'
نکته: علاوه بر مقادیر با حروفچینی شتری (camel case) که در بالا نشان داده شدهاند، مقادیر با حروف کوچک و بزرگ نیز پذیرفته میشوند.
متغیر $MSVC_NOTFOUND_POLICY هنگامی اعمال میشود که هر یک از شرایط زیر برقرار باشد:
متغیر $MSVC_NOTFOUND_POLICY هنگامی نادیده گرفته میشود که هر یک از شرایط زیر برقرار باشد:
جزئیات مهم استفاده:
هنگامی که $MSVC_NOTFOUND_POLICY مشخص نشده باشد، رفتار پیشفرض scons صدور هشدار و ادامه دادن مشروط به شرایط ذکر شده در بالا است. رفتار پیشفرض scons ممکن است در آینده تغییر کند.
جدید در نسخهٔ 4.4
MSVC_SCRIPT_ARGS
$MSVC_SCRIPT_ARGS برای آن دسته از آرگومانهای batch file مربوط به msvc در دسترس است که از طریق متغیرهای ساخت (construction variables) پشتیبانی درجهاول ندارند، یا زمانی که مشکلی در اعتبارسنجی متغیر ساخت مربوطه وجود دارد. در صورت امکان، توصیه میشود به جای آرگومانهای $MSVC_SCRIPT_ARGS از متغیرهای ساخت مناسب (مانند $MSVC_TOOLSET_VERSION) استفاده شود.
مقادیر معتبر برای $MSVC_SCRIPT_ARGS عبارتند از: None، یک رشته، یا فهرستی از رشتهها.
مقدار $MSVC_SCRIPT_ARGS به یک رشته اسکالر تبدیل میشود (یعنی «تخت» یا "flattened" میشود). رشته اسکالر حاصل، در صورتی که خالی نباشد، مشروط به شرایط اعتبارسنجی فهرستشده در زیر، بهعنوان آرگومان به batch file مربوط به msvc که از طریق تشخیص خودکار تعیین شده است ارسال میگردد.
$MSVC_SCRIPT_ARGS زمانی که مقدار آن None باشد و همچنین هنگامی که نتیجه تبدیل آرگومان یک رشته خالی باشد نادیده گرفته میشود. شرایط اعتبارسنجی زیر در این حالت اعمال نمیشوند.
در صورت برقرار بودن هر یک از شرایط زیر، یک استثنا (exception) ایجاد میشود:
مثال ۱ - یک ساخت Visual Studio 2022 با یک نگارش SDK و یک نگارش toolset که با یک آرگومان رشتهای مشخص شدهاند:
env = Environment(MSVC_VERSION='14.3', MSVC_SCRIPT_ARGS='10.0.20348.0 -vcvars_ver=14.29.30133')
مثال ۲ - یک ساخت Visual Studio 2022 با یک نگارش SDK و یک نگارش toolset که با یک آرگومان فهرستی مشخص شدهاند:
env = Environment(MSVC_VERSION='14.3', MSVC_SCRIPT_ARGS=['10.0.20348.0', '-vcvars_ver=14.29.30133'])
جزئیات مهم استفاده:
جدید در نسخه 4.4
MSVC_SCRIPTERROR_POLICY
متغیر $MSVC_SCRIPTERROR_POLICY رفتار scons را هنگام تشخیص خطاهای فایل دستهای msvc مشخص میکند. زمانی که $MSVC_SCRIPTERROR_POLICY مشخص نشده باشد، رفتار پیشفرض scons فرونشاندن پیامهای خطای فایل دستهای msvc است.
ریشه اصلی شکستهای ساخت msvc ممکن است برای عیبیابی دشوار باشد. در این شرایط، تنظیم رفتار scons برای صدور هشدار هنگام تشخیص خطاهای فایل دستهای msvc ممکن است اطلاعات تشخیصی بیشتری تولید کند.
مقادیر معتبر برای $MSVC_SCRIPTERROR_POLICY و رفتار متناظر scons عبارتند از:
'Error' یا 'Exception'
'Warning' یا 'Warn'
'Ignore' یا 'Suppress'
جدید در نسخه 4.4
نکته: علاوه بر مقادیر با نگارش شتری (camel case) نشاندادهشده در بالا، مقادیر با حروف کوچک و حروف بزرگ نیز پذیرفته میشوند.
مثال ۱ - یک ساخت Visual Studio 2022 با آرگومانهای اسکریپت تعریفشده توسط کاربر:
env = environment(MSVC_VERSION='14.3', MSVC_SCRIPT_ARGS=['8.1', 'store', '-vcvars_ver=14.1'])
env.Program('hello', ['hello.c'], CCFLAGS='/MD', LIBS=['kernel32', 'user32', 'runtimeobject'])
مثال ۱ - بخشی از خروجی:
... link /nologo /OUT:_build001\hello.exe kernel32.lib user32.lib runtimeobject.lib _build001\hello.obj LINK : fatal error LNK1104: cannot open file 'MSVCRT.lib' ...
مثال ۲ - یک ساخت Visual Studio 2022 با آرگومانهای اسکریپت تعریفشده توسط کاربر و سیاست خطای اسکریپت تنظیمشده روی صدور هشدار هنگام تشخیص خطاهای فایل دستهای msvc:
env = environment(MSVC_VERSION='14.3', MSVC_SCRIPT_ARGS=['8.1', 'store', '-vcvars_ver=14.1'], MSVC_SCRIPTERROR_POLICY='warn')
env.Program('hello', ['hello.c'], CCFLAGS='/MD', LIBS=['kernel32', 'user32', 'runtimeobject'])
مثال ۲ - بخشی از خروجی:
...
scons: warning: vc script errors detected:
[ERROR:vcvars.bat] The UWP Application Platform requires a Windows 10 SDK.
[ERROR:vcvars.bat] WindowsSdkDir = "C:\Program Files (x86)\Windows Kits\8.1\"
[ERROR:vcvars.bat] host/target architecture is not supported : { x64 , x64 }
...
link /nologo /OUT:_build001\hello.exe kernel32.lib user32.lib runtimeobject.lib _build001\hello.obj
LINK : fatal error LNK1104: cannot open file 'MSVCRT.lib'
جزئیات مهم استفاده:
جدید در نسخه 4.4
MSVC_SDK_VERSION
مقادیر معتبر برای $MSVC_SDK_VERSION عبارتند از: None یا رشتهای شامل نسخهٔ درخواستی SDK (برای نمونه، '10.0.20348.0').
هنگامی که مقدار برابر با None یا یک رشتهٔ خالی باشد، $MSVC_SDK_VERSION نادیده گرفته میشود. شرایط اعتبارسنجی زیر اعمال نمیشوند.
در صورت برقراری هر یک از شرایط زیر، یک استثنا ایجاد میشود:
مثال ۱ - ساخت Visual Studio 2022 با یک نسخهٔ مشخص از Windows SDK:
env = Environment(MSVC_VERSION='14.3', MSVC_SDK_VERSION='10.0.20348.0')
مثال ۲ - ساخت Visual Studio 2022 با یک نسخهٔ مشخص از SDK برای Universal Windows Platform:
env = Environment(MSVC_VERSION='14.3', MSVC_SDK_VERSION='10.0.20348.0', MSVC_UWP_APP=True)
نکات مهم استفاده:
جدید در نسخهٔ 4.4
MSVC_SPECTRE_LIBS
مقادیر معتبر برای $MSVC_SPECTRE_LIBS عبارتند از: True، False یا None.
هنگامی که $MSVC_SPECTRE_LIBS فعال باشد (یعنی True)، محیط Microsoft Visual C++ شامل مسیرهای پیادهسازیهای تخفیفیافته در برابر spectre از کتابخانههای Microsoft Visual C++ خواهد بود.
در صورت برقرار بودن هر یک از شرایط زیر، یک استثنا رخ میدهد:
مثال - یک ساخت Visual Studio 2022 با کتابخانههای Microsoft Visual C++ تخفیفیافته در برابر spectre:
env = Environment(MSVC_VERSION='14.3', MSVC_SPECTRE_LIBS=True)
جزئیات مهم استفاده:
جدید در نسخه 4.4
MSVC_TOOLSET_VERSION
مشخص کردن $MSVC_TOOLSET_VERSION بر تشخیص خودکار و انتخاب نمونههای msvc تأثیری ندارد. متغیر $MSVC_TOOLSET_VERSION پس از انتخاب یک نمونه msvc اعمال میشود. اگر $MSVC_VERSION مشخص نشده باشد، این میتواند نسخه پیشفرض msvc باشد.
مقادیر معتبر برای $MSVC_TOOLSET_VERSION عبارتند از: None یا رشتهای حاوی نسخه مجموعه ابزار درخواستی (مانند '14.29').
هنگامی که مقدار None و یا رشتهای خالی باشد، $MSVC_TOOLSET_VERSION نادیده گرفته میشود. شرایط اعتبارسنجی زیر اعمال نخواهند شد.
در صورت برقرار بودن هر یک از شرایط زیر، یک استثنا رخ میدهد:
جزئیات انتخاب مجموعهابزار:
در آخرین انتشار Visual Studio، نسخهٔ پیشفرض مجموعهابزار Microsoft Visual C++ لزوماً مجموعهابزاری با بزرگترین شماره نسخه نیست.
مثال ۱ - ساخت پیشفرض Visual Studio با مشخص کردن نسخهٔ جزئی مجموعهابزار:
env = Environment(MSVC_TOOLSET_VERSION='14.2')
مثال ۲ - ساخت پیشفرض Visual Studio با مشخص کردن نسخهٔ جزئی مجموعهابزار:
env = Environment(MSVC_TOOLSET_VERSION='14.29')
مثال ۳ - ساخت Visual Studio 2022 با مشخص کردن نسخهٔ کامل مجموعهابزار:
env = Environment(MSVC_VERSION='14.3', MSVC_TOOLSET_VERSION='14.29.30133')
مثال ۴ - ساخت Visual Studio 2022 با مشخص کردن نسخهٔ مجموعهابزار SxS:
env = Environment(MSVC_VERSION='14.3', MSVC_TOOLSET_VERSION='14.29.16.11')
جزئیات مهم استفاده:
جدید در نسخهٔ 4.4
MSVC_USE_SCRIPT
اگر روی نام یک فایل .bat مربوط به Visual Studio (مانند vcvars.bat) تنظیم شود، SCons آن فایل دستهای را به جای فایل تشخیصدادهشده بهطور خودکار اجرا کرده و متغیرهای مرتبط (معمولاً %INCLUDE%، %LIB% و %PATH%) را برای ارائه به فرآیند ساخت از نتیجه استخراج میکند. این ویژگی میتواند برای اجبار به استفاده از نسخهای از کامپایلر که SCons آن را تشخیص نمیدهد مفید باشد. $MSVC_USE_SCRIPT_ARGS آرگومانهای ارسالشده به این اسکریپت را فراهم میکند.
تنظیم $MSVC_USE_SCRIPT روی None تشخیص خودکار Visual Studio را بهطور کامل دور میزند؛ اگر SCons را در یک پنجره cmd مربوط به Visual Studio اجرا میکنید و متغیرهای محیطی پوسته را وارد مینمایید - یعنی اگر مطمئن هستید همهچیز از قبل بهدرستی تنظیم شده و نمیخواهید SCons چیزی را تغییر دهد - از این حالت استفاده کنید.
$MSVC_USE_SCRIPT متغیرهای $MSVC_VERSION و $TARGET_ARCH را نادیده میگیرد.
تغییریافته در نسخه 4.4: متغیر جدید $MSVC_USE_SCRIPT_ARGS روشی برای ارسال آرگومانها فراهم میکند.
MSVC_USE_SCRIPT_ARGS
جدید در نسخه 4.4
MSVC_USE_SETTINGS
$MSVC_USE_SETTINGS در صورتی که $MSVC_USE_SCRIPT تعریف شده باشد و/یا زمانی که $MSVC_USE_SETTINGS روی None تنظیم شده باشد، نادیده گرفته میشود.
این دیکشنری برای مقداردهی متغیرهای مربوطه در محیط (معمولاً %INCLUDE%، %LIB% و %PATH%) جهت ارائه به فرآیند ساخت استفاده میشود. این قابلیت میتواند برای اجبار به استفاده از محیط کامپایلری که SCons آن را بهدرستی پیکربندی نمیکند، مفید باشد. این روش جایگزینی برای پیکربندی دستی محیط در هنگام دور زدن کامل تشخیص خودکار Visual Studio از طریق تنظیم $MSVC_USE_SCRIPT روی None است.
در ادامه نمونهای از پیکربندی یک محیط ساخت با استفاده از کامپایلر Microsoft Visual C++ موجود در Microsoft SDK روی یک میزبان ۶۴ بیتی و ساخت برای یک معماری ۶۴ بیتی آورده شده است:
# Microsoft SDK 6.0 (MSVC 8.0): 64-bit host and 64-bit target
msvc_use_settings = {
"PATH": [
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Bin\\x64",
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Bin\\x64",
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Bin",
"C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727",
"C:\\Windows\\system32",
"C:\\Windows",
"C:\\Windows\\System32\\Wbem",
"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\"
],
"INCLUDE": [
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Include",
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Include\\Sys",
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Include",
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Include\\gl",
],
"LIB": [
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Lib\\x64",
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Lib\\x64",
],
"LIBPATH": [],
"VSCMD_ARG_app_plat": [],
"VCINSTALLDIR": [],
"VCToolsInstallDir": []
}
# Specifying MSVC_VERSION is recommended
env = Environment(MSVC_VERSION='8.0', MSVC_USE_SETTINGS=msvc_use_settings)
جزئیات مهم در استفاده:
جدید در نسخه 4.4
MSVC_UWP_APP
مقادیر معتبر برای $MSVC_UWP_APP عبارتاند از: True، '1'، False، '0' یا None.
هنگامی که $MSVC_UWP_APP فعال باشد (یعنی True یا '1')، محیط Microsoft Visual C++ بهگونهای برپا خواهد شد که به کتابخانههای سازگار با Windows Store و زمانهای اجرای (runtimes) Microsoft Visual C++ اشاره کند. با این کار، هر کتابخانهای که ساخته شود میتواند در یک UWP App استفاده شده و در Windows Store منتشر شود.
در صورت برقراری هر یک از شرایط زیر، یک استثنا (exception) ایجاد میشود:
مثال - ساخت Visual Studio 2022 برای Universal Windows Platform:
env = Environment(MSVC_VERSION='14.3', MSVC_UWP_APP=True)
جزئیات مهم استفاده:
MSVC_VERSION
نکته
برای اعمال شدن، $MSVC_VERSION باید پیش از شناسایی اولیه کامپایلر Microsoft Visual C++ تنظیم شود. شناسایی کامپایلر در دیرترین حالت، در اولین فراخوانی تابع Environment اتفاق میافتد، مگر اینکه فهرست tools مشخص شده باشد که کل زنجیره ابزار Microsoft Visual C++ را مستثنی کند - یعنی، "defaults" و هر ماژول ابزار خاصی را که به بخشهایی از این زنجیره ابزار اشاره دارد (شامل msvc، mslink، masm، midl و msvs) حذف نماید. در این حالت، شناسایی تا زمانی که یکی از آن ماژولهای ابزار بهصورت دستی فراخوانی شود به تعویق میافتد. دو مثال زیر این موضوع را نشان میدهند:
# MSVC_VERSION set as Environment is created
env = Environment(MSVC_VERSION='14.2')
# Initialization deferred with empty tools, triggered manually
env = Environment(tools=[])
env['MSVC_VERSION'] = '14.2
env.Tool('msvc')
env.Tool('mslink')
env.Tool('msvs')
جدول زیر تطابق مقادیر $MSVC_VERSION را با شناسههای مختلف نسخه نشان میدهد ('x' بهعنوان یک جاینگهدار برای یک رقم متغیر استفاده میشود).
| کلید SCons | نسخه Visual C++ | _MSVC_VER | محصول Visual Studio | MSBuild / Visual Studio |
| "14.5" | 14.5x | 195x | Visual Studio 2026 | 18.x |
| "14.3" | 14.3x | 193x | Visual Studio 2022 | 17.x, 17.1x |
| "14.2" | 14.2x | 192x | Visual Studio 2019 | 16.x, 16.1x |
| "14.1" | 14.1 یا 14.1x | 191x | Visual Studio 2017 | 15.x |
| "14.1Exp" | 14.1 یا 14.1x | 191x | Visual Studio 2017 Express | 15.x |
| "14.0" | 14.0 | 1900 | Visual Studio 2015 | 14.0 |
| "14.0Exp" | 14.0 | 1900 | Visual Studio 2015 Express | 14.0 |
| "12.0" | 12.0 | 1800 | Visual Studio 2013 | 12.0 |
| "12.0Exp" | 12.0 | 1800 | Visual Studio 2013 Express | 12.0 |
| "11.0" | 11.0 | 1700 | Visual Studio 2012 | 11.0 |
| "11.0Exp" | 11.0 | 1700 | Visual Studio 2012 Express | 11.0 |
| "10.0" | 10.0 | 1600 | Visual Studio 2010 | 10.0 |
| "10.0Exp" | 10.0 | 1600 | Visual C++ Express 2010 | 10.0 |
| "9.0" | 9.0 | 1500 | Visual Studio 2008 | 9.0 |
| "9.0Exp" | 9.0 | 1500 | Visual C++ Express 2008 | 9.0 |
| "8.0" | 8.0 | 1400 | Visual Studio 2005 | 8.0 |
| "8.0Exp" | 8.0 | 1400 | Visual C++ Express 2005 | 8.0 |
| "7.1" | 7.1 | 1300 | Visual Studio .NET 2003 | 7.1 |
| "7.0" | 7.0 | 1200 | Visual Studio .NET 2002 | 7.0 |
| "6.0" | 6.0 | 1100 | Visual Studio 6.0 | 6.0 |
نکته
MSVS
VERSION
VERSIONS
VCINSTALLDIR
VSINSTALLDIR
FRAMEWORKDIR
FRAMEWORKVERSIONS
FRAMEWORKVERSION
FRAMEWORKSDKDIR
PLATFORMSDKDIR
PLATFORMSDK_MODULES
اگر مقداری تنظیم نشده باشد، در رجیستری در دسترس نبوده است. Visual Studio 2017 و نسخههای جدیدتر برای ذخیرهسازی اصلی این اطلاعات از رجیستری استفاده نمیکنند، بنابراین معمولاً برای این نسخهها فقط PROJECTSUFFIX و SOLUTIONSUFFIX تنظیم خواهند شد.
MSVS_ARCH
مقدار پیشفرض x86 است. amd64 نیز برای بیشتر نسخههای Visual Studio توسط SCons پشتیبانی میشود. از Visual Studio 2015 معماری arm پشتیبانی میشود، و از Visual Studio 2017 معماری arm64 پشتیبانی میشود. تلاش برای تنظیم $MSVS_ARCH روی معماریای که برای یک نسخه مشخص از Visual Studio پشتیبانی نمیشود، خطایی ایجاد خواهد کرد.
MSVS_PROJECT_GUID
MSVS_SCC_AUX_PATH
MSVS_SCC_CONNECTION_ROOT
MSVS_SCC_PROJECT_NAME
MSVS_SCC_PROVIDER
MSVS_VERSION
اگر $MSVS_VERSION تنظیم نشده باشد، SCons (به طور پیشفرض) آخرین نسخه Visual Studio نصبشده بر روی سیستم شما را انتخاب خواهد کرد. بنابراین، اگر نسخههای 6 و 7 (MSVS .NET) نصب شده باشند، نسخه 7 را ترجیح خواهد داد. شما میتوانید با مشخص کردن متغیر $MSVS_VERSION هنگام مقداردهی اولیه Environment و تنظیم آن روی نسخه مناسب (برای نمونه '6.0' یا '7.0')، این مقدار را بازنویسی کنید. اگر نسخه مشخصشده نصب نشده باشد، مقداردهی اولیه ابزار با شکست مواجه خواهد شد.
از نسخه 1.3.0 منسوخ شده است: $MSVS_VERSION منسوخ شده و به جای آن استفاده از $MSVC_VERSION توصیه میشود. به عنوان یک راهکار کمکی در دوره گذار، اگر $MSVS_VERSION تنظیم شده باشد و $MSVC_VERSION تنظیم نشده باشد، $MSVC_VERSION با مقدار $MSVS_VERSION مقداردهی اولیه خواهد شد. در صورتی که هر دو تنظیم شده باشند و مقادیر متفاوتی داشته باشند، یک خطا ایجاد میشود.
MSVSBUILDCOM
MSVSCLEANCOM
MSVSENCODING
MSVSPROJECTCOM
MSVSPROJECTSUFFIX
MSVSREBUILDCOM
MSVSSCONS
MSVSSCONSCOM
MSVSSCONSCRIPT
MSVSSCONSFLAGS
MSVSSOLUTIONCOM
MSVSSOLUTIONSUFFIX
MT
MTEXECOM
MTFLAGS
MTSHLIBCOM
MWCW_VERSION
MWCW_VERSIONS
NAME
سازندهٔ Package را ببینید.
NINJA_ALIAS_NAME
NINJA_CMD_ARGS
این مقدار را میتوان از طریق خط فرمان نیز ارسال کرد:
scons NINJA_CMD_ARGS=-v or scons NINJA_CMD_ARGS="-v -j 3"
NINJA_COMPDB_EXPAND
ابزار compdb در Ninja پرچم -x را در Ninja V1.9.0 اضافه کرد.
NINJA_DEPFILE_PARSE_FORMAT
NINJA_DIR
NINJA_DISABLE_AUTO_RUN
اگر بهصراحت تنظیم نشده باشد، در صورتی که --disable_execute_ninja یا SetOption('disable_execute_ninja', True) دیده شود، این متغیر روی True تنظیم خواهد شد.
NINJA_ENV_VAR_CACHE
این مقدار با شل (shell) پیشفرض سیستمعامل سازگار خواهد بود.
اگر بهصراحت تنظیم نشده باشد، SCons آن را بهطور پویا از محیط اجرای ذخیرهشده در محیط ساخت فعلی (مثلاً env['ENV']) در جاهایی که آن مقادیر با شل موجود تفاوت دارند، تولید خواهد کرد.
NINJA_FILE_NAME
NINJA_FORCE_SCONS_BUILD
NINJA_GENERATED_SOURCE_ALIAS_NAME
NINJA_GENERATED_SOURCE_SUFFIXES
NINJA_MSVC_DEPS_PREFIX
NINJA_POOL
NINJA_REGENERATE_DEPS
_NINJA_REGENERATE_DEPS_FUNC
NINJA_SCONS_DAEMON_KEEP_ALIVE
NINJA_SCONS_DAEMON_PORT
NINJA_SYNTAX
no_import_lib
OBJPREFIX
OBJSUFFIX
PACKAGEROOT
سازندهٔ Package را ببینید.
PACKAGETYPE
$PACKAGETYPE میتواند با گزینهٔ خط فرمان --package-type بازنویسی شود.
سازندهٔ Package را ببینید.
PACKAGEVERSION
سازندهٔ Package را ببینید.
PCH
env['PCH'] = File('StdAfx.pch')
env['PCH'] = env.PCH('pch.cc')[0]
PCHCOM
PCHCOMSTR
PCHPDBFLAGS
PCHSTOP
env['PCHSTOP'] = 'StdAfx.h'
PDB
env['PDB'] = 'hello.pdb'
سوییچ کامپایلر Microsoft Visual C++ که SCons بهطور پیشفرض برای تولید اطلاعات PDB استفاده میکند /Z7 است. این سوییچ با ساختهای موازی (-j) به درستی کار میکند زیرا برخلاف بهاشتراکگذاری یک فایل PDB واحد بین چندین فایل شیء، اطلاعات اشکالزدایی را درون فایلهای شیء میانی جاسازی میکند. این روش همچنین تنها راه برای گنجاندن اطلاعات اشکالزدایی درون یک کتابخانهٔ ایستا است. استفاده از /Zi به جای آن ممکن است عملکرد زمان پیوند را بهبود بخشد، هرچند ساختهای موازی دیگر کار نخواهند کرد. شما میتوانید با بازنویسی متغیر پیشفرض $CCPDBFLAGS، فایلهای PDB را با سوییچ /Zi تولید کنید؛ برای مثالهای مشخص، مدخل مربوط به آن متغیر را ببینید.
PDFLATEX
PDFLATEXCOM
PDFLATEXCOMSTR
env = Environment(PDFLATEX;COMSTR = "Building $TARGET from LaTeX input $SOURCES")
PDFLATEXFLAGS
PDFPREFIX
PDFSUFFIX
PDFTEX
PDFTEXCOM
PDFTEXCOMSTR
env = Environment(PDFTEXCOMSTR = "Building $TARGET from TeX input $SOURCES")
PDFTEXFLAGS
PKGCHK
PKGINFO
PLATFORM
env = Environment(tools=[])
if env['PLATFORM'] == 'cygwin':
Tool('mingw')(env)
else:
Tool('msvc')(env)
POAUTOINIT
POCREATE_ALIAS
POSUFFIX
POTDOMAIN
POTSUFFIX
POTUPDATE_ALIAS
POUPDATE_ALIAS
PRINT_CMD_LINE_FUNC
هر یک یا همهٔ آرگومانها را میتوان برای ایجاد پیام به کار برد. source و target فهرستهایی از گرهها خواهند بود و باید برای چاپ به شکل مناسبی تبدیل شوند (نمونه را ببینید). حالت پیشفرض که در صورت تنظیم نشدن متغیر یا تنظیم آن روی None استفاده میشود، تنها چاپ رشتهٔ s است که معادل است با:
def print_cmd_line(s, target, source, env):
sys.stdout.write(s + "\n")
این نمونه از پارامترهای source و target برای قالببندی یک پیام سفارشی استفاده میکند:
def print_cmd_line(s, target, source, env):
sys.stdout.write(
"Building %s -> %s...\n"
% (
' and '.join([str(x) for x in source]),
' and '.join([str(x) for x in target]),
)
)
env = Environment(PRINT_CMD_LINE_FUNC=print_cmd_line)
env.Program('foo', ['foo.c', 'bar.c'])
این موارد را چاپ میکند:
... scons: Building targets ... Building bar.c -> bar.o... Building foo.c -> foo.o... Building foo.o and bar.o -> foo... scons: done building targets.
کاربرد احتمالی دیگر برای یک تابع چاپ، نمایش پیامی بسیار مختصر در کنسول و همزمان ثبت کامل خط فرمان در یک فایل است.
PROGEMITTER
PROGPREFIX
PROGSUFFIX
PSCOM
PSCOMSTR
PSPREFIX
PSSUFFIX
RANLIB
RANLIBCOM
RANLIBCOMSTR
env = Environment(RANLIBCOMSTR = "Indexing $TARGET")
RANLIBFLAGS
RC
RCCOM
RCCOMSTR
RCFLAGS
RCINCFLAGS
RCINCPREFIX
RCINCSUFFIX
RDirs
REGSVR
REGSVRCOM
REGSVRCOMSTR
REGSVRFLAGS
RMIC
RMICCOM
RMICCOMSTR
env = Environment(
RMICCOMSTR="Generating stub/skeleton class files $TARGETS from $SOURCES"
)
RMICFLAGS
RPATH
_RPATH
RPATHPREFIX
RPATHSUFFIX
RPCGEN
RPCGENCLIENTFLAGS
RPCGENFLAGS
RPCGENHEADERFLAGS
RPCGENSERVICEFLAGS
RPCGENXDRFLAGS
SCANNERS
SCONS_HOME
SHCC
SHCCCOM
SHCCCOMSTR
env = Environment(SHCCCOMSTR = "Compiling shared object $TARGET")
SHCCFLAGS
SHCFLAGS
SHCXX
SHCXXCOM
SHCXXCOMSTR
env = Environment(SHCXXCOMSTR = "Compiling shared object $TARGET")
SHCXXFLAGS
SHDC
SHDCOM
SHDCOMSTR
SHDLIBVERSIONFLAGS
SHDLINK
SHDLINKCOM
SHDLINKFLAGS
SHELL
SHELL_ENV_GENERATORS
این مقدار باید فهرستی (یا پیمایشپذیر دیگری) از توابعی باشد که هر کدام دیکشنریِ محیط اجرا را تولید کرده یا تغییر میدهند. به نخستین تابع، رونوشتی از محیط اجرای اولیه ($ENV در محیط ساخت جاری) داده میشود؛ دیکشنری بازگرداندهشده توسط آن تابع به تابع بعدی داده میشود، تا زمانی که تمام توابع اجرا شوند و نتیجه برای استفاده توسط اجراکنندهٔ فرمان بازگردانده شود. محیط اجرای اصلی دستنخورده باقی میماند.
هر تابعی که در $SHELL_ENV_GENERATORS ارائه میشود باید چهار آرگومان بپذیرد و یک دیکشنری بازگرداند: env محیط ساخت برای این کنش است؛ target فهرست هدفهای مرتبط با این کنش است؛ source فهرست منابع مرتبط با این کنش است؛ و shell_env دیکشنری فعلی پس از اجرای توابع قبلی در $SHELL_ENV_GENERATORS است (میتوان این مقدار را با محیط اجرای اولیه که به صورت env['ENV'] در دسترس است مقایسه کرد تا هرگونه تغییر تشخیص داده شود).
مثال:
def custom_shell_env(env, target, source, shell_env):
"""customize shell_env if desired"""
if str(target[0]) == 'special_target':
shell_env['SPECIAL_VAR'] = env.subst('SOME_VAR', target=target, source=source)
return shell_env
env["SHELL_ENV_GENERATORS"] = [custom_shell_env]
از نسخهٔ 4.4 در دسترس است
SHF03
SHF03COM
SHF03COMSTR
SHF03FLAGS
SHF03PPCOM
SHF03PPCOMSTR
SHF08
SHF08COM
SHF08COMSTR
SHF08FLAGS
SHF08PPCOM
SHF08PPCOMSTR
SHF77
SHF77COM
SHF77COMSTR
SHF77FLAGS
SHF77PPCOM
SHF77PPCOMSTR
SHF90
SHF90COM
SHF90COMSTR
SHF90FLAGS
SHF90PPCOM
SHF90PPCOMSTR
SHF95
SHF95COM
SHF95COMSTR
SHF95FLAGS
SHF95PPCOM
SHF95PPCOMSTR
SHFORTRAN
SHFORTRANCOM
SHFORTRANCOMSTR
SHFORTRANFLAGS
SHFORTRANPPCOM
SHFORTRANPPCOMSTR
SHLIBEMITTER
SHLIBNOVERSIONSYMLINKS
SHLIBPREFIX
_SHLIBSONAME
SHLIBSUFFIX
SHLIBVERSION
_SHLIBVERSIONFLAGS
SHLIBVERSIONFLAGS
SHLINK
در سیستمهای POSIX (سیستمهایی که از ابزار link استفاده میکنند)، معمولاً نباید این مقدار را تغییر دهید زیرا پیشفرض آن یک ابزار پیونددهنده “هوشمند” است که راهانداز کامپایلر متناسب با نوع فایلهای منبع مورد استفاده را انتخاب میکند. بنابراین بهعنوان مثال، اگر $SHCXX را روی نام یک کامپایلر خاص تنظیم کنید و در حال کامپایل منابع C++ باشید، تابع smartlink بهطور خودکار همان کامپایلر را برای پیوند دادن انتخاب میکند.
SHLINKCOM
SHLINKCOMSTR
env = Environment(SHLINKCOMSTR = "Linking shared $TARGET")
SHLINKFLAGS
SHOBJPREFIX
SHOBJSUFFIX
SONAME
# Will cause libtest.so.2 to exist and be a symlink to libtest.so.0.1.2
env.SharedLibrary('test', 'test.c', SHLIBVERSION='0.1.2', SONAME='libtest.so.2')
این متغیر توسط زنجیرههای ابزاری که از شیءهای اشتراکی نسخهدار پشتیبانی میکنند استفاده میشود.
SOURCE
SOURCE_URL
سازنده Package را ببینید.
SOURCES
SOVERSION
# SONAME will be libtest.so.2, and will be a symlink to libtest.so.0.1.2
env.SharedLibrary('test', 'test.c', SHLIBVERSION='0.1.2', SOVERSION='2')
این متغیر توسط زنجیرههای ابزاری که از شیءهای اشتراکی نسخهدار پشتیبانی میکنند استفاده میشود.
SPAWN
def spawn(shell, escape, cmd, args, env):
shell رشتهای است که نام برنامه پوسته مورد استفاده را مشخص میکند، escape تابعی است که میتواند برای گریز دادن نویسههای ویژه پوسته در خط فرمان فراخوانی شود، cmd مسیر دستوری است که باید اجرا شود، args شامل آرگومانهای دستور است و env واژهنامهای از متغیرهای محیطی است که محیط اجرایی دستور را تعریف میکند.
STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME
SUBST_DICT
SUBSTFILEPREFIX
SUBSTFILESUFFIX
SUMMARY
سازندهٔ Package را ببینید.
SWIG
SWIGCFILESUFFIX
SWIGCOM
SWIGCOMSTR
SWIGCXXFILESUFFIX
SWIGDIRECTORSUFFIX
SWIGFLAGS
_SWIGINCFLAGS
SWIGINCPREFIX
SWIGINCSUFFIX
SWIGOUTDIR
SWIGPATH
آرگومانهای دایرکتوری include را صریحاً در $SWIGFLAGS قرار ندهید؛ نتیجه غیرقابلحمل خواهد بود و دایرکتوریها توسط پویندهٔ وابستگی جستجو نخواهند شد. نکته: نامهای دایرکتوری در $SWIGPATH هنگامی که در یک فرمان استفاده میشوند، نسبت به دایرکتوری SConscript جستجو خواهند شد. برای وادار کردن scons به جستجوی یک دایرکتوری نسبت به ریشهٔ درخت کد منبع، از مسیر نسبی به ریشه (#) استفاده کنید:
env = Environment(SWIGPATH='#/include')
همچنین میتوان جستجوی دایرکتوری را با استفاده از تابع Dir() اجبار کرد:
include = Dir('include')
env = Environment(SWIGPATH=include)
فهرست دایرکتوریها از طریق متغیر ساخت بهطور خودکار تولیدشدهٔ $_SWIGINCFLAGS به خطوط فرمان اضافه خواهد شد، که با الحاق مقادیر متغیرهای ساخت $SWIGINCPREFIX و $SWIGINCSUFFIX به ترتیب به ابتدا و انتهای هر دایرکتوری در $SWIGPATH ساخته میشود. هر خط فرمانی که تعریف میکنید و به فهرست دایرکتوریهای SWIGPATH نیاز دارد، باید شامل $_SWIGINCFLAGS باشد:
env = Environment(SWIGCOM="my_swig -o $TARGET $_SWIGINCFLAGS $SOURCES")
SWIGVERSION
TAR
TARCOM
TARCOMSTR
env = Environment(TARCOMSTR = "Archiving $TARGET")
TARFLAGS
TARGET
TARGET_ARCH
در سکوی win32، اگر کامپایلر Microsoft Visual C++ در دسترس باشد، راهاندازی ابزار msvc با استفاده از $HOST_ARCH و $TARGET_ARCH انجام میشود. اگر مقداری مشخص نشده باشد، برابر با همان مقدار $HOST_ARCH تنظیم خواهد شد. تغییر مقدار پس از مقداردهی اولیه محیط باعث راهاندازی مجدد ابزار نخواهد شد. در صورتی که سامانه کامپایل از تولید برای آن هدف پشتیبانی کند، اشیاء کامپایلشده در معماری هدف خواهند بود. جدیدترین کامپایلری که بتواند این نیازمندی را برآورده کند انتخاب خواهد شد، مگر اینکه نگارش متفاوتی توسط مقدار متغیر ساخت $MSVC_VERSION تعیین شده باشد.
در ترکیب win32/msvc، مقادیر معتبر معماری هدف عبارتند از x86، arm، i386 برای هدفهای ۳۲ بیتی و amd64، arm64، x86_64 و ia64 (ایتانیوم) برای هدفهای ۶۴ بیتی. برای نمونه، اگر میخواهید باینریهای ۶۴ بیتی کامپایل کنید، هنگام ایجاد محیط ساخت، TARGET_ARCH='x86_64' را تنظیم میکنید. توجه داشته باشید که همه معماریهای هدف برای تمام نگارشهای Visual Studio / MSVC پشتیبانی نمیشوند. مستندات مربوطه مایکروسافت را بررسی کنید.
متغیر $TARGET_ARCH در حال حاضر توسط سایر ابزارهای کامپایل استفاده نمیشود، اما این گزینه برای انجام این کار در آینده رزرو شده است.
TARGET_OS
متغیر $TARGET_OS در حال حاضر توسط SCons استفاده نمیشود، اما این گزینه برای انجام این کار در آینده رزرو شده است.
TARGETS
TARSUFFIX
TEMPFILE
env["TEMPFILE"] = TempFileMunge
env["LINKCOM"] = "${TEMPFILE('$LINK $TARGET $SOURCES', '$LINKCOMSTR')}"
مقدار پیشفرض SCons برای $TEMPFILE، یعنی TempFileMunge، جایگزینی فرمان را روی خط فرمان ارسالشده انجام میدهد، بررسی میکند که آیا نیاز به تغییر وجود دارد یا خیر، سپس همه کلمات به جز کلمه نخست (که فرض میشود نام فرمان است) از فهرست حاصل را در یک فایل موقت (که گاهی response file یا command file نامیده میشود) قرار میدهد، و یک خط فرمان جدید متشکل از نام فرمان و ارجاعی با قالببندی مناسب به فایل موقت بازمیگرداند.
یک جایگزین برای شیء tempfile پیشفرض باید اساساً همان کار را انجام دهد، از جمله در نظر گرفتن مقادیر $MAXLINELENGTH، $TEMPFILEPREFIX، $TEMPFILESUFFIX، $TEMPFILEARGJOIN، $TEMPFILEDIR و $TEMPFILEARGESCFUNC. اگر مورد استفاده خاصی نیاز به تبدیلی متفاوت از پیشفرض داشته باشد، توصیه میشود سازوکار مربوطه کپی شده و یک متغیر ساخت جدید تعریف شود و متغیر(های) *COM مرتبط برای استفاده از آن بازنویسی شوند، تا از احتمال اختلال در کاربردهای موجود $TEMPFILE جلوگیری شود.
TEMPFILEARGESCFUNC
import sys
import re
from SCons.Subst import quote_spaces
WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)")
def tempfile_arg_esc_func(arg):
arg = quote_spaces(arg)
if sys.platform != "win32":
return arg
# GCC requires double Windows slashes, let's use UNIX separator
return WINPATHSEP_RE.sub(r"/\1", arg)
env["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func
TEMPFILEARGJOIN
TEMPFILEDIR
TEMPFILEENCODING
جدید در نسخه 4.10.0
TEMPFILEPREFIX
TEMPFILESUFFIX
TEX
TEXCOM
TEXCOMSTR
env = Environment(TEXCOMSTR = "Building $TARGET from TeX input $SOURCES")
TEXFLAGS
TEXINPUTS
TEXTFILEPREFIX
TEXTFILESUFFIX
TOOLS
UNCHANGED_SOURCES
UNCHANGED_TARGETS
VENDOR
سازندهٔ Package را ببینید.
VERSION
سازندهٔ Package را ببینید.
VSWHERE
فایل اجرایی vswhere.exe از نسخهٔ 2017 به بعد همراه با Microsoft Visual Studio و Build Tools عرضه میشود، اما بهصورت یک نصب مستقل نیز در دسترس است. این ابزار امکان پرسوجو برای دریافت اطلاعات دقیق دربارهٔ نسخههای نصبشدهٔ 2017 و جدیدتر را فراهم میکند. SCons از این اطلاعات برای تعیین وضعیت پشتیبانی کامپایلر از آن نسخهها استفاده میکند.
تنظیم متغیر $VSWHERE به مسیر یک فایل اجرایی vswhere.exe خاص، باعث میشود SCons از آن فایل استفاده کند. در صورت عدم تنظیم، SCons به ترتیب در مکانهای زیر به دنبال آن میگردد و از اولین مورد یافتشده استفاده میکند ($VSWHERE با این مکان بهروزرسانی میشود):
نکته
برای اینکه $VSWHERE اثرگذار باشد، باید پیش از انجام شناسایی اولیهٔ کامپایلر Microsoft Visual C++ تنظیم شود. این شناسایی در دیرترین حالت، در اولین فراخوانی تابع Environment رخ میدهد، مگر اینکه یک فهرست tools مشخص شده باشد که کل زنجیره ابزار Microsoft Visual C++ را مستثنی کند - یعنی، "defaults" و هر ماژول ابزار خاصی که به بخشهایی از این زنجیره ابزار ارجاع میدهد (msvc، mslink، masm، midl و msvs) را حذف کند. در این حالت، شناسایی تا زمانی که یکی از آن ماژولهای ابزار بهصورت دستی فراخوانی شود به تعویق میافتد. دو مثال زیر این موضوع را نشان میدهند:
# VSWHERE set as Environment is created
env = Environment(VSWHERE='c:/my/path/to/vswhere')
# Initialization deferred with empty tools, triggered manually
env = Environment(tools=[])
env['VSWHERE'] = r'c:/my/vswhere/install/location/vswhere.exe'
env.Tool('msvc')
env.Tool('mslink')
env.Tool('msvs')
WINDOWS_EMBED_MANIFEST
WINDOWS_INSERT_DEF
WINDOWS_INSERT_MANIFEST
WINDOWSDEFPREFIX
WINDOWSDEFSUFFIX
WINDOWSEXPPREFIX
WINDOWSEXPSUFFIX
WINDOWSPROGMANIFESTPREFIX
WINDOWSPROGMANIFESTSUFFIX
WINDOWSSHLIBMANIFESTPREFIX
WINDOWSSHLIBMANIFESTSUFFIX
X_IPK_DEPENDS
سازندهٔ Package را ببینید.
X_IPK_DESCRIPTION
X_IPK_MAINTAINER
X_IPK_PRIORITY
X_IPK_SECTION
X_MSI_LANGUAGE
سازندهٔ Package را ببینید.
X_MSI_LICENSE_TEXT
سازندهٔ Package را ببینید.
X_MSI_UPGRADE_CODE
X_RPM_AUTOREQPROV
سازندهٔ Package را ببینید.
X_RPM_BUILD
X_RPM_BUILDREQUIRES
X_RPM_BUILDROOT
X_RPM_CLEAN
X_RPM_CONFLICTS
X_RPM_DEFATTR
X_RPM_DISTRIBUTION
X_RPM_EPOCH
X_RPM_EXCLUDEARCH
X_RPM_EXLUSIVEARCH
X_RPM_EXTRADEFS
جدید در نگارش 3.1.
env.Package(
NAME="foo",
...
X_RPM_EXTRADEFS=[
"%define _unpackaged_files_terminate_build 0"
"%define _missing_doc_files_terminate_build 0"
],
...
)
X_RPM_GROUP
X_RPM_GROUP_lang
X_RPM_ICON
X_RPM_INSTALL
X_RPM_PACKAGER
X_RPM_POSTINSTALL
X_RPM_POSTUNINSTALL
X_RPM_PREFIX
X_RPM_PREINSTALL
X_RPM_PREP
X_RPM_PREUNINSTALL
X_RPM_PROVIDES
X_RPM_REQUIRES
X_RPM_SERIAL
X_RPM_URL
XGETTEXT
XGETTEXTCOM
XGETTEXTCOMSTR
_XGETTEXTDOMAIN
XGETTEXTFLAGS
XGETTEXTFROM
_XGETTEXTFROMFLAGS
XGETTEXTFROMPREFIX
XGETTEXTFROMSUFFIX
XGETTEXTPATH
نکته
این متغیر تنها همراه با $XGETTEXTFROM کار میکند.
_XGETTEXTPATHFLAGS
XGETTEXTPATHPREFIX
XGETTEXTPATHSUFFIX
YACC
YACC_GRAPH_FILE
جدید در نسخهٔ 4.4.0.
YACC_GRAPH_FILE_SUFFIX
پسوند فایلی که حاوی گراف ماشین خودکار دستور زبان است، هنگامی که گزینهٔ -g (یا --graph= بدون آرگومان گزینه) در $YACCFLAGS استفاده شود. توجه داشته باشید که تنظیم این متغیر به SCons اطلاع میدهد که چگونه نام فایل گراف را برای مقاصد ردیابی بسازد، و تاثیری بر نام واقعی فایل تولیدشده نمیگذارد. ابزارهای گوناگون yacc در زمانهای مختلف قالبهای متفاوتی را تولید کردهاند. این متغیر را طوری تنظیم کنید که با آنچه تولیدکنندهٔ تجزیهکنندهٔ شما تولید میکند مطابقت داشته باشد.
جدید در نسخهٔ 4.6.0.
YACC_HEADER_FILE
جدید در نسخهٔ 4.4.0.
YACCCOM
YACCCOMSTR
env = Environment(YACCCOMSTR="Yacc'ing $TARGET from $SOURCES")
YACCFLAGS
اگر گزینهٔ -d در $YACCFLAGS موجود باشد، scons فرض میکند که این فراخوانی یک فایل سرآیند نیز ایجاد خواهد کرد؛ با پسوند تعیینشده توسط $YACCHFILESUFFIX اگر فایل منبع yacc به پسوند .y ختم شود، یا فایلی با پسوند تعیینشده توسط $YACCHXXFILESUFFIX اگر فایل منبع yacc به پسوند .yy ختم شود. فایل سرآیند همان نام پایهٔ هدف درخواستی را خواهد داشت. این رفتار تنها در صورتی درست است که فایل اجرایی bison (یا win_bison) باشد. در صورت استفاده از Berkeley yacc (byacc)، همواره فایل y.tab.h نوشته میشود - در این حالت از -d اجتناب کرده و در عوض از $YACC_HEADER_FILE استفاده کنید.
اگر گزینهٔ -g موجود باشد، scons فرض میکند که فراخوانی یک فایل گراف نیز با پسوند تعیینشده توسط $YACCVCGFILESUFFIX ایجاد خواهد کرد.
اگر گزینهٔ -v موجود باشد، scons فرض میکند که فراخوانی یک فایل خروجی اشکالزدایی با پسوند .output نیز ایجاد خواهد کرد.
همچنین گزینههای GNU bison شناسایی میشوند: --header (و مترادف منسوخشدهٔ آن --defines)، که مشابه -d است اما امکان نامگذاری صریح فایل سرآیند خروجی را از طریق آرگومان گزینه فراهم میسازد؛ و --graph، که مشابه -g است اما امکان نامگذاری صریح فایل گراف خروجی را از طریق یک آرگومان گزینه فراهم میکند. در صورتی که این گزینهها در قالب option=argument استفاده شوند، پسوندهای فایل توصیفشده برای -d و -g در بالا اعمال نخواهند شد.
توجه داشته باشید که فایلهای مشخصشده با --header= و --graph= ممکن است در همهٔ شرایط بهدرستی توسط SCons مدیریت نشوند و استفاده از آنها در $YACCFLAGS باید صرفاً به عنوان پشتیبانی از روشهای قدیمی در نظر گرفته شود. اگر نیاز به نامگذاری صریح فایلها دارید، استفاده از $YACC_HEADER_FILE و $YACC_GRAPH_FILE را در نظر بگیرید (جدید در نسخهٔ 4.4.0).
YACCHFILESUFFIX
YACCHXXFILESUFFIX
YACCVCGFILESUFFIX
تغییریافته در نسخه 4.6.0: منسوخ شد. مقدار پیشفرض از .vcg تغییر یافت (تولید خروجی .vcg توسط bison از نسخه 2.4 در سال 2006 متوقف شد).
ZIP
ZIP_OVERRIDE_TIMESTAMP
ZIPCOM
ZIPCOMPRESSION
ZIPCOMSTR
env = Environment(ZIPCOMSTR = "Zipping $TARGET")
ZIPFLAGS
ZIPROOT
env = Environment()
env.Zip('foo.zip', 'subdir1/subdir2/file1', ZIPROOT='subdir1')
یک فایل zip با نام foo.zip تولید خواهد کرد که حاوی فایلی با نام subdir2/file1 بهجای subdir1/subdir2/file1 است.
ZIPSUFFIX
بافتهای پیکربندی (Configure Contexts)
SCons یک سازوکار پیکربندی خودکارِ یکپارچه (الهامگرفته از GNU Autoconf اما درونیِ SCons) برای بررسی وجود موارد خارجیِ مورد نیاز ساخت، مانند فایلهای سرایند C، کتابخانهها و غیره ارائه میدهد. این سازوکار میتواند برای ساخت ویژگیهای اختیاری تنها در صورت در دسترس بودن پشتیبانی آنها، لغو سریع ساخت در صورت مفقود بودن عناصر ضروری، یا صرفاً تنظیم ساخت متناسب با بستر ساختِ مشخص مورد استفاده قرار گیرد. این سازوکار در میان بسترهای مختلف، قابلحمل (portable) است.
شما سیستم پیکربندی را با ایجاد یک بافت پیکربندی (configure context) فعال میکنید که اطلاعات گردآوریشده را در حین انجام بررسیها نگهداری کرده، بررسیهای مورد نظر را درخواست میکند و سپس اطلاعات را به محیط ساخت عادی انتقال میدهد. همچنین بهصورت اختیاری، یک سرایند پیکربندی که کدهای C یا C++ میتوانند آن را درج (include) کنند، میتواند تولید شود. SCons (برخلاف Autoconf) یک حافظهٔ نهان (cache) صریح از مقادیر آزمایششده نگهداری نمیکند، بلکه از سازوکار عادیِ ردیابی وابستگیهای خود برای بهروز نگه داشتن مقادیر بررسیشده استفاده میکند. شما میتوانید این رفتار را با گزینهٔ خط فرمان --config بازنویسی (override) کنید.
Configure(env, [custom_tests, conf_dir, log_file, config_h, clean, help]), env.Configure([custom_tests, conf_dir, log_file, config_h, clean, help])
custom_tests یک دیکشنری شامل بررسیهای سفارشی را مشخص میکند (جزئیات را در ادامه ببینید). مقدار پیشفرض None است که نشاندهندهٔ عدم وجود بررسیهای سفارشی در بافت پیکربندی است.
conf_dir دایرکتوریای را مشخص میکند که موارد آزمایشی در آن ساخته میشوند. این دایرکتوری برای ساخت اهداف عادی استفاده نمیشود. مقدار پیشفرض “#/.sconf_temp” است.
log_file فایلی را مشخص میکند که خروجی دستورات اجرا شده برای بررسی وجود فایلهای سرایند، کتابخانهها و غیره را جمعآوری میکند. مقدار پیشفرض “#/config.log” است. اگر از دایرکتوریهای متغیر (variant directories) استفاده میکنید، ممکن است بخواهید فایل گزارش را برای یک ساخت مشخص، زیر دایرکتوری متغیرِ همان ساخت قرار دهید.
config_h یک فایل سرایند C را مشخص میکند که نتایج آزمایشها در آن نوشته خواهد شد، تا فرآیند ساخت با درج (include) کردن آن به این اطلاعات دسترسی داشته باشد. نتایج شامل خطوطی مانند #define HAVE_GETADDRINFO 1, #define HAVE_INTTYPES_H 1 و غیره خواهند بود. مقدار پیشفرض None است که هیچ سرایند پیکربندیای ایجاد نمیکند. عرف بر این بوده است که این سرایند پیکربندی config.h نامیده شود. میتوانید فایل config_h یکسانی را در فراخوانیهای متعدد Configure مشخص کنید، که در این صورت SCons تمام نتایج را در فایل مشخصشده الحاق خواهد کرد. توجه داشته باشید که SCons از سازوکار عادیِ ردیابی وابستگیهای خود برای تصمیمگیری در مورد لزوم بازسازی سرایند پیکربندی استفاده میکند. این بدان معناست که این فایل لزوماً با هر بار اجرای scons بازسازی نمیشود، بلکه تنها در صورتی بازسازی میشود که محتویات آن تغییر کرده باشد و هدفی وابسته به سرایند پیکربندی در حال ساخت باشد.
آرگومانهای clean و help میتوانند برای جلوگیری از اجرای آزمایشهای پیکربندی، بهترتیب هنگام استفاده از گزینههای -c/--clean یا -H/-h/--help استفاده شوند. رفتار پیشفرض همیشه اجرای آزمایشهای بافت پیکربندی است، زیرا نتایج آزمایشها ممکن است بر فهرست اهداف پاکسازیشونده یا متن راهنما تأثیر بگذارد. اگر آزمایشهای پیکربندی بر این موارد تأثیری ندارند، میتوانید آرگومانهای clean=False یا help=False (یا هر دو) را اضافه کنید تا از اجرای غیرضروری آزمایشها جلوگیری شود.
تغییر یافته در نسخهٔ 4.0: در صورت تلاش برای ایجاد یک بافت جدید در حالی که یک بافت فعال وجود دارد، یک استثنا صادر میکند.
context.Finish()
مثالی از یک کاربرد متداول Configure:
env = Environment()
conf = Configure(env)
if not conf.CheckCHeader("math.h"):
print("We really need math.h!")
Exit(1)
if conf.CheckLibWithHeader("qt", "qapp.h", "c++", call="QApplication qapp(0,0);"):
# do stuff for qt - usage, e.g.
conf.env.Append(CPPDEFINES="WITH_QT")
env = conf.Finish()
یک بافت پیکربندی متدهای از پیش تعریفشدهٔ زیر را دارد که میتوانند برای انجام بررسیها استفاده شوند. در جاهایی که language یک پارامتر اختیاری است، زبان برنامهنویسی بررسی را مشخص میکند که در حال حاضر انتخابی بین C یا C++ است. نگارشهای قابل قبول برای C عباتاند از “C” یا “c”؛ برای C++ این مقدار میتواند “CXX”, “cxx”, “C++” یا “c++” باشد. اگر language حذف شود، “C” در نظر گرفته میشود.
context.CheckHeader(header, [include_quotes, language])
یک مقدار بولی را برمیگرداند که نشاندهندهٔ موفقیت یا شکست است. اگر یک سرایند پیکربندی درخواست شده باشد، نتیجه در صورت موفقیت بهصورت یک ماکروی پیشپردازنده، یا در صورت شکست بهصورت یک توضیح (comment) آگاهیبخش در آن ثبت میشود.
context.CheckCHeader(header, [include_quotes])
context.CheckCXXHeader(header, [include_quotes])
context.CheckFunc(function_name, [header, language, funcargs])
آرگومان اختیاری header رشتهای است که قطعه کدی را برای قرار گرفتن در بالای برنامه آزمایشی مشخص میکند که برای بررسی وجود تابع کامپایل خواهد شد. در صورت حذف، قطعه پیشفرض به این صورت خواهد بود (با جایگزینی مناسب function_name):
#ifdef __cplusplus extern "C" #endif char function_name(void);
اگر header ارائه شود، not (نباید) شامل فایل سرآیند استانداردی باشد که function_name را اعلان میکند، و should (باید) شامل یک پیشنمونه ساختگی مشابه حالت پیشفرض باشد. اگر این کار ممکن نیست، میتوان از آرگومان اختیاری funcargs برای تعیین رشتهای حاوی فهرست آرگومانها با همان تعداد و نوع آرگومانهای پیشنمونه استفاده کرد. این آرگومانها میتوانند صرفاً مقادیر ثابتی از نوع صحیح باشند. کامپایلرهای مدرن C/C++ اعلانهای ضمنی توابع را رد میکنند و همچنین ممکن است فراخوانیهای توابعی را که آرگومانهای آنها از نظر نوع با پیشنمونه سازگار نیستند، رد کنند.
یک مقدار بولی نشاندهنده موفقیت یا شکست بازمیگرداند. اگر یک سرآیند پیکربندی (configure header) درخواست شده باشد، نتیجه در صورت موفقیت به صورت یک ماکروی پیشپردازنده، یا در صورت شکست به صورت یک توضیح (comment) آگاهیبخش در آن ثبت میشود.
تغییریافته در نسخه 4.7.0: آرگومان funcargs اضافه شد.
context.CheckLib([library, symbol, header, language, extra_libs=None, autoadd=True, append=True, unique=False])
توجه داشته باشید که اگر symbol داده شود، برنامه ساختگی با یک پیشنمونه به سبک قدیمی (old-style) تولید خواهد شد، زیرا اطلاعی از پیشنمونه واقعی ندارد (برای مثال char sin(); به جای double sin(double x);). چنین استفادهای در C23 و نسخههای پس از آن دیگر مجاز نیست.
باقی آرگومانها باید به صورت کلیدواژهای مشخص شوند. اگر extra_libs مشخص شده باشد، فهرستی از کتابخانههای اضافی برای گنجاندن هنگام پیوند دادن برنامه ساختگی است (معمولاً وابستگیهای کتابخانهای که بررسی میشود). اگر autoadd درست (true، پیشفرض) باشد و پیوند موفقیتآمیز باشد، کتابخانه به متغیر ساخت $LIBS در context اضافه میشود. اگر append درست (true، پیشفرض) باشد، کتابخانه افزوده شده به انتها الحاق میشود، در غیر این صورت به ابتدا اضافه میشود. اگر unique درست (true) باشد، و در حالتی که کتابخانه باید اضافه شود اما از قبل در $LIBS در context پیکربندی وجود داشته باشد، مجدداً اضافه نخواهد شد. مقدار پیشفرض False است.
library میتواند فهرستی از نامهای کتابخانهها یا None (پیشفرض در صورت حذف آرگومان) باشد. در حالت اول، symbol به ترتیب با هر نام کتابخانه بررسی شده و با اولین آزمایش موفق، نتیجه بازگردانده میشود (و موفقیت گزارش میگردد)؛ در حالت دوم، با مقدار فعلی $LIBS بررسی میشود (در این حالت هیچ نام کتابخانهای اضافه نخواهد شد). اگر symbol حذف شود یا None باشد، آنگاه CheckLib صرفاً بررسی میکند که آیا میتوانید در برابر library مشخصشده پیوند دهید یا خیر. توجه داشته باشید که با وجود نحو معتبر، فراخوانی این متد با حذف یا None بودن همزمان library و symbol چندان کاربردی نخواهد بود - حداقل یکی از آنها باید ارائه شود.
یک مقدار بولی نشاندهنده موفقیت یا شکست بازمیگرداند.
تغییریافته در نسخه 4.5.0: پارامترهای append و unique اضافه شدند.
تغییریافته در نسخه 4.9.0: پارامتر extra_libs اضافه شد.
context.CheckLibWithHeader([library, header, language, extra_libs=None, call=None, autoadd=True, append=True, unique=False])
باقی پارامترها باید به صورت کلیدواژهای مشخص شوند. در صورت ارائه، call قطعه کدی است که به عنوان آزمایش ساختگی کامپایل میشود و جایگزین برنامه ساختگی تولیدشده بهطور خودکار میگردد. این قطعهکد باید یک عبارت معتبر در language باشد. در صورت عدم ارائه، حالت پیشفرض قابلیت پیوند در برابر library مشخصشده را بررسی میکند. extra_libs میتواند برای افزودن کتابخانههای اضافی جهت پیوند دادن استفاده شود (معمولاً وابستگیهای کتابخانه تحت آزمایش). اگر autoadd درست (true، پیشفرض) باشد، نخستین کتابخانهای که بررسی را با موفقیت بگذراند به متغیر ساخت $LIBS در context پیکربندی اضافه میشود و متد پایان مییابد. اگر append درست (true، پیشفرض) باشد، کتابخانه افزوده شده به انتها الحاق میشود، در غیر این صورت به ابتدا اضافه میشود. اگر unique درست (true) باشد، و در حالتی که کتابخانه باید اضافه شود اما از قبل در $LIBS در context پیکربندی وجود داشته باشد، مجدداً اضافه نخواهد شد. مقدار پیشفرض False است.
یک مقدار بولی نشاندهنده موفقیت یا شکست بازمیگرداند.
تغییریافته در نسخه 4.5.0: پارامترهای append و unique اضافه شدند.
تغییریافته در نسخه 4.9.0: پارامتر extra_libs اضافه شد.
context.CheckType(type_name, [includes, language])
مثال:
sconf.CheckType('foo_type', '#include "my_types.h"', 'C++')
context.CheckTypeSize(type_name, [header, language, expect])
مثال:
CheckTypeSize('short', expect=2)
تنها در صورتی اندازه 2 را برمیگرداند که short واقعاً دو بایت باشد.
context.CheckCC()
برنامه آزمایشی با همان خط فرمانی ساخته میشود که توسط سازنده Object برای فایلهای مبدأ C استفاده میشود، بنابراین با تنظیم متغیرهای ساخت مربوطه میتوان از آن برای تشخیص پذیرفته شدن یا رد شدن پرچمهای خاص کامپایلر توسط کامپایلر استفاده کرد.
context.CheckCXX()
برنامه آزمایشی با همان خط فرمانی ساخته میشود که توسط سازنده Object برای فایلهای مبدأ ++C استفاده میشود، بنابراین با تنظیم متغیرهای ساخت مربوطه میتوان از آن برای تشخیص پذیرفته شدن یا رد شدن پرچمهای خاص کامپایلر توسط کامپایلر استفاده کرد.
context.CheckSHCC()
برنامه آزمایشی با همان خط فرمانی ساخته میشود که توسط سازنده SharedObject برای فایلهای مبدأ C استفاده میشود، بنابراین با تنظیم متغیرهای ساخت مربوطه میتوان از آن برای تشخیص پذیرفته شدن یا رد شدن پرچمهای خاص کامپایلر توسط کامپایلر استفاده کرد. توجه داشته باشید که این متد ایجاد شدن یا نشدن یک کتابخانه اشتراکی/dll را بررسی نمیکند.
context.CheckSHCXX()
برنامه آزمایشی با همان خط فرمانی ساخته میشود که توسط سازنده SharedObject برای فایلهای مبدأ ++C استفاده میشود، بنابراین با تنظیم متغیرهای ساخت مربوطه میتوان از آن برای تشخیص پذیرفته شدن یا رد شدن پرچمهای خاص کامپایلر توسط کامپایلر استفاده کرد. توجه داشته باشید که این متد ایجاد شدن یا نشدن یک کتابخانه اشتراکی/dll را بررسی نمیکند.
context.CheckProg(prog_name)
context.CheckDeclaration(symbol, [includes, language])
یک مقدار بولی نشاندهنده موفقیت یا شکست را برمیگرداند.
context.CheckMember(aggregate_member, [header, language])
sconf.CheckMember('struct tm.tm_sec', '#include <time.h>')
یک مقدار بولی نشاندهنده موفقیت یا شکست را برمیگرداند.
اضافهشده در 4.4.0.
context.Define(symbol, [value, comment])
مثالها:
env = Environment()
conf = Configure(env)
# Puts the following line in the config header file:
# #define A_SYMBOL
conf.Define("A_SYMBOL")
# Puts the following line in the config header file:
# #define A_SYMBOL 1
conf.Define("A_SYMBOL", 1)
مثالهایی از قرار دادن مقادیر رشتهای در نقلقول:
env = Environment()
conf = Configure(env)
# Puts the following line in the config header file:
# #define A_SYMBOL YA
conf.Define("A_SYMBOL", "YA")
# Puts the following line in the config header file:
# #define A_SYMBOL "YA"
conf.Define("A_SYMBOL", '"YA"')
مثال شامل کامنت:
env = Environment()
conf = Configure(env)
# Puts the following lines in the config header file:
# /* Set to 1 if you have a symbol */
# #define A_SYMBOL 1
conf.Define("A_SYMBOL", 1, "Set to 1 if you have a symbol")
شما میتوانید علاوه بر استفاده از بررسیهای از پیش تعریفشده، بررسیهای سفارشی خود را نیز تعریف کنید. برای فعالسازی بررسیهای سفارشی، یک دیکشنری را به تابع Configure به عنوان پارامتر custom_tests ارسال کنید. این دیکشنری نامهای بررسیها را به فراخوانپذیرهای (callables) بررسی سفارشی (یا یک تابع Python یا نمونهای از کلاسی که متد __call__ را پیادهسازی کرده است) نگاشت میکند. هر بررسی سفارشی با یک نمونه از CheckContext به عنوان اولین پارامتر فراخوانی میشود و به دنبال آن بقیه آرگومانها که باید توسط کاربر بررسی ارائه شوند، قرار میگیرند. یک CheckContext مشابه بافت پیکربندی (configure context) نیست؛ بلکه نمونهای از کلاسی است که حاوی یک بافت پیکربندی میباشد (قابل دسترس از طریق chk_ctx.sconf). یک CheckContext متدهای زیر را ارائه میدهد که بررسیهای سفارشی میتوانند از آنها بهره ببرند:
chk_ctx.Message(text)
chk_ctx.Result(res)
chk_ctx.TryCompile(text, extension='')
chk_ctx.TryLink(text, extension='')
chk_ctx.TryRun(text, extension='')
chk_ctx.TryAction(action, [text, extension=''])
chk_ctx.TryBuild(builder, [text, extension=''])
نمونهای از پیادهسازی و استفاده از بررسیهای سفارشی:
def CheckQt(chk_ctx, qtdir):
chk_ctx.Message('Checking for qt ...')
lastLIBS = chk_ctx.env['LIBS']
lastLIBPATH = chk_ctx.env['LIBPATH']
lastCPPPATH = chk_ctx.env['CPPPATH']
chk_ctx.env.Append(LIBS='qt', LIBPATH=qtdir + '/lib', CPPPATH=qtdir + '/include')
ret = chk_ctx.TryLink(
"""\
#include <qapp.h>
int main(int argc, char **argv) {
QApplication qapp(argc, argv);
return 0;
}
"""
)
if not ret:
chkctx.env.Replace(LIBS=lastLIBS, LIBPATH=lastLIBPATH, CPPPATH=lastCPPPATH)
chkctx.Result(ret)
return ret
env = Environment()
conf = Configure(env, custom_tests={'CheckQt': CheckQt})
if not conf.CheckQt('/usr/lib/qt'):
print('We really need qt!')
Exit(1)
env = conf.Finish()
متغیرهای ساخت خط فرمان (Command-Line Construction Variables)
ابزار SCons برای کنترل چگونگی ساخت هدفها به اطلاعات ذخیرهشده در متغیرهای ساخت وابسته است. اغلب ضروری است که اطلاعات خاصی در زمان ساخت منتقل شود تا متغیرهای موجود در اسکریپتهای ساخت بازنویسی (override) شوند. این کار میتواند از طریق آرگومانهای مقداردهی متغیر در خط فرمان و/یا در فایلهای متغیرهای ذخیرهشده انجام شود.
برای مواردی که میخواهید مقادیر جدیدی را برای متغیرهای ساخت تعیین کنید، SCons یک شیء Variables فراهم میکند تا جمعآوری آنها و بهروزرسانی محیط ساخت با این مقادیر را تسهیل کند. این قابلیت به پردازش خط فرمانهایی مانند این کمک میکند:
scons VARIABLE=foo OTHERVAR=bar
متغیرهای ارائهشده در خط فرمان همیشه میتوانند با پیمایش دیکشنری ARGUMENTS یا لیست ARGLIST به صورت دستی پردازش شوند. با این حال، استفاده از یک شیء Variables به شما امکان میدهد متغیرهای مورد انتظار را توصیف کنید، تبدیل نوع لازم را انجام دهید، مطابقت مقادیر با محدودیتهای تعریفشده را اعتبارسنجی کنید، و مقادیر پیشفرض، پیامهای راهنما و نامهای مستعار را تعیین نمایید. این رویکرد رابطی مشابه مدیریت گزینهها ارائه میدهد (ببینید: AddOption). یک شیء Variables همچنین دریافت مقادیر از یک فایل متغیرهای ذخیرهشده، یا از یک دیکشنری سفارشی در یک فایل SConscript را امکانپذیر میسازد. سپس میتوان متغیرهای پردازششده را در محیط ساخت مورد نظر اعمال کرد.
از نظر مفهومی، هدفهای خط فرمان کنترل میکنند که چه چیزی ساخته شود، متغیرهای خط فرمان (و فایلهای متغیر) نحوه ساخت را مشخص میکنند، و گزینههای خط فرمان بر شیوه عملکرد SCons نظارت دارند (اگرچه SCons این تفکیک را اجباری نمیکند).
برای دریافت شیئی جهت دستکاری متغیرها، تابع سازنده Variables را فراخوانی کنید:
Variables([files, [args]])
هر یک از محتواهای نمونه فایل زیر میتواند برای تنظیم یک کامپایلر C جایگزین استفاده شود:
CC = 'my_cc'
CC = os.environ.get('CC')
اگر args مشخص شود، باید یک دیکشنری باشد. جفتهای کلید-مقدار موجود در args به جفتهای بهدستآمده از files (در صورت وجود) اضافه خواهند شد. کلیدهای args بر کلیدهای همنام در files اولویت دارند. در صورت حذف، پیشفرض دیکشنری ARGUMENTS است که متغیرهای ساخت تعیینشده در خط فرمان را نگهداری میکند. استفاده از ARGUMENTS به شما امکان میدهد تعیین کنید که اگر یک مقدار هم در خط فرمان و هم در فایل(ها) وجود داشته باشد، مقدار خط فرمان ترجیح داده شود. با این حال، هر دیکشنری دلخواهی را میتوان ارسال کرد. مثالها:
vars = Variables('custom.py')
vars = Variables('overrides.py', ARGUMENTS)
vars = Variables(None, {FOO:'expansion', BAR:7})
vars = Variables(args={FOO:'expansion', BAR:7})
فراخوانی Variables بدون هیچ آرگومانی معادل است با:
vars = Variables(files=None, args=ARGUMENTS)
یک شیء Variables ظرفی برای توصیفهای متغیر است که با فراخوانی متدهای Add یا AddVariables اضافه میشوند. توصیف یک متغیر شامل یک نام، فهرستی از نامهای مستعار برای آن نام، یک پیام راهنما، یک مقدار پیشفرض، و توابعی برای اعتبارسنجی و تبدیل مقادیر است. پردازش منابع ورودی تا زمان فراخوانی متد Update به تعویق میافتد؛ در این زمان، متغیرها با استفاده از نام خود به عنوان نام متغیر ساخت به محیط ساخت مشخصشده افزوده میشوند؛ نامهای مستعار اضافه نخواهند شد. متغیرهایی از منابع ورودی که با هیچیک از نامها یا نامهای مستعار موجود در توصیفهای متغیر این شیء مطابقت ندارند نادیده گرفته میشوند، با این تفاوت که دیکشنریای از نامها و مقادیر آنها در ویژگی unknown از شیء Variables در دسترس قرار میگیرد. این فهرست از طریق متد UnknownVariables نیز قابل دریافت است. اگر توصیف یک متغیر مقدار پیشفرضی غیر از None داشته باشد و در منابع ورودی ظاهر نشود، با مقدار پیشفرض خود به محیط ساخت افزوده میشود. فهرستی از متغیرهایی که از مقادیر پیشفرضشان تنظیم شدهاند و نه از منابع ورودی، در ویژگی defaulted شیء Variables در دسترس است. اطلاعات متغیرهای ناشناخته و متغیرهای پیشفرض تا زمانی که متد Update اجرا نشده باشد، در دسترس نیستند.
از آنجا که متغیرها در نهایت به عنوان متغیرهای ساخت (construction variables) اضافه میشوند، باید نامهایی را برای متغیرها انتخاب کنید که ناخواسته متغیرهای ساخت از پیش تعریفشدهای را که پروژهتان از آنها استفاده میکند تغییر ندهند (برای مرجع به بخش “Construction Variables” مراجعه کنید)، زیرا مقادیر مشخصشده به متغیرهای ساخت مربوطه انتساب داده میشوند، نه اینکه با آنها ادغام گردند.
زیرسیستم Variables به طور مستقیم روشی را برای تعریف متغیری که کاربر حتماً باید آن را مشخص کند پشتیبانی نمیکند، اما میتوان این حالت را با استفاده از یک تابع اعتبارسنج (validator) و تعیین یک مقدار پیشفرض که اعتبارسنج آن را رد میکند شبیهسازی کرد، که منجر به پیام خطای مقدار نامعتبر میشود (متدهای کمکی EnumVariable و ListVariable این کار را نسبتاً ساده میکنند).
یک شیء Variables دارای متدهای زیر است:
vars.Add(key, [help, default, validator, converter, subst])
help متن راهنما برای متغیر است (پیشفرض یک رشتهٔ خالی است).
default مقداری است که در صورت ارائه نشدن هیچ مقداری در منابع ورودی، در محیط ساخت به متغیر تخصیص مییابد. اگر default برابر None باشد (حالت پیشفرض)، متغیر به محیط ساخت اضافه نمیشود مگر اینکه به طور صریح در منابع ورودی تنظیم شده باشد. مقدار پیشفرض میتواند از نوع مورد نظر، یا رشتهای باشد که converter بتواند آن را به آن نوع تبدیل کند.
اگر آرگومان validator مشخص شود، یک تابع بازفراخوانی برای اعتبارسنجی مقدار متغیر است. اعتبارسنج هنگامی که متد Update فراخوانی شود صدا زده میشود. یک اعتبارسنج باید سه آرگومان بپذیرد: key، value و env. در صورتی که مقدار نامعتبر باشد باید یک استثنا (با یک پیام خطای مفید) ایجاد کند؛ هیچ مقدار بازگشتی مورد انتظار نیست.
اگر آرگومان converter مشخص شود، یک تابع بازفراخوانی برای تبدیل مقدار به قالب مورد نظر برای محیط ساخت است. مبدل پیش از اعتبارسنج فراخوانی میشود. باید مقداری را برگرداند، که سپس به validator (در صورت وجود) فرستاده میشود. یک مبدل باید حداقل آرگومان value را بپذیرد، و در صورتی که نیاز به دسترسی به محیط ساخت داشته باشد، میتواند به صورت اختیاری env را به عنوان آرگومان دوم بپذیرد. به طور کلی، مبدل نباید با شکست مواجه شود و بررسیهای اعتبارسنجی را به اعتبارسنج واگذار میکند، اگرچه اگر انجام یک عملیات غیرممکن باشد یا اعتبارسنج جداگانهای وجود نداشته باشد، میتواند یک ValueError ایجاد کند.
اگر آرگومان subst مشخص شود، یک مقدار بولی است که نشان میدهد آیا پیش از ارسال مقدار به توابع مبدل و اعتبارسنج، جایگزینی روی مقدار انجام شود یا خیر. مقدار پیشفرض True است. غیرفعال کردن جایگزینی زمانی مفید است که مقدار متغیر شبیه به یک ارجاع متغیر ساخت (مانند $VAR) باشد و اعتبارسنج یا مبدل باید آن را بسطنیافته ببینند.
به عنوان یک حالت خاص، اگر key یک دنباله و تنها آرگومان ورودی به Add باشد، به شش پارامتر key، help، default، validator، converter و subst باز میشود، و هر عضو ناموجود از سمت راست با مقادیر پیشفرض مربوطه پر میشود. این حالت امکان استفاده از تاپل حاصل از توابع تسهیلکنندهٔ BoolVariable، EnumVariable، ListVariable، PackageVariable و PathVariable را فراهم میکند.
مثالها:
vars.Add('CC', help='The C compiler')
def valid_color(key, val, env):
if not val in ['red', 'blue', 'yellow']:
raise Exception("Invalid color value '%s'" % val)
vars.Add('COLOR', validator=valid_color)
تغییریافته در نسخهٔ 4.8.0: پارامتر subst اضافه شد.
vars.AddVariables(args)
opt.AddVariables(
("debug", "", 0),
("CC", "The C compiler"),
("VALIDATE", "An option for testing validation", "notset", validator, None),
)
vars.FormatVariableHelpText(env, opt, help, default, actual, aliases)
FormatVariableHelpText بهطور معمول مستقیماً فراخوانی نمیشود، بلکه توسط GenerateHelpText که وظیفه بهدست آوردن مقادیر لازم را بر عهده دارد، فراخوانی میگردد. برای سفارشیسازی ظاهر پیامهای راهنمای متغیر، میتوانید تابع اختصاصی خود را با همان امضای تابع جایگزین کنید. مثال:
def my_format(env, var, help, default, actual):
fmt = "\n%s: default=%s actual=%s (%s)\n"
return fmt % (var, default, actual, help)
vars.FormatVariableHelpText = my_format
توجه داشته باشید که GenerateHelpText هیچ خط خالی یا نویسه اضافهای میان مدخلها قرار نمیدهد؛ بنابراین اگر میخواهید مدخلها جدا شوند، باید این نویسهها را به رشته بازگشتی اضافه کنید.
vars.GenerateHelpText(env, [sort])
اگر پارامتر اختیاری sort روی یک مقدار قابلفراخوانی (callable) تنظیم شده باشد، از آن بهعنوان تابع مقایسه برای تعیین نحوه مرتبسازی متغیرهای افزودهشده استفاده میشود. این تابع باید دو آرگومان را بپذیرد، آنها را با هم مقایسه کند و در صورتی که اولی کوچکتر از دومی باشد یک عدد صحیح منفی، در صورت برابر بودن صفر، و در صورتی که بزرگتر باشد یک عدد صحیح مثبت بازگرداند. اگر sort قابلفراخوانی نباشد اما به مقدار درست (true) ارزیابی شود، یک مرتبسازی الفبایی انجام میشود. پیشفرض False (مرتبنشده) است.
Help(vars.GenerateHelpText(env))
def cmp(a, b):
return (a > b) - (a < b)
Help(vars.GenerateHelpText(env, sort=cmp))
vars.Save(filename, env)
env = Environment()
vars = Variables(['variables.cache', 'custom.py'])
vars.Add(...)
vars.Update(env)
vars.Save('variables.cache', env)
vars.UnknownVariables()
env = Environment(variables=vars)
for key, value in vars.UnknownVariables():
print("unknown variable: %s=%s" % (key, value))
vars.Update(env, [args])
اگر آرگومان اختیاری args ارائه شود، باید یک دیکشنری از متغیرها باشد که بهجای دیکشنری ذخیرهشده در هنگام ایجاد شیء Variables استفاده خواهد شد.
بهطور معمول، Update بهصورت مستقیم فراخوانی نمیشود، بلکه بهطور غیرمستقیم با ارسال شیء Variables به تابع Environment فراخوانی میگردد:
env = Environment(..., variables=vars)
یک شیء Variables همچنین دو مشخصه دادهای در دسترس قرار میدهد که میتوانند برای اطلاعات بیشتر خوانده شوند. اینها تنها در صورتی مقدار دارند که Update قبلاً اجرا شده باشد.
vars.defaulted
vars.unknown
اضافهشده در 4.9.0: مشخصه defaulted.
ابزار SCons پنج نوع متغیر از پیش تعریفشده فراهم میکند که از طریق توابع کارخانهای (factory functions) در دسترس هستند؛ این توابع یک چندتایی (tuple) مناسب برای ارسال مستقیم به متدهای Add یا AddVariables تولید میکنند.
BoolVariable(key, help, default)
EnumVariable(key, help, default, allowed_values, [map, ignorecase])
ListVariable(key, help, default, names, [map, validator])
آرگومان اختیاری map یک دیکشنری است که میتواند برای تبدیل مقادیر ورودی به مقادیر معتبر خاص در فهرست names استفاده شود. (توجه داشته باشید که مقادیر اضافیِ پذیرفتهشده از طریق استفاده از map در پیام راهنمای تولیدشده بازتاب نمییابند).
آرگومان اختیاری validator میتواند برای تعیین یک تابع بازخوان (callback) اعتبارسنج سفارشی، همانطور که برای Add شرح داده شده است، استفاده شود. حالت پیشفرض، استفاده از یک روتین اعتبارسنج داخلی است.
اضافهشده در 4.8.0: پارامتر validator.
PackageVariable(key, help, default)
هر یک از رشتههای (بدون حساسیت به بزرگی و کوچکی حروف) 1، yes، true، on، enable یا search میتوانند برای نشان دادن «فعال بودن» بسته به کار روند و همچنین میتوانند به عنوان مقدار default استفاده شوند. به جز در مورد حالت خاصی که برای یک رشته مسیر شرح داده شد، مقدار بولی True تولید میشود.
هر یک از رشتههای (بدون حساسیت به بزرگی و کوچکی حروف) 0، no، false، off یا disable میتوانند برای نشان دادن «غیرفعال بودن» بسته به کار روند و همچنین میتوانند به عنوان مقدار default استفاده شوند. مقدار بولی False تولید میشود.
رشتهای که نه رشته فعالساز باشد و نه رشته غیرفعالساز، یک «رشته مسیر» در نظر گرفته میشود. یک رشته مسیر میتواند هنگام تعیین متغیر ارائه شود و همچنین میتواند به عنوان مقدار default به کار رود. یک رشته مسیر باید به یک مسیر موجود در فایلسیستم اشاره داشته باشد، اما تصمیمگیری در مورد معنای بیشتر آن بر عهده سیستم ساخت است. رشته مسیر تولید میشود. به عنوان یک حالت ویژه، اگر default یک رشته مسیر باشد و متغیر با یک رشته فعالساز مشخص شود، به جای True، رشته مسیر پیشفرض تولید میشود.
PathVariable(key, help, default, [validator])
پارامتر اختیاری validator یک تابع بازخورد (callback) را تعریف میکند که برای بررسی پذیرفتنی بودن مسیر مشخصشده فراخوانی خواهد شد. SCons اعتبارسنجهای آمادهٔ زیر را ارائه میدهد:
PathVariable.PathExists
PathVariable.PathIsFile
PathVariable.PathIsDir
PathVariable.PathIsDirCreate
PathVariable.PathAccept
میتوانید تابع validator سفارشی خود را ارائه دهید که باید سه آرگومان را بپذیرد: key، نام متغیری که باید تنظیم شود؛ val، مقدار مشخصشدهای که بررسی میشود؛ و env، محیط ساخت (construction environment)؛ و در صورتی که مقدار مشخصشده پذیرفتنی نباشد، باید یک استثنا (exception) ایجاد کند.
این توابع ایجاد چندین متغیر با رفتاری یکدست را در قالب یک فراخوانی منفرد به متد AddVariables آسان میسازند:
vars.AddVariables(
BoolVariable(
"warnings",
help="compilation with -Wall and similar",
default=True,
),
EnumVariable(
"debug",
help="debug output and symbols",
default="no",
allowed_values=("yes", "no", "full"),
map={},
ignorecase=0, # case-sensitive
),
ListVariable(
"shared",
help="libraries to build as shared libraries",
default="all",
names=list_of_libs,
),
PackageVariable(
"x11",
help="use X11 installed here (yes = search some places)",
default="yes",
),
PathVariable(
"qtdir",
help="where the root of Qt is installed",
default=qtdir
),
PathVariable(
"foopath",
help="where the foo library is installed",
default=foopath,
validator=PathVariable.PathIsDir,
),
)
اشیاء گره (Node Objects)
SCons اشیائی را که منبع یا هدف عملیات ساخت هستند بهصورت گرهها (Nodes)، که ساختارهای داده درونیاند، نمایش میدهد. چندین نوع گره قابلمشاهده برای کاربر وجود دارد: گرههای فایل (File Nodes)، گرههای دایرکتوری (Directory Nodes)، گرههای مقدار (Value Nodes) و گرههای نام مستعار (Alias Nodes). برخی از انواع گرهها دارای مشخصهها و متدهای عمومی هستند که در ادامه توضیح داده شدهاند. هر یک از انواع گره یک تابع سراسری و یک متد محیطی متناظر برای ایجاد نمونهها دارند: File، Dir، Value و Alias.
گرههای
سامانه
فایل (Filesystem Nodes)
توابع/متدهای File و Dir بهترتیب گرههای فایل و گرههای دایرکتوری را بازمیگردانند. چنین گرههای سامانه فایلی نماینده مؤلفههای ساختی هستند که با مدخلی در سامانه فایل رایانه متناظرند، فارغ از اینکه در زمان ایجاد گره چنین مدخلی وجود داشته باشد یا خیر. معمولاً نیازی به ایجاد صریح گرههای سامانه فایل ندارید، زیرا زمانی که رشتهای را بهعنوان هدف یا منبع یک Builder مشخص میکنید، SCons گرهها را برحسب نیاز برای پر کردن گراف وابستگی ایجاد خواهد کرد. سازندهها (Builders) گره(های) هدف را در قالب یک فهرست بازمیگردانند که سپس میتوانید از آنها استفاده کنید. با این حال، از آنجا که گرههای سامانه فایل مشخصهها و متدهای عمومی مفیدی دارند که میتوانید در فایلهای SConscript بهکار گیرید، گاهی مناسب است که آنها را بهصورت دستی و خارج از روال معمول فراخوانی یک Builder بسازید.
مشخصههای زیر اطلاعاتی درباره یک Node ارائه میدهند:
node.path
node.abspath
node.relpath
node.srcnode()
نمونهها:
# دریافت مسیر دایرکتوری ساخت جاری، نسبت به ریشه پروژه.
Dir('.').path
# مسیر مطلق دایرکتوری جاری
Dir('.').abspath
# مسیر دایرکتوری جاری نسبت به دایرکتوری ریشه پروژه
Dir('.').relpath
# خط بعدی همیشه '.' است، زیرا مسیر دایرکتوری ریشه نسبت به خودش است.
Dir('#.').path
# مسیر منبع فایل منبع دادهشده.
File('foo.c').srcnode().path
# سازندهها فهرستی از اشیاء File بازمیگردانند:
foo = env.Program('foo.c')
print("foo will be built in", foo[0].path)
اشیاء گره سامانه فایل متدهایی برای ایجاد گرههای سامانه فایل جدید نسبت به گره اصلی دارند. همچنین مواقعی وجود دارد که ممکن است نیاز به ارجاع به مدخلی در سامانه فایل داشته باشید بدون اینکه از قبل بدانید آن مدخل یک فایل است یا یک دایرکتوری. برای این موقعیتها، متد Entry در اشیاء گره سامانه فایل وجود دارد که گرهای را بازمیگرداند که میتواند نمایانگر یک فایل یا یک دایرکتوری باشد.
اگر گره اصلی یک گره دایرکتوری باشد، این متدها گره جدید را درون دایرکتوریای قرار میدهند که گره اصلی نشان میدهد:
node.Dir(name)
node.File(name)
node.Entry(name)
اگر گره اصلی یک گره فایل باشد، این متدها گره جدید را در همان دایرکتوریای قرار میدهند که گره اصلی در آن قرار دارد:
node.Dir(name)
node.File(name)
node.Entry(name)
برای نمونه:
# دریافت یک Node برای یک فایل درون یک دایرکتوری
incl = Dir('include')
f = incl.File('header.h')
# دریافت یک Node برای یک زیردایرکتوری درون یک دایرکتوری
dist = Dir('project-3.2.1')
src = dist.Dir('src')
# دریافت یک Node برای فایلی در همان دایرکتوری
cfile = File('sample.c')
hfile = cfile.File('sample.h')
# نمونه ترکیبی
docs = Dir('docs')
html = docs.Dir('html')
index = html.File('index.html')
css = index.File('app.css')
گرههای Value
و Alias
SCons دو نوع Node دیگر را برای نمایش اشیایی فراهم میکند که ورودی معادل در سیستمفایل (filesystem) نخواهند داشت. چنین Nodeهایی همواره باید بهصورت صریح ایجاد شوند.
متد Alias یک Alias Node بازمیگرداند. نامهای مستعار (Aliases) اشیایی مجازی هستند - خود آنها منجر به ساخته شدن اشیاء فیزیکی نمیشوند، بلکه به گراف وابستگی مرتبط با منابعشان (sources) وارد میشوند. بهروز بودن یک alias با بررسی بهروز بودن منابع آن سنجیده میشود. یک alias با اطمینان از اینکه منابعش ساخته شدهاند ساخته میشود و در صورت انجام هرگونه ساخت، هرگونه Action که به عنوان بخشی از alias تعریف شده است اعمال میگردد.
یک فراخوانی Alias مدخلی را در فضاینام alias ایجاد میکند که برای رفع ابهام به کار میرود. اگر منبع یک alias نامی با مقدار رشتهای داشته باشد، به یک Node مدخل سیستمفایل حل (resolve) میشود، مگر آنکه در فضاینام alias یافت شود، که در این حالت به Node منطبق از نوع alias حل خواهد شد. در نتیجه، ترتیب فراخوانیهای Alias دارای اهمیت است. یک alias میتواند به alias دیگری ارجاع دهد، اما تنها در صورتی که آن alias دیگر پیشتر ایجاد شده باشد.
متد Value یک Value Node بازمیگرداند. گرههای Value Node اغلب برای دادههای تولیدشدهای استفاده میشوند که هیچ مدخل متناظری در سیستمفایل ندارند، اما برای تعیین اینکه آیا یک هدف ساخت قدیمی (out-of-date) است یا خیر، یا برای گنجانده شدن به عنوان بخشی از یک Action ساخت به کار میروند. نمونههای رایج شامل رشتههای برچسب زمانی (timestamp)، رشتههای نسخه سیستم کنترل نگارش و سایر رشتههای تولیدشده در زمان اجرا (run-time) هستند.
یک Value Node میتواند همچنین هدف (target) یک builder باشد.
گسترش SCONS (EXTENDING SCONS)
SCons بهگونهای طراحی شده است که از طریق امکانات ارائهشده قابل گسترش باشد، بنابراین برای سفارشیسازی رفتار آن، بهندرت به تغییر کدِ خودِ SCons نیاز است. تعدادی از عملیات اصلی از اشیای قابل فراخوانی (callable objects) استفاده میکنند که با نوشتن موارد دلخواه خود میتوانید آنها را تکمیل کنید. Builders، Scanners و Tools هر یک از نوعی سامانهٔ افزونهای استفاده میکنند که به شما اجازه میدهد بهسادگی موارد جدیدی را به کار بگیرید. اطلاعات دربارهٔ ایجاد Builder Objects و Scanner Objects در بخشهای بعدی آمده است. دستورالعملهایی که SCons در عمل برای ساخت چیزها به کار میبرد Actions نام دارند، و ایجاد Action Objects و سپردن آنها به اشیایی که نیاز به دانستن آن کنشها دارند ساده است (علاوه بر Builders، به AddPostAction، AddPreAction و Alias برای نمونههایی دیگر از بخشهایی که Actions را میپذیرند مراجعه کنید). Action Objects نیز در ادامه تشریح شدهاند. افزودن پیمانههای جدید Tool در Tool Modules توضیح داده شده است.
اشیای سازنده (Builder Objects)
scons میتواند با افزودن اشیای Builder جدید به یک construction environment (محیط ساخت)، برای ساخت انواع دیگری از هدفها گسترش یابد. بهطور کلی، تنها زمانی باید یک شیء Builder جدید اضافه کنید که بخواهید نوع جدیدی از فایل یا سایر هدفهای خارجی را بسازید. برای انواع فایلهای خروجی که scons از پیش آنها را میشناسد، معمولاً میتوانید رفتار Builderهای از پیشآماده نظیر Program، Object یا Library را با تغییر construction variables (متغیرهای ساخت) کنترلکنندهٔ رفتار آنها ($CC، $LINK و غیره) دستخوش تغییر کنید. با این روش میتوانید برای نمونه کامپایلر مورد استفاده را تغییر دهید، که بسیار سادهتر بوده و نسبت به نوشتن یک builder جدید کمتر مستعد خطا است. مستندات مربوط به هر Builder فهرست construction variables مورد استفادهٔ آن را آورده است.
اشیای Builder با استفاده از تابع کارخانهای Builder ایجاد میشوند. پس از ایجاد، یک builder با ثبت شدن در دیکشنری $BUILDERS در یک construction environment، به آن محیط افزوده میشود (برخی از مثالهای این بخش این موضوع را نشان میدهند). انجام این کار بهطور خودکار باعث میشود SCons متدی با نام آن builder به محیط بیفزاید.
تابع Builder آرگومانهای کلیدواژهای زیر را میپذیرد:
action
یک تابع action باید سه آرگومان را بپذیرد: source، target و env. source فهرستی از گرههای منبع است؛ target فهرستی از گرههای هدف است؛ env نیز construction environment است که برای زمینه (context) استفاده میشود.
آرگومانهای action و generator نباید هر دو بهطور همزمان برای یک Builder استفاده شوند.
prefix
b = Builder("build_it < $SOURCE > $TARGET", prefix="file-")
def gen_prefix(env, sources):
return "file-" + env['PLATFORM'] + '-'
b = Builder("build_it < $SOURCE > $TARGET", prefix=gen_prefix)
b = Builder(
"build_it < $SOURCE > $TARGET",
suffix={None: "file-", "$SRC_SFX_A": gen_prefix},
)
suffix
b = Builder("build_it < $SOURCE > $TARGET", suffix="-file")
def gen_suffix(env, sources):
return "." + env['PLATFORM'] + "-file"
b = Builder("build_it < $SOURCE > $TARGET", suffix=gen_suffix)
b = Builder(
"build_it < $SOURCE > $TARGET",
suffix={None: ".sfx1", "$SRC_SFX_A": gen_suffix},
)
ensure_suffix
b1 = Builder("build_it < $SOURCE > $TARGET", suffix=".out")
b2 = Builder(
"build_it < $SOURCE > $TARGET", suffix=".out", ensure_suffix=True
)
env = Environment()
env['BUILDERS']['B1'] = b1
env['BUILDERS']['B2'] = b2
# Builds "foo.txt" because ensure_suffix is not set.
env.B1('foo.txt', 'foo.in')
# Builds "bar.txt.out" because ensure_suffix is set.
env.B2('bar.txt', 'bar.in')
src_suffix
target_scanner
source_scanner
target_factory
مثال:
def my_mkdir(target, source, env):
# target[0] will be a Dir node for 'new_directory'
MakeDirectoryBuilder = Builder(action=my_mkdir, target_factory=Dir)
env = Environment()
env.Append(BUILDERS={'MakeDirectory': MakeDirectoryBuilder})
env.MakeDirectory('new_directory', [])
توجه داشته باشید که فراخوانی به Builder مربوط به MakeDirectory باید یک فهرست منبع خالی را مشخص کند تا رشته نام فایل، هدف builder را مشخص کند. SCons فرض میکند که یک آرگومان مکانی منفرد دادهشده به یک builder همان منبع است، و سعی میکند نام هدف را از آن استنتاج کند؛ که در صورت نبود یک پیشوند یا پسوند خودکار، به تطابق نام هدف و منبع و ایجاد یک وابستگی دورانی (circular dependency) منجر خواهد شد.
source_factory
مثال:
def collect(target, source, env):
# target[0] will default to a File node for 'archive' (no target_factory)
# source[0] will be a Dir node for 'directory_name'
CollectBuilder = Builder(action=collect, source_factory=Dir)
env = Environment()
env.Append(BUILDERS={'Collect': CollectBuilder})
env.Collect('archive', 'directory_name')
emitter
تابعی که بهصورت emitter ارسال میشود باید سه آرگومان بپذیرد: source، target و env. source فهرستی از گرههای منبع، target فهرستی از گرههای هدف، و env همان construction environment است که برای زمینه (context) استفاده میشود.
یک emitter باید یک چندتایی (tuple) شامل دو فهرست بازگرداند: فهرست اهدافی که باید توسط این builder ساخته شوند، و فهرست منابع برای این builder.
مثال:
def e(target, source, env):
return target + ['foo.foo'], source + ['foo.src']
# Simple association of an emitter function with a Builder.
b = Builder("my_build < $TARGET > $SOURCE", emitter=e)
def e2(target, source, env):
return target + ['bar.foo'], source + ['bar.src']
# Simple association of a list of emitter functions with a Builder.
b = Builder("my_build < $TARGET > $SOURCE", emitter=[e, e2])
# Calling an emitter function through a construction variable.
env = Environment(MY_EMITTER=e)
b = Builder("my_build < $TARGET > $SOURCE", emitter='$MY_EMITTER')
# Calling a list of emitter functions through a construction variable.
env = Environment(EMITTER_LIST=[e, e2])
b = Builder("my_build < $TARGET > $SOURCE", emitter='$EMITTER_LIST')
# Associating multiple emitters with different file
# suffixes using a dictionary.
def e_suf1(target, source, env):
return target + ['another_target_file'], source
def e_suf2(target, source, env):
return target, source + ['another_source_file']
b = Builder(
action="my_build < $TARGET > $SOURCE",
emitter={'.suf1': e_suf1, '.suf2': e_suf2}
)
multi
env
generator
تابعی که به عنوان generator ارسال میشود باید چهار آرگومان را بپذیرد: source، target، env و for_signature. source فهرستی از گرههای منبع است، target فهرستی از گرههای هدف است، env همان محیط ساخت برای استفاده به عنوان زمینه (context) است، و for_signature یک مقدار بولی است که به تابع اعلام میکند آیا به منظور تولید یک امضای ساخت (build signature) فراخوانی شده است (در مقایسه با اجرای واقعی دستور). از آنجا که امضای ساخت برای تعیین نیاز به ساخت مجدد استفاده میشود، اگر for_signature درست (true) باشد، تابع باید آن دسته از عناصری را که بر تحریک ساخت مجدد تأثیری ندارند حذف کند.
مثال:
def g(source, target, env, for_signature):
return [["gcc", "-c", "-o"] + target + source]
b = Builder(generator=g)
آرگومانهای generator و action نباید به طور همزمان برای یک Builder یکسان استفاده شوند.
src_builder
single_source
source_ext_match
در مثال زیر، مقداردهی source_ext_match مانع از خروج scons با خطا به دلیل عدم تطابق پسوندهای foo.in و foo.extra میشود.
b = Builder(action={'.in': 'build $SOURCES > $TARGET'}, source_ext_match=False)
env = Environment(BUILDERS={'MyBuild': b})
env.MyBuild('foo.out', ['foo.in', 'foo.extra'])
env
b = Builder(action="build < $SOURCE > $TARGET")
env = Environment(BUILDERS={'MyBuild' : b})
env.MyBuild('foo.out', 'foo.in', my_arg='xyzzy')
chdir
توجه داشته باشید که scons هنگام استفاده از آرگومان کلیدواژهای chdir بسط متغیرهای ساخت مانند $TARGET و $SOURCE را به طور خودکار اصلاح نخواهد کرد--به این معنی که نامهای فایل بسطیافته همچنان نسبت به دایرکتوری ریشه پروژه نسبی خواهند بود، و در نتیجه نسبت به دایرکتوری chdir نادرست هستند. سازندگانی که با استفاده از آرگومان کلیدواژهای chdir ایجاد میشوند، نیاز دارند تا از بسط متغیرهای ساخت مانند ${TARGET.file} و ${SOURCE.file} استفاده کنند تا فقط بخش نام فایل هدفها و منبع به کار گرفته شود.
b = Builder(action="build < ${SOURCE.file} > ${TARGET.file}", chdir=True)
env = Environment(BUILDERS={'MyBuild' : b})
env.MyBuild('sub/dir/foo.out', 'sub/dir/foo.in')
هشدار
Python تنها یک موقعیت دایرکتوری جاری را دنبال میکند، حتی اگر چندین ریسه (thread) در حال اجرا باشند. این بدان معناست که استفاده از آرگومان chdir در حالت چندریسهای SCons (گزینه -j) کار نخواهد کرد، زیرا ریسههای کاری مجزایی که توسط SCons ایجاد شدهاند هنگام شروع به تغییر دایرکتوری با یکدیگر تداخل پیدا میکنند.
هر آرگومان کلیدواژهای اضافی که هنگام ایجاد یک شیء Builder (یعنی هنگام فراخوانی تابع Builder) مشخص شود، هنگام فراخوانی شیء Builder در محیط ساخت (construction environment) در حال اجرا تنظیم خواهد شد. نمونه بارز در اینجا، تنظیم یک متغیر ساخت (construction variable) روی مخزن یک سیستم کنترل نسخه کد منبع است.
هرگونه آرگومان کلیدواژهای از این دست که هنگام فراخوانی یک شیء Builder ارسال شود، تنها با هدفی که توسط همان فراخوانی بخصوص Builder ایجاد شده است (و هر فایل دیگری که در نتیجه این فراخوانی ساخته میشود) مرتبط خواهد بود. این آرگومانهای کلیدواژهای اضافی به توابع زیر ارسال میشوند: توابع تولیدکننده فرمان (command generator functions)، Actionهای تابعی (function Actions)، و توابع emitter.
هنگام اشکالزدایی خطاها در یک متد builder سفارشی، به یاد داشته باشید که Action مربوط به builder به صورت ناهمگام اجرا میشود - فراخوانی builder در SConscript صرفاً به SCons اعلام میکند که مایلید چه چیزی ساخته شود، در حالی که ساخت واقعی بعداً (در صورت نیاز) توسط taskmaster زمانبندی میشود. در نتیجه، قرار دادن یک فراخوانی builder درون یک بلوک try مفید نخواهد بود، زیرا موفقیت در فراخوانی builder به معنای موفقیتآمیز بودن خودِ ساخت نیست. در صورت نیاز، Action یک builder را به گونهای کدنویسی کنید که با یک پیام خطای مفید که نشاندهنده مشکل در فایل SConscript است خارج شود. تلاش برای بازیابی برنامهنویسیشده از خطاهای ساخت به ندرت مفید واقع میشود.
اشیاء Action (Action Objects)
تابع کارخانهای Builder آرگومان کلیدواژهای action خود را به یک شیء Action داخلی مناسب تبدیل میکند، همانگونه که تابع Command عمل میکند. همچنین میتوانید با فراخوانی تابع کارخانهای Action، اشیاء Action را به طور صریح برای ارسال به Builder، یا سایر توابعی که actionها را به عنوان آرگومان میپذیرند، ایجاد کنید. هنگامی که چندین شیء Builder نیاز به انجام کار یکسانی دارند، این کار کارآمدتر از این است که به هر یک از آن اشیاء Builder اجازه داده شود یک شیء Action جداگانه بسازند. همچنین امکان پیکربندی انعطافپذیرتری را برای یک شیء Action فراهم میکند. برای نمونه، جهت کنترل پیامی که هنگام انجام اقدام چاپ میشود، باید شیء action را با استفاده از Action ایجاد کنید.
تابع کارخانهای Action بسته به نوع آرگومان action (نخستین پارامتر موضعی)، شیء مناسبی را برای آن اقدام بازمیگرداند:
Action('$CC -c -o $TARGET $SOURCES')
# Doesn't print the line being executed.
Action('@build $TARGET $SOURCES')
# Ignores return value
Action('-build $TARGET $SOURCES')
Action([['cc', '-c', '-DWHITE SPACE', '-o', '$TARGET', '$SOURCES']])
اگر بیش از یک فایل هدف یا فایل منبع وجود داشته باشد، آرگومانهای target و source میتوانند لیستهایی از اشیاء Node باشند. نام(های) واقعی فایلهای هدف و منبع را میتوان از طریق تابع توکار str در Python از اشیاء Node آنها بازیابی کرد:
target_file_name = str(target) source_file_names = [str(x) for x in source]
این تابع برای نشان دادن ساخت موفقیتآمیز فایل(های) هدف باید 0 یا None را بازگرداند. تابع ممکن است برای نشان دادن ساخت ناموفق، یک استثنا صادر کند (raise) یا یک وضعیت خروج غیر صفر برگرداند.
def build_it(target=None, source=None, env=None):
# build the target from the source
return 0
a = Action(build_it)
فرم متد محیط env.Action در زمان فراخوانی، متغیرهای ساخت را در تمام رشتههای آرگومان، از جمله action، با استفاده از متغیرهای ساخت موجود در محیط ساخت که از طریق آن فراخوانی شده است، بسط میدهد. فرم تابع سراسری Action بسط متغیرها را تا زمانی که شیء Action واقعاً استفاده شود به تأخیر میاندازد.
آرگومان اختیاری دوم برای Action جهت کنترل خروجیای استفاده میشود که هنگام اجرای واقعی Action چاپ میگردد. اگر این پارامتر حذف شود، یا مقدار آن یک رشتهٔ خالی باشد، یک خروجی پیشفرض بسته به نوع action استفاده میشود. برای مثال، یک action خط فرمانی، دستور اجرا شده را چاپ خواهد کرد. انواع آرگومانهای زیر پذیرفته میشوند:
آرگومانهای کلیدواژهای cmdstr و strfunction نباید هر دو با هم در یک فراخوانی واحد از Action ارائه شوند.
چاپ رشتههای action تحت تأثیر تنظیمات $PRINT_CMD_LINE_FUNC قرار دارد.
مثالها:
def build_it(target, source, env):
# build the target from the source
return 0
def string_it(target, source, env):
return "building '%s' from '%s'" % (target[0], source[0])
# Use a positional argument.
f = Action(build_it, string_it)
s = Action(build_it, "building '$TARGET' from '$SOURCE'")
# Alternatively, use a keyword argument.
f = Action(build_it, strfunction=string_it)
s = Action(build_it, cmdstr="building '$TARGET' from '$SOURCE'")
# You can provide a configurable variable.
l = Action(build_it, '$STRINGIT')
هر آرگومان موضعی اضافی در صورت وجود، میتواند متغیرهای ساخت یا فهرستی از متغیرهای ساخت باشد که مقادیر آنها در امضای Action (امضای ساخت یا build signature) هنگام تصمیمگیری در این مورد که آیا یک هدف باید به دلیل تغییر action مجدداً ساخته شود یا خیر، گنجانده خواهد شد. چنین متغیرهایی را میتوان با استفاده از پارامتر کلیدواژهای varlist نیز مشخص کرد؛ هر دو شکل موضعی و کلیدواژهای میتوانند وجود داشته باشند و با یکدیگر ترکیب خواهند شد. این امر هر زمان که بخواهید با تغییر یک متغیر ساخت خاص، هدف مجدداً ساخته شود، ضروری است. این کار اغلب برای یک رشتهٔ action نیاز نیست، زیرا متغیرهای بسطیافته معمولاً بخشی از خط فرمان خواهند بود، اما در صورتی که یک action از نوع تابع Python هنگام تولید خط فرمان از مقدار یک متغیر ساخت استفاده کند، ممکن است لازم باشد.
def build_it(target, source, env):
# build the target from the 'XXX' construction variable
with open(target[0], 'w') as f:
f.write(env['XXX'])
return 0
# Use positional arguments.
a = Action(build_it, '$STRINGIT', ['XXX'])
# Alternatively, use a keyword argument.
a = Action(build_it, varlist=['XXX'])
برای تغییر دادن رفتار شیء Action، میتوان آرگومانهای کلیدواژهای اختیاری زیر را به تابع کارخانهای Action ارسال کرد:
chdir
توجه داشته باشید که هنگام استفاده از پارامتر chdir، SCons بسط متغیرهای ساخت مانند $TARGET و $SOURCE را بهطور خودکار تغییر نخواهد داد - بدین معنا که نامهای بسطیافتهٔ فایلها همچنان نسبت به دایرکتوری ریشهٔ پروژه نسبی خواهند بود، و در نتیجه نسبت به دایرکتوری chdir نادرست هستند. سازندگانی (Builders) که با استفاده از آرگومان کلیدواژهای chdir ایجاد میشوند، برای استفاده از بخش نام فایل اهداف و منبع، باید از بسط متغیرهای ساخت مانند ${TARGET.file} و ${SOURCE.file} استفاده کنند. مثال:
a = Action("build < ${SOURCE.file} > ${TARGET.file}", chdir=True)
exitstatfunc
def always_succeed(s):
# Always return 0, which indicates success.
return 0
a = Action("build < ${SOURCE.file} > ${TARGET.file}", exitstatfunc=always_succeed)
batch_key
a = Action('build $CHANGED_SOURCES', batch_key=True)
آرگومان batch_key همچنین میتواند یک تابع فراخوانپذیر باشد که کلیدی را برای شناسایی «دستهها» (batches) مختلف فایلهای هدف جهت گردآوری برای ساخت دستهای برمیگرداند. یک تابع batch_key باید چهار پارامتر بپذیرد: action، env، target و source. پارامتر اول، action، شیء Action فعال است. پارامتر دوم، env، محیط ساختی است که برای هدف پیکربندی شده است. پارامترهای target و source فهرستهایی از اهداف و منابع برای عمل پیکربندیشده هستند.
کلید بازگرداندهشده معمولاً باید یک تاپل از مقادیر بهدستآمده از آرگومانها باشد و با بهرهگیری از هر منطق مناسبی، تصمیم بگیرد که فراخوانیهای متعدد چگونه باید دستهبندی شوند. برای نمونه، یک تابع batch_key ممکن است تصمیم بگیرد مقدار یک متغیر ساخت خاص را از env برگرداند که باعث میشود scons هدفهایی را که دارای مقادیر یکسان از آن متغیر ساخت هستند، بهصورت دستهای بسازد؛ یا شاید id() پایتون مربوط به کل محیط ساخت را برگرداند، که در این حالت scons تمام هدفهای پیکربندیشده با همان محیط ساخت را بهصورت دستهای خواهد ساخت. بازگرداندن None نشان میدهد که آن هدف خاص نباید بخشی از هیچ ساخت دستهای باشد، بلکه در عوض با یک فراخوانی جداگانه از دستور یا تابع Action ساخته خواهد شد. مثال:
def batch_key(action, env, target, source):
tdir = target[0].dir
if tdir.name == 'special':
# Don't batch-build any target
# in the special/ subdirectory.
return None
return (id(action), id(env), tdir)
a = Action('build $CHANGED_SOURCES', batch_key=batch_key)
توابع
متفرقه Action
SCons توابع Action مختلفی را فراهم میکند که امکان انجام انواع عملیات رایج بر روی فایلها و دایرکتوریها را مهیا میسازند. این توابع از نظر مفهومی شبیه به «tasks» در ابزار ساخت Ant هستند، هرچند پیادهسازی آنها کمی متفاوت است. این توابع در زمان فراخوانی، در واقع کار مشخصشده را اجرا نمیکنند، بلکه توابع کارخانهای (factory functions) هستند که یک شیء Action را برمیگردانند تا در زمان مناسب اجرا شود.
دو روش طبیعی برای استفاده از این توابع Action در نظر گرفته شده است.
نخست، اگر نیاز دارید عمل همزمان با خواندهشدن فایل SConscript انجام شود، میتوانید از تابع سراسری Execute استفاده کنید:
Execute(Touch('file'))
دوم، میتوانید از این توابع برای ارائه فهرستی از Actionها جهت استفاده در متد env.Command بهره ببرید. این قابلیت به شما امکان میدهد توالیهای پیچیدهتری از دستکاری فایلها را بدون وابستگی به دستورهای خارجی وابسته به پلتفرم اجرا کنید:
env = Environment(TMPBUILD='/tmp/builddir')
env.Command(
target='foo.out',
source='foo.in',
action=[
Mkdir('$TMPBUILD'),
Copy('$TMPBUILD', '${SOURCE.dir}'),
"cd $TMPBUILD && make",
Delete('$TMPBUILD'),
],
)
Chmod(dest, mode)
Execute(Chmod('file', 0o755))
env.Command(
'foo.out',
'foo.in',
[Copy('$TARGET', '$SOURCE'), Chmod('$TARGET', 0o755)],
)
Execute(Chmod('file', "ugo+w"))
env.Command(
'foo.out',
'foo.in',
[Copy('$TARGET', '$SOURCE'), Chmod('$TARGET', "ugo+w")],
)
رفتار Chmod در پلتفرمهای Windows و WebAssembly دارای محدودیت است؛ یادداشتهای موجود در مستندات Python را برای os.chmod[8] که تابع زیربنایی آن است، ببینید.
Copy(dest, src)
Execute(Copy('foo.output', 'foo.input'))
env.Command('bar.out', 'bar.in', Copy('$TARGET', '$SOURCE'))
Delete(entry, [must_exist])
Execute(Delete('/tmp/buildroot'))
env.Command(
'foo.out',
'foo.in',
action=[
Delete('${TARGET.dir}'),
MyBuildAction,
],
)
Execute(Delete('file_that_must_exist', must_exist=True))
Mkdir(name)
Execute(Mkdir('/tmp/outputdir'))
env.Command(
'foo.out',
'foo.in',
action=[
Mkdir('/tmp/builddir'),
Copy('/tmp/builddir/foo.in', '$SOURCE'),
"cd /tmp/builddir && make",
Copy('$TARGET', '/tmp/builddir/foo.out'),
],
)
Move(dest, src)
Execute(Move('file.destination', 'file.source'))
env.Command(
'output_file',
'input_file',
action=[MyBuildAction, Move('$TARGET', 'file_created_by_MyBuildAction')],
)
Touch(file)
Execute(Touch('file_to_be_touched'))
env.Command('marker', 'input_file', action=[MyBuildAction, Touch('$TARGET')])
جایگزینی
متغیرها (Variable
Substitution)
پیش از اجرای یک دستور، scons بسط پارامتر (جایگزینی) را روی رشتهای که بخش کُنش (action) سازنده را تشکیل میدهد انجام میدهد. قالب یک پارامتر قابل جایگزینی به صورت ${expression} است. اگر expression به یک متغیر اشاره کند، آکولادها در ${expression} میتوانند حذف شوند مگر آنکه بلافاصله پس از نام متغیر، نویسهای بیاید که بتواند به عنوان بخشی از نام تفسیر شود، یا از نحو Python مانند [ (برای نمایهگذاری/برش) یا . (برای دسترسی به مشخصهها - بخش Special Attributes در زیر را ببینید) باشد.
اگر expression به یک construction variable اشاره کند، آن عبارت (شامل $ یا ${ }) با مقدار آن متغیر در construction environment در زمان اجرا جایگزین میشود. اگر expression شبیه به نام یک متغیر باشد اما در construction environment تعریف نشده باشد، با یک رشتهٔ خالی جایگزین خواهد شد. اگر expression به یکی از Special Variables (زیر را ببینید) اشاره داشته باشد، مقدار متناظر آن متغیر جایگزین میشود. expression همچنین میتواند یک عبارت Python برای ارزیابی باشد. برای توضیحات به بخش Python Code Substitution در زیر مراجعه کنید.
SCons هنگام تبدیل construction variables به رشتههای خط فرمان، از قوانین زیر پیروی میکند:
هنگامی که یک کُنش ساخت (build action) اجرا میشود، هشی از خط فرمان به همراه سایر اطلاعات مربوط به هدف(های) ساختهشده توسط آن کُنش، برای استفادههای بعدی در تعیین لزوم ساخت مجدد ذخیره میشود. این مقدار build signature (یا build action signature) نامیده میشود. توالی گریز $( subexpression $) میتواند برای مشخص کردن بخشهایی از خط فرمان استفاده شود که ممکن است بدون نیاز به ساخت مجدد تغییر کنند--یعنی بخشهایی که نباید در هنگام محاسبهٔ build signature لحاظ شوند. تمام متن از $( تا و با احتساب $) متناظر، پیش از اضافه شدن به build signature از خط فرمان حذف خواهد شد، در حالی که پیش از اجرای دستور فقط $( و $) حذف خواهند شد. برای مثال، رشتهٔ خط فرمان:
"echo Last build occurred $( $TODAY $). > $TARGET"
دستور زیر را اجرا خواهد کرد:
echo Last build occurred $TODAY. > $TARGET
اما امضای ساخت (build signature) اضافهشده به هر فایل هدف از این عبارت محاسبه خواهد شد:
echo Last build occurred . > $TARGET
در حالی که متغیرهای ساخت معمولاً بهطور مستقیم جایگزین میشوند، اگر یک متغیر ساخت دارای مقداری باشد که یک شیء قابل فراخوانی (callable) در Python است (یک تابع، یا کلاسی با متد __call__)، آن شیء در طول جایگزینی فراخوانی میشود. شیء قابل فراخوانی باید چهار آرگومان بپذیرد: target، source، env و for_signature. source فهرستی از گرههای منبع است، target فهرستی از گرههای هدف است، env همان محیط ساخت مورد استفاده برای زمینه است، و for_signature یک مقدار بولی است که به شیء قابل فراخوانی اعلام میکند آیا به منظور تولید یک امضای ساخت فراخوانی شده است یا خیر. از آنجا که امضای ساخت برای تعیین لزوم ساخت مجدد به کار میرود، مؤلفههای متغیری که بر راهاندازی ساخت مجدد بیتأثیر هستند، در صورت صادق (true) بودن for_signature باید از رشته بازگردانده شده حذف شوند. برای ساختار نحوی به بخشهای $( و $) در بالا مراجعه کنید.
SCons هر آنچه را که شیء قابل فراخوانی بازمیگرداند در رشته بسطیافته قرار میدهد:
def foo(target, source, env, for_signature):
return "bar"
# Will expand $BAR to "bar baz"
env = Environment(FOO=foo, BAR="$FOO baz")
جهت یادآوری، جایگزینی زمانی رخ میدهد که $BAR در عمل در یک کنش سازنده استفاده شود. مقدار env['BAR'] دقیقاً همان مقداری خواهد بود که تنظیم شده بود: "$FOO baz". این موضوع میتواند اشکالزدایی را دشوار سازد، زیرا نتیجه جایگزینشده در زمان تفسیر فایلهای SConscript در دسترس نیست و از این رو برای تابع print قابل دسترسی نخواهد بود. با این حال، میتوانید در صورت نیاز با فراخوانی متد env.subst به این منظور، جایگزینی را بر حسب تقاضا انجام دهید.
میتوانید از این ویژگی برای ارسال آرگومانها به یک متغیر قابل فراخوانی استفاده کنید؛ بدین صورت که یک کلاس قابل فراخوانی بسازید که آرگومانهای ارسالی را در نمونه ذخیره کرده و سپس هنگام فراخوانی نمونه (در متد __call__) از آنها استفاده کند. توجه داشته باشید که در این حالت، کل بسط متغیر باید درون آکولاد محصور شود تا آرگومانها به نمونهسازی کلاس مرتبط شوند:
class foo:
def __init__(self, arg):
self.arg = arg
def __call__(self, target, source, env, for_signature):
return self.arg + " bar"
# Will expand $BAR to "my argument bar baz"
env=Environment(FOO=foo, BAR="${FOO('my argument')} baz")
جایگزینی:
متغیرهای
ویژه (Substitution: Special Variables)
علاوه بر متغیرهای ساخت معمولی، scons متغیرهای ویژه (Special Variables) زیر را برای استفاده در بسط دادن دستورها ارائه میکند:
$CHANGED_SOURCES
$CHANGED_TARGETS
$SOURCE
$SOURCES
$TARGET
$TARGETS
$UNCHANGED_SOURCES
$UNCHANGED_TARGETS
این نامها رزرو شدهاند و نمیتوان به آنها مقداری تخصیص داد یا به عنوان متغیرهای ساخت استفاده کرد. SCons آنها را به روشی وابسته به زمینه (context-dependent) محاسبه میکند و از یک محیط ساخت بازیابی نمیشوند.
برای نمونه، فراخوانی سازنده زیر:
env = Environment(CC='cc')
env.Command(
target=['foo'],
source=['foo.c', 'bar.c'],
action='@echo $CC -c -o $TARGET $SOURCES'
)
خروجی زیر را تولید خواهد کرد:
cc -c -o foo foo.c bar.c
در مثال قبلی، رشته ${SOURCES[1]} به صورت زیر باز خواهد شد: bar.c.
جایگزینی:
صفتهای
ویژه (Substitution: Special Attributes)
یک نام متغیر ممکن است شامل اصلاحکنندههای زیر درون آکولادهای دربرگیرنده باشد تا به ویژگیهای رشته درونیابیشده دسترسی پیدا کند. اینها به عنوان صفتهای ویژه (special attributes) شناخته میشوند.
مسیر پایه نام فایل،
شامل مسیر دایرکتوری
اما بدون هیچگونه پسوندی.
مسیری که در آن دایرکتوریها با اسلش رو به جلو
(/)
از هم جدا شدهاند.
گاهی اوقات در سیستمهای Windows ضروری است،
هنگامی که یک مسیر به فایلی در سایر سیستمها (POSIX) ارجاع میدهد.
مسیری که در آن دایرکتوریها با بکاسلش
(\\)
از هم جدا شدهاند.
گاهی اوقات در سیستمهای سبک POSIX ضروری است،
هنگامی که یک مسیر به فایلی در سایر سیستمها (Windows) ارجاع میدهد.
win32 یک مترادف (منسوخشده) برای
windows است.
دایرکتوری و نام فایل برای فایل منبعی که از طریق
VariantDir()
به این فایل پیوند خورده است.
اگر این فایل پیوند نخورده باشد،
صرفاً دایرکتوری و نام فایل را بدون تغییر بازمیگرداند.
دایرکتوری حاوی فایل منبعی که از طریق
VariantDir()
به این فایل پیوند خورده است.
اگر این فایل پیوند نخورده باشد،
تنها بخش دایرکتوریِ نام فایل را بازمیگرداند.
دایرکتوری و نام فایل برای فایل منبعی که از طریق
VariantDir()
به این فایل پیوند خورده است.
اگر فایل به صورت محلی وجود نداشته باشد اما در یک مخزن (Repository) موجود باشد،
مسیر موجود در مخزن بازگردانده میشود.
اگر این فایل پیوند نخورده باشد، صرفاً
دایرکتوری و نام فایل را بدون تغییر بازمیگرداند.
دایرکتوری مخزن (Repository) حاوی فایل منبعی که از طریق
VariantDir()
به این فایل پیوند خورده است.
اگر این فایل پیوند نخورده باشد،
تنها بخش دایرکتوریِ نام فایل را بازمیگرداند.
برای نمونه، هدف مشخصشده برای اصلاحکنندههای متناظر به صورت زیر باز خواهد شد:
$TARGET => sub/dir/file.x
${TARGET.base} => sub/dir/file
${TARGET.dir} => sub/dir
${TARGET.file} => file.x
${TARGET.filebase} => file
${TARGET.suffix} => .x
${TARGET.abspath} => /top/dir/sub/dir/file.x
${TARGET.relpath} => sub/dir/file.x
$TARGET => ../dir2/file.x
${TARGET.abspath} => /top/dir2/file.x
${TARGET.relpath} => ../dir2/file.x
SConscript('src/SConscript', variant_dir='sub/dir')
$SOURCE => sub/dir/file.x
${SOURCE.srcpath} => src/file.x
${SOURCE.srcdir} => src
Repository('/usr/repository')
$SOURCE => sub/dir/file.x
${SOURCE.rsrcpath} => /usr/repository/src/file.x
${SOURCE.rsrcdir} => /usr/repository/src
برخی از اصلاحکنندهها میتوانند ترکیب شوند، مانند ${TARGET.srcpath.base), ${TARGET.file.suffix} و غیره.
جایگزینی
کد Python (Python Code Substitution)
اگر عبارت قابلجایگزینی با استفاده از نشانهگذاری ${expression} با هیچیک از الگوهای جایگزینی دیگر مطابقت نداشته باشد، به عنوان یک عبارت Python ارزیابی میشود. این کار با استفاده از تابع eval در Python انجام میپذیرد، در حالی که پارامتر globals روی مجموعه متغیرهای ساخت محیط فعلی تنظیم شده و نتیجه در آن جایگزین میشود. بنابراین در حالت زیر:
env.Command(
'foo.out', 'foo.in', "echo ${COND==1 and 'FOO' or 'BAR'} > $TARGET"
)
دستور اجراشده یکی از موارد زیر خواهد بود:
echo FOO > foo.out
یا
echo BAR > foo.out
که بستگی به مقدار فعلی env['COND'] در زمان اجرای دستور دارد. ارزیابی در زمانی انجام میشود که هدف در حال ساخت است، نه زمانی که SConscript خوانده میشود. بنابراین اگر env['COND'] بعداً در SConscript تغییر کند، مقدار نهایی استفاده خواهد شد.
در اینجا یک مثال کاملتر آمده است. توجه داشته باشید که تمام موارد COND، FOO و BAR متغیرهای ساخت هستند و مقادیر آنها در دستور نهایی جایگزین میشود. FOO یک لیست است، بنابراین عناصر آن با فاصلههای جداکننده درج میشوند.
env=Environment()
env['COND'] = 1
env['FOO'] = ['foo1', 'foo2']
env['BAR'] = 'barbar'
env.Command(
'foo.out', 'foo.in', "echo ${COND==1 and FOO or BAR} > $TARGET"
)
دستور زیر را اجرا خواهد کرد:
echo foo1 foo2 > foo.out
در واقع، ارزیابی عبارت Python همان روشی است که ویژگیهای خاص جایگزین میشوند: آنها صرفاً ویژگیهای شیءهای Python هستند که $TARGET، $SOURCES و غیره را نشان میدهند، که SCons آنها را به eval ارسال کرده تا مقدار را بازگرداند.
هشدار (Caution)
استفاده از تابع eval در Python دارای پیامدهای امنیتی در نظر گرفته میشود، زیرا بسته به منابع ورودی، رشتههای دلخواه و بررسینشدهای از کد میتوانند توسط مفسر Python اجرا شوند. اگرچه SCons از آن در بستری تا حدی محدود استفاده میکند، اما هنگام استفاده از ساختار ${python-expression-for-subst} باید از این مسئله آگاه باشید.
اشیاء Scanner (Scanner Objects)
اشیاء Scanner برای پویش انواع خاصی از فایلها به منظور یافتن وابستگیهای ضمنی استفاده میشوند؛ برای نمونه، دستورهای تعبیهشدهٔ پیشپردازنده/کامپایلر که موجب میشوند فایلهای دیگر در حین پردازش ضمیمه (include) شوند. SCons دارای تعدادی شیء Scanner از پیش ساخته شده است، بنابراین معمولاً تنها تنظیم Scannerها برای انواع فایلهای جدید ضروری است. شما این کار را با فراخوانی تابع کارخانهای (factory function) Scanner انجام میدهید. Scanner آرگومانهای زیر را میپذیرد. تنها function الزامی است؛ باقی اختیاری هستند:
function
تابع پویشگر میتواند از str(node) برای دریافت نام فایل، از node.dir برای دریافت دایرکتوری قرارگیری فایل، از node.get_contents() برای دریافت محتویات فایل به صورت بایت، یا از node.get_text_contents() برای دریافت محتویات فایل به صورت متن استفاده کند.
تابع پویشگر باید هنگام تعیین وجود وابستگیهای احتمالی، دایرکتوریهای فهرستشده در پارامتر path را در نظر بگیرد. به ابزارهای خارجی مانند پیشپردازندهٔ C/C++ فهرستی از دایرکتوریها داده میشود تا در آنها به دنبال دستورهای گنجاندن فایل منبع بگردند (برای نمونه #include "myheader.h"). این فهرست از متغیر مسیر مربوطه (برای نمونه $CPPPATH برای C/C++) تولید میشود. میتوان Scanner را هدایت کرد تا همان فهرست را از طریق پارامتر path به تابع پویشگر منتقل کند تا بتواند در همان مکانها جستجو نماید. امکان ارسال این فهرست توسط Scanner، از طریق آرگومان path_function در زمان ایجاد Scanner فعال میشود.
به جای یک تابع پویشگر، میتوانید یک دیکشنری به عنوان پارامتر function ارائه دهید. این دیکشنری باید کلیدها (مانند پسوندهای فایل) را به اشیاء Scanner دیگر نگاشت کند. اسکنری که به این شیوه ساخته شود به عنوان توزیعکننده (dispatcher) عمل میکند: پارامتر skeys مربوط به Scanner به طور خودکار با کلیدهای دیکشنری پر میشود، که نشان میدهد این Scanner، گرههای Nodeای را که با آن کلیدها مطابقت دارند مدیریت میکند؛ سپس از این نگاشت برای واگذاری فایل به یک Scanner دیگر استفاده میشود که بر اساس skeys خودش برای مدیریت آن Node انتخاب نمیشده است.
توجه داشته باشید که تضمینی وجود ندارد که فایل مورد پویش در زمان فراخوانی پویشگر وجود داشته باشد - ممکن است فایلی تولیدی باشد که هنوز ایجاد نشده است - بنابراین تابع پویشگر باید در برابر این موضوع انعطافپذیر باشد.
اگرچه بسیاری از توابع پویشگر با جستجوی الگوهای شناختهشده در کد، بر روی فایلهای کد منبع عمل میکنند، اما در واقع میتوانند هر کاری را که لازم است انجام دهند. به عنوان مثال، به سازندهٔ Program یک target_scanner اختصاص داده شده است که فهرست کتابخانههای ارائهشده برای ساخت ($LIBS) را بررسی میکند و در مورد افزودن آنها به عنوان وابستگی تصمیم میگیرد؛ این پویشگر به درون باینری ساختهشده نگاه نمیکند.
تصمیمگیری در این مورد که آیا برای موارد شناساییشده توسط پویش، یک وابستگی در SCons ایجاد شود یا خیر، بر عهدهٔ تابع پویشگر است. وابستگیها بخشی کلیدی از سازوکار SCons هستند که هم تعیین بازسازی و هم ترتیب درست ساختها را امکانپذیر میکنند. بهویژه مهم است که فایلهای تولیدی که وابستگی هستند به گراف Node افزوده شوند، در غیر این صورت خطاهای استفاده پیش از ایجاد (use-before-create) محتمل خواهد بود. با این حال، ممکن است نیازی نباشد همه چیز به عنوان وابستگی ردگیری شود. در برخی موارد، فایلهای سرآیند ارائهشده توسط پیادهسازی به ندرت تغییر میکنند ولی به طور بسیار گسترده ضمیمه میشوند، بنابراین ردگیری آنها در گراف گره SCons میتواند در ازای فایدهای اندک، بسیار پرهزینه باشد - برای مثال فایل سرآیند استاندارد C یعنی string.h را در نظر بگیرید. هیچ اطلاعات ویژهای برای کمک به این تصمیمگیری به تابع پویشگر داده نمیشود، بنابراین منطق تصمیمگیری کدنویسیشده در تابع پویشگر باید به دقت سنجیده شود.
name
argument
skeys
path_function
تابع FindPathDirs میتواند فراخوانی شود تا یک path_function آماده برای یک نام متغیر ساخت (construction variable) مشخص برگرداند، که معمولاً آسانتر از نوشتن تابع از ابتدا است. برای نمونه، path_function=FindPathDirs('CPPPATH') بدین معناست که تابع پویشگر با مسیرهای استخراجشده از $CPPPATH در محیط ساخت env فراخوانی میشود و به عنوان پارامتر path به تابع پویشگر ارسال میگردد.
node_class
node_factory
scan_check
recursive
یک Scanner پس از ایجاد، میتواند با قرار گرفتن در فهرست $SCANNERS به یک محیط افزوده شود، که این امر به طور خودکار باعث میشود SCons آن را به عنوان یک متد نیز به محیط اضافه کند. با این حال، معمولاً یک scanner واقعاً مستقل نیست، بلکه باید به سازوکار انتخاب موجود متصل شود تا تصمیم بگیرد که فایلهای منبع را چگونه بر اساس پسوند نام فایل پویش کند. برای این منظور، SCons دارای یک شیء سراسری SourceFileScanner است که توسط سازندههای Object، SharedObject و StaticObject استفاده میشود تا تصمیم بگیرند کدام scanner باید به کار گرفته شود. شما میتوانید از متد SourceFileScanner.add_scanner() برای افزودن شیء Scanner خود به زیرساخت SCons که برنامهها یا کتابخانههای هدف را از فهرستی از فایلهای منبع با انواع مختلف میسازد استفاده کنید:
def xyz_scan(node, env, path):
contents = node.get_text_contents()
# Scan the contents and return the included files.
XYZScanner = Scanner(xyz_scan)
SourceFileScanner.add_scanner('.xyz', XYZScanner)
env.Program('my_prog', ['file1.c', 'file2.f', 'file3.xyz'])
ماژولهای ابزار (Tool Modules)
ابزارهای سفارشی را میتوان یا با قرار دادن آنها در زیردایرکتوری site_tools یک دایرکتوری site پیکربندیشده، یا در مکانی که توسط آرگومان کلیدواژهای toolpath در Environment مشخص شده است به پروژه افزود. شما باید ترتیبی دهید که ابزار برای اثرگذاری فراخوانی شود، یا به عنوان بخشی از فهرست ارائهشده به آرگومان کلیدواژهای tools در هنگام مقداردهی اولیه محیط ساخت، یا با فراخوانی env.Tool.
پارامتر toolpath فهرستی از رشتههای مسیر، و پارامتر tools فهرستی از ابزارها را میپذیرد که اغلب رشته هستند:
env = Environment(tools=['default', 'foo'], toolpath=['tools'])
این دستور یک ماژول مشخصات ابزار به نام foo را در دایرکتوری tools و در مکانهای استاندارد جستجو میکند، و علاوه بر این از ابزارهای پیشفرض معمول برای پلتفرم مربوطه استفاده مینماید.
هنگام جستجوی ماژولهای مشخصات ابزار، دایرکتوریهای مشخصشده از طریق toolpath پیش از مسیر ابزار موجود (زیردایرکتوریهای site_tools دایرکتوریهای site پیشفرض یا مشخصشده) در نظر گرفته میشوند، که آنها نیز به نوبه خود پیش از ابزارهای توکار (built-in) بررسی میشوند. به عنوان مثال، افزودن یک ماژول مشخصات ابزار gcc.py به دایرکتوری toolpath، ابزار توکار gcc را بازنویسی (override) خواهد کرد. پارامتر toolpath در محیط ذخیره شده و در فراخوانیهای بعدی متد env.Tool و همچنین توسط env.Clone استفاده خواهد شد.
base = Environment(toolpath=['custom_path']) derived = base.Clone(tools=['custom_tool']) derived.CustomBuilder()
یک ماژول مشخصات ابزار شکلی از ماژول Python است که در داخل با استفاده از سازوکار import در Python جستجو میشود، بنابراین یک ابزار میتواند شامل یک فایل Python تکی با نام ابزار (مانند mytool.py) یا یک دایرکتوری با نام ابزار (مانند mytool/) که حداقل دارای یک فایل __init__.py است باشد. یک ماژول مشخصات ابزار دارای دو نقطه ورود الزامی است:
generate(env, **kwargs)
def generate(env):
...
if 'MYTOOL' not in env:
env['MYTOOL'] = env.Detect("mytool")
flags = env.get('MYTOOLFLAGS', SCons.Util.CLVar())
env.AppendUnique(MYTOOLFLAGS='--myarg')
...
تابع generate میتواند از هر آرگومان کلیدواژهای که کاربر از طریق kwargs ارائه میدهد برای تغییر در مقداردهی اولیه خود استفاده کند.
exists(env)
نکته
در حال حاضر، تابع exists ابزارهای افزودهشده توسط کاربر بهطور خودکار فراخوانی نمیشود. در نتیجه، توصیه میشود که تابع generate بهصورت تدافعی کدنویسی شود - یعنی به اینکه بررسیهای لازم برای وجود ابزار از قبل انجام شده است تکیه نکند. انتظار میرود این یک محدودیت موقت باشد و تابع exists همچنان باید ارائه شود.
یک عنصر از فهرست tools همچنین میتواند یک تابع یا شیء قابل فراخوانی دیگر (شامل یک شیء Tool حاصل از فراخوانی قبلی Tool) باشد که در این صورت، تابع Environment مستقیماً آن شیء را برای بهروزرسانی محیط ساخت (construction environment) جدید فراخوانی خواهد کرد. در این حالت هیچ جستجویی برای ابزار انجام نمیشود.
def my_tool(env):
env['XYZZY'] = 'xyzzy'
env = Environment(tools=[my_tool])
یک عنصر از فهرست tools همچنین میتواند یک فهرست یا تاپل دو عنصری به شکل (toolname, kw_dict) باشد. SCons ماژول مشخصات ابزار toolname را همانطور که در بالا شرح داده شد جستجو میکند، و kw_dict را که باید یک دیکشنری باشد، به عنوان آرگومانهای کلیدواژهای به تابع generate ابزار ارسال میکند. تابع generate میتواند از آن آرگومانها برای تغییر رفتار ابزار با برپاسازی محیط به روشهای گوناگون یا تغییر در مقداردهی اولیهٔ آن استفاده کند.
# in tools/my_tool.py:
def generate(env, **kwargs):
# Sets MY_TOOL to the value of keyword 'arg1' or '1' if not supplied
env['MY_TOOL'] = kwargs.get('arg1', '1')
def exists(env):
return True
# in SConstruct:
env = Environment(
tools=['default', ('my_tool', {'arg1': 'abc'})], toolpath=['tools']
)
مشخصات ابزار (my_tool در این مثال) میتواند از متغیر $PLATFORM از محیط ساخت که به آن فرستاده شده برای سفارشیسازی ابزار برای پلتفرمهای مختلف استفاده کند.
ابزارها میتوانند «تودرتو» (nested) باشند - بدین معنی که میتوانند درون یک زیردایرکتوری در toolpath قرار گیرند. نام یک ابزار تودرتو از نقطه به عنوان جداکنندهٔ دایرکتوری استفاده میکند.
# namespaced builder env = Environment(ENV=os.environ.copy(), tools=['SubDir1.SubDir2.SomeTool']) env.SomeTool(targets, sources) # Search Paths # SCons\Tool\SubDir1\SubDir2\SomeTool.py # SCons\Tool\SubDir1\SubDir2\SomeTool\__init__.py # .\site_scons\site_tools\SubDir1\SubDir2\SomeTool.py # .\site_scons\site_tools\SubDir1\SubDir2\SomeTool\__init__.py
رفتار وابسته به سیستم (SYSTEM-SPECIFIC BEHAVIOR)
scons و فایلهای پیکربندی آن تا حد زیادی به دلیل پیادهسازی با Python بسیار سازگار و قابلحمل هستند. با این حال، چند مسئله در زمینهٔ سازگاری وجود دارد که ممکن است افراد ناآگاه را به دام بیندازد.
پسوند فایل .C (.C File Suffix)
scons بسته به قابلیتهای سیستم زیربنایی، با پسوند فایل بزرگ .C بهطور متفاوتی رفتار میکند. در یک سیستم حساس به کوچک و بزرگی حروف مانند Linux یا UNIX، scons با فایلی دارای پسوند .C مانند یک فایل منبع C++ برخورد میکند. در یک سیستم غیرحساس به بزرگی و کوچکی حروف مانند Windows، scons با فایلی با پسوند .C مانند یک فایل منبع C رفتار میکند.
پسوندهای فایل فرترن (Fortran File Suffixes)
پسوندهای فایلهای منبع هنگام کار با کدهای زبان Fortran به چند روش بر رفتار SCons اثر میگذارند (همهٔ آنها وابسته به سیستم نیستند، اما برای کامل بودن در اینجا ذکر شدهاند).
از آنجا که زبان Fortran در طول نگارشهای استاندارد متعددی تکامل یافته است، پروژهها ممکن است نیاز داشته باشند که با فایلهای مربوط به نسلهای مختلف زبان، به شکل متفاوتی رفتار کنند. بدین منظور، SCons بسته به پسوند فایل، کار را به پیکربندی لهجهٔ کامپایلر متفاوتی (که به صورت مجموعهای از متغیرهای ساخت بیان میشود) ارسال میکند. بهطور پیشفرض، همهٔ این پیکربندیها یکسان آغاز میشوند، اما متغیرهای ساخت را میتوان بر اساس نیاز برای تنظیم دقیق یک لهجهٔ مشخص تغییر داد. هر یک از این لهجهها دارای یک ماژول مشخصات ابزار است که مستندات آن متغیرهای ساخت مرتبط با آن لهجه را توصیف میکند: .f (و همچنین .for و .ftn) در fortran؛ (متغیرهای ساخت با FORTRAN آغاز میشوند) .f77 در f77؛ (متغیرهای ساخت با F77 آغاز میشوند) .f90 در f90؛ (متغیرهای ساخت با F90 آغاز میشوند) .f95 در f95؛ (متغیرهای ساخت با F95 آغاز میشوند) .f03 در f03؛ (متغیرهای ساخت با F03 آغاز میشوند) .f08 در f08 (متغیرهای ساخت با F08 آغاز میشوند).
اگرچه SCons چندین لهجهٔ داخلی را بر اساس پسوندهای نام فایل شناسایی میکند، اما عرف کامپایلرهای مختلف موجود Fortran این است که تنها به دو مورد از این پسوندها معنای واقعی اختصاص میدهند: .f (و همچنین .for و .ftn) به کد منبع با قالب ثابت (fixed-format) اشاره دارد که تنها گزینهٔ موجود در FORTRAN 77 و پیش از آن بود، و .f90 به کد منبع با قالب آزاد (free-format) اشاره دارد که از استاندارد Fortran 90 به بعد در دسترس قرار گرفت. برخی از کامپایلرها پسوندهایی را که با مشخصات Fortran پس از F90 مطابقت دارند، برای این منظور معادل با .f90 میدانند، در حالی که برخی دیگر چنین نیستند - مستندات کامپایلر خود را بررسی کنید. یک سیاست که گهگاه پیشنهاد میشود، استفادهٔ انحصاری از .f و .f90 به عنوان پسوندهای نام فایل Fortran است. تعیین قالب ثابت/آزاد معمولاً میتواند بهطور صریح با پرچمهای کامپایلر (مانند -ffixed-form برای gfortran) کنترل شود و هر فرضیهای را که ممکن است بر اساس پسوند فایل منبع ایجاد شده باشد لغو کند.
پسوند فایل منبع متضمن انطباق با استاندارد فرترن همنام آن نیست - پسوند .f08 به این معنی نیست که شما لزوماً برای Fortran 2008 کامپایل میکنید. معمولاً کامپایلرها گزینههای خط فرمانی را برای اعمال این انتخاب ارائه میدهند (مانند -std=f2008 برای gfortran).
برای لهجههای از F90 به بعد (از جمله لهجهٔ عمومی FORTRAN)، پسوند .mod برای ماژولهای Fortran شناخته میشود. این فایلها اثر جانبی کامپایل یک فایل منبع Fortran شامل اعلانهای ماژول هستند و هنگام پردازش کدهای دیگری که اعلام کردهاند از ماژول استفاده میکنند، باید در دسترس باشند. SCons در حال حاضر پشتیبانی یکپارچهای از زیرماژولها (submodules) ندارد که در استاندارد Fortran 2008 معرفی شدند - کامپایلر فراخوانیشده نتایج را تولید خواهد کرد، اما SCons فایلهای .smod را به عنوان اشیاء رهگیریشده نخواهد شناخت.
در یک سیستم حساس به کوچک و بزرگی حروف مانند Linux یا UNIX، فایلی با پسوند با حروف بزرگ از مجموعهٔ .F، .FOR، .FTN، .F90، .F95، .F03 و .F08 به عنوان یک فایل منبع Fortran در نظر گرفته میشود که باید ابتدا از پیشپردازندهٔ استاندارد C عبور داده شود. نگارشهای حروف کوچک این پسوندها باعث چنین رفتاری نمیشوند. در سیستمهایی که تفاوتی میان حروف کوچک و بزرگ در نام فایلها قائل نمیشوند، این رفتار در دسترس نیست، اما فایلهایی با پسوند .FPP یا .fpp همواره ابتدا به پیشپردازنده ارسال میشوند. این رفتار با عرف gfortran از کلکسیون کامپایلرهای گنو (GNU Compiler Collection) همخوانی دارد و همچنین توسط برخی کامپایلرهای دیگر Fortran نیز دنبال میشود. برای این دو پسوند، لهجهٔ عمومی FORTRAN انتخاب خواهد شد.
خود SCons پیشپردازنده را فراخوانی نمیکند و این کار توسط کامپایلر انجام میشود، اما متغیرهای ساختی را اضافه میکند که برای اجرای پیشپردازنده کاربرد دارند. شما میتوانید این تفاوت را با بررسی $FORTRANPPCOM و $FORTRANPPCOMSTR مشاهده کنید که به جای $FORTRANCOM و $FORTRANCOMSTR برای آن لهجه استفاده میشوند.
ویندوز: ابزارهای Cygwin و Cygwin Python در برابر Pythonهای ویندوز
محیط Cygwin مجموعهای از ابزارها و برنامههای کمکی را فراهم میکند که به کاربران امکان میدهد در یک سیستم ویندوز با استفاده از محیطی شبه-POSIX کار کنند. ابزارهای Cygwin، از جمله Cygwin Python، این کار را تا حدی با داشتن توانایی مشترک در تفسیر نام مسیرها به سبک POSIX انجام میدهند. به عنوان مثال، ابزارهای Cygwin به صورت درونی یک نام مسیر Cygwin مانند /cygdrive/c/mydir را به نام مسیر معادل در ویندوز مانند C:/mydir (معادل با C:\mydir) ترجمه میکنند.
نسخههایی از Python که برای اجرای بومی (native) در ویندوز ساخته شدهاند، مانند نسخههای python.org و ActiveState، معناشناسی نام مسیرهای Cygwin را متوجه نمیشوند. این بدان معناست که استفاده از نسخه بومی ویندوز Python برای ساخت برنامههای کامپایلشده با ابزارهای Cygwin (مانند gcc، bison و flex) ممکن است نتایج غیرقابلپیشبینی به بار آورد. «ترکیب و تطبیق» به این شیوه میتواند کارساز باشد، اما نیازمند توجه دقیق به استفاده از نام مسیرها در فایلهای SConscript شما است.
در عمل، کاربران میتوانند با رعایت رهنمودهای زیر از این مشکل اجتناب کنند: هنگام استفاده از gcc مربوط به Cygwin برای کامپایل، از مفسر Python ارائهشده توسط Cygwin برای اجرای scons استفاده کنید؛ هنگام استفاده از Microsoft Visual C++ (یا یک کامپایلر «بومی» دیگر ویندوز) از نسخههای python.org، Microsoft Store، ActiveState یا دیگر نسخههای بومی Python برای اجرای scons استفاده نمایید.
این بحث تا حد زیادی برای محیط msys2 نیز صدق میکند (با استفاده از زنجیره ابزار کامپایلر mingw)، به ویژه توصیه میشود در صورت اجرای scons از داخل یک پوسته msys2، از نسخه msys2 مفسر Python استفاده شود.
ویندوز: فایل scons.bat
در ویندوز، اگر scons از طریق یک فایل دستهای (batch file) واسط به نام scons.bat اجرا شود، (دستکم) دو پیامد به دنبال دارد. توجه داشته باشید که این حالت دیگر پیشفرض نیست - scons که از طریق نصاب pip مربوط به Python نصب شده باشد دارای یک scons.exe خواهد بود که این محدودیتها را ندارد:
نخست، کاربران خط فرمان ویندوز که مایلند از تخصیص متغیر در خط فرمان استفاده کنند، ممکن است مجبور شوند تخصیصها را داخل علامتهای نقلقول دوتایی قرار دهند؛ در غیر این صورت پوسته خط فرمان ویندوز آنها را به عنوان آرگومانهای خودش مصرف میکند، نه آرگومانهای scons:
scons "FOO=BAR" "BAZ=BLEH"
دوم، پوسته Cygwin تایپ کردن scons در اعلان خط فرمان را به عنوان اشاره به این فایل واسط تشخیص نمیدهد. میتوانید با اجرای scons.bat (همراه با پسوند) از خط فرمان Cygwin، یا با ایجاد یک اسکریپت پوسته واسط به نام scons که scons.bat را فراخوانی میکند، این مشکل را برطرف نمایید.
MinGW
دایرکتوری bin مربوط به MinGW باید در متغیر محیطی PATH شما یا متغیر ساخت ['ENV']['PATH'] قرار داشته باشد تا scons بتواند ابزارهای MinGW را شناسایی کرده و به کار گیرد. هنگام اجرا تحت مفسر بومی Python در Windows، اگر هر دو نصب شده باشند، scons ابزارهای MinGW را بدون در نظر گرفتن ترتیب دایرکتوریهای bin در متغیر PATH به ابزارهای Cygwin ترجیح میدهد. اگر هم MSVC و هم MinGW را نصب کردهاید و میخواهید به جای MSVC از MinGW استفاده کنید، باید صریحاً با ارسال tools=['mingw'] به تابع Environment به scons اعلام کنید که از MinGW استفاده کند، زیرا scons ابزارهای MSVC را به ابزارهای MinGW ترجیح خواهد داد.
محیط (ENVIRONMENT)
بهطور کلی، scons توسط متغیرهای محیطیِ تنظیمشده در شلی که برای فراخوانی آن استفاده شده کنترل نمیشود و تصمیم برای وارد کردن (import) آنها را در صورت تمایل، بر عهدهٔ نویسندهٔ فایل SConscript میگذارد. با این حال، متغیرهای زیر در صورت تنظیم شدن، توسط خود scons وارد میشوند:
SCONS_LIB_DIR
SCONSFLAGS
SCONS_CACHE_MSVC_CONFIG
اگر روی یک مقدار شبهدرست ("1"، "true" یا "True") تنظیم شود، اطلاعات را در فایلی به نام scons_msvc_cache.json در دایرکتوری خانگی کاربر کش میکند. اگر روی یک مسیر فایل تنظیم شود، از همان مسیر برای کش استفاده خواهد کرد.
نکته: این پیادهسازی ممکن است هنوز تا حدی شکننده باشد. در صورت بروز مشکل، فایل کش را حذف کنید - ایجاد مجدد با اطلاعات تازه معمولاً هرگونه مشکلی را حل میکند. SCons خطاهای خواندن یا نوشتن فایل کش را نادیده میگیرد و در چنین مواردی بدون سر و صدا به رفتار بدون کش بازمیگردد.
جدید در نسخهٔ 3.1 (آزمایشی). نام پیشفرض فایل کش در نسخهٔ 4.4 به مقدار فعلی تغییر یافت و محتویات آن گسترش پیدا کرد.
همچنین ببینید (SEE ALSO)
راهنمای
کاربر SCons در
https://scons.org/doc/production/HTML/scons-user.html
دستورالعملهای
SCons (SCons Cookbook) در
https://scons-cookbook.readthedocs.io
برای
مثالهایی
از نحوه حل
مسائل
گوناگون با
SCons.
کد منبع SCons
در GitHub[9]
مرجع API
نرمافزار
SCons
https://scons.org/doc/production/HTML/scons-api/index.html
(برای
جزئیات
داخلی)
نویسندگان (AUTHORS)
در ابتدا: Steven Knight knight@baldmt.com و Anthony Roach aroach@electriceyeball.com.
از ۲۰۱۰ تاکنون: The SCons Development Team scons-dev@python.org.
نویسنده (AUTHOR)
The SCons Development Team
حق نشر (COPYRIGHT)
حق نشر © 2001 - 2026 The SCons Foundation
نکات (NOTES)
- 1.
- مشخصات LLVM
- 2.
- JEP 313
- 5.
- مستندات optparse
- 6.
- اگر no_progress از طریق SetOption در یک فایل SConscript تنظیم شده باشد (اما نه در صورتی که در یک فایل site_init.py تنظیم شده باشد)، همچنان یک پیام وضعیت اولیه درباره خواندن فایلهای SConscript نمایش داده خواهد شد، زیرا SCons باید خواندن آنها را پیش از دیدن SetOption آغاز کند.
- 7.
- http://www.opensource.org/licenses/alphabetical
- 8.
- os.chmod
- 9.
- در GitHub
| <pubdate>Released Wed, 26 Aug 2026 21:18:42 -0700</pubdate> | SCons 4.11.1 Version 4.11. |