portmaster ابزاری سبک و حرفه‌ای برای مدیریت کردن پورت‌های FreeBSD است. در صورتی که قصد دارید پورت‌های خود را به نسخه جدیدتر آپدیت کنید، باید یکی از برنامه‌های ports-mgmt/portmaster و یا ports-mgmt/portupgrade را انتخاب کنید. مهمترین مزیتی که portmaster نسبت به portupgrade دارد این است که portmaster به هیچ پورت دیگری وابسته نیست و بنابراین نصب آن بسیار سریع است و فضای بسیار اندکی اشغال می‌کند. اما در طرف مقابل portupgrade به برنامه حجیمی مانند Ruby وابسته است که این مسئله باعث طولانی شدن زمان نصب و مصرف بیشتر فضای دیسک می‌شود. در آن روی سکه، portupgrade قابلیت‌های بیشتری نسبت به portmaster دارد. اما من به شما قول می‌دهم که portmaster تمام قابلیت‌های استاندارد را دارد و قابلیت‌های اضافه‌ای که portupgrade دارد هم به ندرت استفاده می‌شوند. نحوه استفاده از این دو ابزار بسیار مشابه است و با یاد گرفتن یکی از آنها می توانید از دیگری هم استفاده کنید. بنابراین ما فقط یکی از آنها (portmaster) را با هم به طور کامل مرور می‌کنیم و نگاه مختصری هم به portupgrade می‌اندازیم.

به کمک portmaster می‌توانید عملیات مختلفی مانند نصب، حذف، به روز‌رسانی، پیکربندی و … بر روی پورت‌ها انجام دهید. اما مهمترین کاربرد portmaster انجام عمل به روز‌رسانی پورت‌ها است و اساسا برای انجام این کار نوشته شده. برای به روز رسانی کردن پورت ها حتما باید از این برنامه‌ (و یا برنامه portupgrade) استفاده کنید. چرا که در صورت استفاده نکردن از این برنامه‌ها و انجام دستی عمل به روز‌رسانی، ممکن است برنامه‌ها آسیب ببینند و غیر قابل استفاده شوند. (این موضوع بعدا بررسی می‌شود)

نصب portmaster

نصب portmaster مانند دیگر پورت‌هاست:

cd /usr/ports/ports-mgmt/portmaster
make install clean

استفاده ساده

نصب نرم‌افزار‌ها

به جای اینکه به صورت دستی به دایرکتوری یک پورت رفته و دستور make install clean را اجرا کنید، می‌توانید خیلی سریع یک برنامه را با portmaster نصب کنید. روش کلی انجام این کار بدین صورت است:

portmaster /usr/ports/category/name

با اجرای دستور بالا، portmaster شروع به شناسایی وابستگی‌های مورد نیاز می‌کند. اگر یکی از وابستگی‌ها احتیاج به پیکربندی داشت، منویی ظاهر شده و از شما خواسته می‌شود که گزینه‌های مورد نظر خود را انتخاب کنید. این کار برای تمام وابستگی‌ها انجام می‌شود. سپس برنامه کامپایل و نصب می‌شود. بنابراین در هنگام نصب برنامه‌های طولانی، نیازی نیست تا دائم صفحه مانیتور را زیر نظر داشته باشید تا مبادا پورتی نیاز به پیکربندی داشته باشد. همچنین portmaster قبل و بعد از نصب هر پورت، دستور make clean را اجرا می‌کند تا فایل‌های اضافه پاک شوند. با این کار هم در فضای دیسک سخت صرفه جویی می‌شود و هم اگر فایل موقتی از قبل وجود داشته پاک شود تا مزاحم نصب نرم‌افزار نشوند.

دستور بالا را می‌توانید به صورت زیر هم بنویسید:

portmaster category/name

به عنوان مثال:

portmaster x11/xterm

که این حالت سریع تر است و نیاز به تایپ کمتری دارد. اگر نمی‌دانید پورت مورد نظرتان در کدام دسته قرار گرفته، می‌توانید به این صورت عمل کنید:

portmaster /usr/ports/*/name

که بسیار ساده تر از اجرای دستور make search و نصب دستی برنامه است.

همچنین امکان نصب نرم‌افزار از طریق بسته‌های باینری هم وجود دارد. کافی است از گزینه ‎-P استفاده کنید:

portmaster -P x11/xterm

حذف یک برنامه

حذف کردن یک برنامه هم به سادگی نصب آن است. کافی است از گزینه ‎-e (مخفف erase) استفاده کنید:

portmaster -e pidgin-2.10.7_1

دقت کنید که باید نام برنامه را به صورت کامل و به همراه نسخه برنامه مشخص کنید. همچنین امکان استفاده از wildcard ها هم وجود دارد.

به روزرسانی پورت‌ها

به روزرسانی پورت ها قدری پیچیده تر از نصب آنهاست چرا که نیاز به کمی کار اضافه دارد. مهمترین نکته ای که در هنگام به روز‌رسانی پورت‌ها باید به یاد داشته باشید، این است که شما نمی‌توانید به همین سادگی نسخه قدیمی را پاک کرده و نسخه جدید را نصب کنید. این کار در بیشتر موارد بنا به دلایلی که در ادامه توضیح خواهیم دارد خطرناک است و باعث می‌شود برنامه‌ها از کار بیفتند. فایل /usr/ports/UPDATING دربرگیرنده دستورالعمل‌هایی است که باید قبل از عمل به روزرسانی اجرا شوند. این فایل را باید همیشه قبل از به روز‌رسانی یا حتی قبل از نصب یک نرم‌افزار بخوانید و دستورالعمل‌های موجود در آن را اجرا کنید. چرا که ممکن است نیاز به انجام گامهای اضافه تری باشد. در ادامه مهمترین سناریوهایی که معمولا باید قبل از به روز‌رسانی کردن برنامه‌ها انجام شود را با هم مرور می کنیم.

کتابخانه‌ها

فایل‌های اجرایی از توابع موجود در کتابخانه‌های اشتراکی (shared libraries) استفاده می‌کنند. اگر این کتابخانه‌ها پاک شوند (و یا به هر دلیلی فایل اجرایی نتواند این کتابخانه ها را پیدا کند)، برنامه غیر قابل استفاده خواهد بود و در هنگام اجرا پیغام خطاهای عجیب و غریب چاپ خواهد کرد و نمی‌توانید از آنها استفاده کنید. با ذکر یک مثال ارتباط این موضوع با آپدیت کردن پورت‌ها را شرح می‌دهیم. فرض کنید برنامه‌ای داریم به نام foo که به کتابخانه libbar.so لینک شده است. بنابراین اگر این کتابخانه پاک شود یا آسیب ببینید برنامه foo از کار خواهد افتاد. حالا فرض کنید که ما با portsnap درخت پورت‌های خود را بروز‌رسانی کرده‌ایم و با انجام این کار، نسخه جدید‌تر کتابخانه libbar در درخت پورت‌ها قرار گرفته است. حالا اگر ما خیلی ساده بیاییم نسخه قدیمی libbar را حذف کنیم و نسخه جدید را نصب کنیم، برنامه foo از کار خواهد افتاد. چرا که این برنامه هنوز به کتابخانه قدیمی اشاره می‌کند. بنابراین باید علاوه بر کتابخانه libbar.so برنامه foo را هم مجددا کامپایل کنیم تا به کتابخانه جدید اشاره کند. انجام این کار به صورت دستی می‌تواند بسیار سخت و شاید غیر ممکن باشد. چرا که مثلا اگر ۱۰ کتابخانه به روز شدند، ما باید تمام برنامه‌هایی که به این ۱۰ کتابخانه لینک شده‌اند را مجددا کامپایل کنیم که شاید تعداد آنها به ۱۰۰ تا هم برسد. بنابراین ما باید ۱۰۰ تا برنامه را به ترتیب خاصی حذف و دوباره نصب کنیم! portmaster برنامه‌ایست که اساسا برای حل این مشکل نوشته شده است و خودش به صورت خودکار وابستگی‌ها را تشخیص داده و آنها را به ترتیب صحیح نصب می‌کند. تنها کاری که ما باید انجام دهیم این است که فایل /usr/ports/UPDATING را بخوانیم و ببینیم چه کتابخانه‌هایی به روز شده‌اند. سپس ابتدا این کتابخانه‌ها و هر چیزی که به آنها وابسته است را مجدا کامپایل و نصب کرده و بعد به سراغ بقیه پورت ها برویم. برای مثال ممکن است در فایل /usr/ports/UPDATING چنین چیزی ببینید:

۲۰۱۲۱۲۱۱:
  AFFECTS: users of devel/pcre
  AUTHOR: bdrewery@FreeBSD.org

  The pcre library has been updated to version 8.32.  Please
  rebuild all ports that depend on it.

  If you use portmaster:
        portmaster -w -r pcre
  If you use portupgrade:
        portupgrade -fr devel/pcre
  If you use pkgng with binary packages:
        pkg install -fR devel/pcre

همان طور که مشاهده می‌کنید، نوشته شده که کتابخانه pcre به نسخه ۸٫۳۲ به روز شده و باید تمام پورت‌هایی که به آن وابسته هستند مجددا کامپایل شوند. روش های مختلف انجام این کار با استفاده از برنامه‌های مختلف هم توضیح داده شده است.

البته این فقط یکی از سناریو‌های رایج قبل از به روزرسانی پورت ها بود و این فایل مسائل دیگری را هم پوشش می‌دهد. بنابراین هر وقت که درخت پورت‌های خود را با استفاده از portsnap یا Subversion به روز می‌کنید، باید این فایل را بخوانید.

سوال:
من فراموش کردم فایل /usr/ports/UPDATING را بخوانم. حالا برنامه <your-program-here> اجرا نمی‌شود. چکار کنم؟

ابتدا sysutils/bsdadminscripts را نصب کنید. این پورت شامل تعدادی برنامه مفید است که ما به طور خاص با برنامه pkg_libchk کار داریم. کافی است این برنامه را در خط فرمان بدون هیچ آرگومانی اجرا کنید. این برنامه تمام پورت‌های نصب شده را بررسی می‌کند و کتابخانه‌های آسیب‌دیده یا گم شده را پیدا می‌کند. مطلوب است این برنامه چیزی گزارش نکند (این یعنی همه کتابخانه‌ها سالم هستند). در غیر این صورت باید آن کتابخانه را از درخت پورت ها پیدا کرده و سپس این دستور را اجرا کنید:

portmaster -r name-of-shared-library

این یک راه حل کلی است و همیشه جواب نخواهد داد. (بسته به عمق فاجعه و شرایط خاص)

پاک کردن distfile ها قدیمی

با گذشت زمان، distfile های موجود در شاخه /usr/ports/distfiles قدیمی می‌شوند و درخت پورت‌ها دیگر از آنها استفاده نمی‌کند. بنابراین می‌توانید آنها را پاک کرده تا در فضای دیسک صرفه‌جویی شود. کافی است این دستور را اجرا کنید:

portmaster -t --clean-distfiles

پیدا کردن distfile های قدیمی چند دقیقه طول خواهد کشید. سپس portmaster برای پاک کردن تک تک آنها از شما تایید می‌گیرد که باید با y پاسخ مثبت دهید. اگر می‌خواهید portmaster بدون تایید همه distfile های قدیمی را پاک کند، از گزینه ‎-y استفاده کنید.

فایل پیکربندی

portmaster یک فایل پیکربندی دارد که در مسیر /usr/local/etc/portmaster.rc قرار گرفته است. می‌توانید تنظیمات مورد نظر خود را در این فایل وارد کنید تا مجبور نباشید همیشه آنها را در خط فرمان مشخص کنید. این فایل بسیار ساده است و نکته خاصی ندارد و به طور پیش فرض کلیه دایرکتیو‌ها به صورت توضیح در آن قرار داده شده‌اند. تنها کاری که باید بکنید این است که این فایل را از بالا به پایین مرور کرده و تنظیمات مورد نظر خود را از حالت توضیح خارج کنید. (کاراکتر # را از ابتدای خطوط بردارید) در ادامه برخی از تنظیماتی که ممکن است برای شما جالب باشد را مرور می‌کنیم:

NO_BACKUP=Bopt
BACKUP=bopt

portmaster همیشه قبل از اینکه پورتی را از روی سیستم پاک کند، یک نسخه پشتیبان از آن تهیه می‌کند. اگر گزینه اول را فعال کنید، portmaster دیگر این نسخه پشتیبان را تهیه نمی‌کند. گزینه دوم که گزینه پیش فرض هم هست، باعث می‌شود portmaster این نسخه پشتیبان را همیشه تهیه کند. (این دو گزینه معادل استفاده از گزینه‌های ‎-B و ‎-b در خط فرمان هستند)

DONT_SCRUB_DISTFILES=Dopt
ALWAYS_SCRUB_DISTFILES=dopt

می‌توانید portmaster را طوری تنظیم کنید که همیشه بعد از نصب یک نرم‌افزار، distfile های قدیمی مربوط به آن برنامه را پیدا کرده و سپس از روی سیستم پاک کند تا در فضای دیسک صرفه جویی شود. البته این کار پیشنهاد نمی‌شود و بهتر است به صورت دوره‌ای این کار را انجام دهید. چون portmaster برای تشخیص distfile های قدیمی نسخه آن distfile را با نسخه‌ای که در درخت پورت‌ها وجود دارد مقابسه می‌کند و اگر قدیمی بود distfile را پاک می‌کند. اما این تشخیص همیشه ایده‌ال نیست و ممکن است portmaster اشتباها یک distfile جدید را پاک کند. (این یکی از مواردی است که portupgrade کارآیی بهتری دارد چون از regex های پیشرفته تری برای تشخیص distfile های قدیمی استفاده می‌کند) فعال کردن گزینه اول باعث می‌شود portmaster هیچ گاه سعی در پیدا کردن و پاک کردن distfile های قدیمی نکند. گزینه دوم دقیقا برعکس. این گزینه‌ها معادل استفاده از ‎-D و ‎-d در خط فرمان هستند.

PM_DEL_BUILD_ONLY=pm_dbo

پیشنهاد می‌شود این گزینه را همیشه فعال کنید. اگر فعال باشد، portmaster همیشه بعد از نصب یک برنامه تمام «وابستگی‌های زمان کامپایل» را پاک می‌کند. وابستگی‌های زمان کامپایل وابستگی‌هایی هستند که فقط در هنگام کامپایل کردن پورت به آنها نیاز است و بعد از اینکه پورت کامپایل و نصب شد می‌توان آنها را پاک کرد تا در مصرف دیسک صرفه جویی شود. برنامه‌هایی مانند gmake از این نوع هستند. اما دقت داشته باشید که بسیاری از برنامه‌ها از در زمان نصب به gmake وابسته هستند. این حرف بدین معنی است که شما باید زمان بیشتری در حین نصب برنامه‌ها منتظر بمانید.

DONT_PRE_CLEAN=Copt
DONT_POST_CLEAN=Kopt

همان طور که قبلا گفته شد، portmaster همیشه قبل و بعد از نصب یک پورت دستور make clean را اجرا می‌کند. با فعال کردن این گزینه‌ها می‌توانید این رفتار portmaster را کنترل کنید. (اما فعال کردن آنها پیشنهاد نمی‌شود چون پاک نکردن فایل‌های موقتی که از کامپایل قبلی بر روی دیسک وجود دارند می‌توانند باعث شود که عملیات کامپایل با شکست مواجه شود.) این دو گزینه معادل استفاده از ‎-C و ‎-K در خط فرمان هستند.

SAVE_SHARED=wopt

فعال کردن این گزینه باعث می‌شود portmaster یک کپی از کتابخانه‌های قدیمی نگه دارد تا اگر مشکلی پیش آمد بتوان از آنها استفاده کرد. فعال کردن این گزینه پیشنهاد می‌شود. معادل استفاده از ‎-w در خط فرمان است.

PM_PACKAGES=first
PM_PACKAGES=only

portmaster به صورت پیش فرض برنامه‌ها را با استفاده از پورت‌ها کامپایل کرده و سپس نصب می‌کند. اما شما می‌توانید از بسته‌های باینری هم استفاده کنید تا سرعت عملیات بیشتر شود. اگر گزینه اول را فعال کنید، portmaster ابتدا سعی می‌کند از یک بسته باینری استفاده کند و تنها در صورتی به سراغ پورت ها می‌رود که بسته باینری موجود نباشد. اما اگر گزینه دوم را فعال کنید، portmster فقط با بسته‌ها کار می‌کند. این گزینه‌ها معادل استفاده از ‎-P و ‎-PP در خط فرمان هستند.

PM_PACKAGES_BUILD=pmp_build

اگر این گزینه را فعال کنید، portmaster برای نصب کردن وابستگی‌های زمان اجرا از بسته‌های باینری استفاده می‌کند، اما خود برنامه اصلی از روی پورت ها کامپایل و نصب می‌شود.

LOCAL_PACKAGEDIR=<path>

portmaster بسته‌های باینری را از یک سرور راه دور دریافت و نصب می‌کند. اما شما می‌توانید خودتان هم یک سرور مخصوص برای این کار طراحی کنید تا سرعت دانلود بسته‌ها بیشتر شود و همچنین ترافیک سرور‌های عمومی کاهش یابد. (این مسئله در مقاله‌ای دیگر بررسی می‌شود) اگر در سیستم خود دایرکتوری دارید که حاوی بسته‌های باینری است، می‌توانید آدرس این دایرکتوری را وارد کنید تا portmaster بسته‌های باینری را از این دایرکتوری دریافت کند، به جای اینکه به یک سرور راه دور متصل شده و بسته را دانلود کند. معادل استفاده از ‎–local-packagedir در خط فرمان است.

PM_VERBOSE=vopt

اگر می‌خواهید portmaster کمی بیشتر وراج شود و شما را در جریان همه کارها قرار دهد، این گزینه را فعال کنید. معادل استفاده از ‎-v در خط فرمان است.

PM_MAKE_ARGS='-DFORCE_PKG_REGISTER'

گاهی اوقات نیاز است آرگومان‌هایی را برای make ارسال کنیم. این کار با استفاده از گزینه ‎-m در خط فرمان قابل انجام است. برای مثال اگر می‌خواهید یک متغیر را تعریف کنید، می‌توانید به این صورت عمل کنید:

portmaster -m -DWITH_FRIBIDI net-im/pidgin

در مثال بالا آرگومان ‎-DWITH_FRIBIDI برای make ارسال می‌شود. این گزینه را می‌توانید در فایل پیکربندی هم وارد کنید تا مجبور نباشید همیشه آن را در خط فرمان مشخص کنید.

HIDE_BUILD=Hopt

فعال کردن این گزینه باعث می‌شود جزئیات عمل نصب به جای اینکه بر روی صفحه نمایش چاپ شود، به یک فایل فرستاده شود. این گزینه برای مواقعی مفید است که می‌خواهید portmaster را به صورت غیر تعاملی اجرا کنید. این گزینه معادل استفاده از ‎-H در خط فرمان است.

PM_LOG=/full/path/to/file

این گزینه فایلی را مشخص می‌کند که جزئیات کارها به آن فرستاده خواهند شد. (گزینه قبلی را ببینید)

مسائل تکمیلی

همان طور که مشخص است، به مرور زمان نسخه‌های جدیدی از برنامه‌ها منتشر می‌شود که این برنامه‌ها کم‌کم وارد درخت پورت‌ها می‌شوند و شما می‌توانید از آنها استفاده کنید. به روزرسانی پورت‌ها را می‌توانید برای مثال هر دو هفته یک بار انجام دهید. برای به روزرسانی پورت‌های نصب شده به نسخه جدید‌تر، ابتدا باید درخت پورت‌های خود را به روز کنید:

portsnap fetch update

بعد از انجام این کار باید فایل /usr/ports/UPDATING را طبق آنچه قبلا گفته شد مطالعه کرده و دستورالعمل‌های آن را به ترتیب از قدیمی‌ترین به جدید‌ترین اجرا کنید. سپس برای به روزرسانی پورت‌های نصب شده به نسخه جدید‌تر، دستور زیر را اجرا کنید:

portmaster -a

دستور بالا تمام پورت‌ها را چک کرده و آنها را به نسخه جدیدتر بروز می‌کند. این کار به صورت پیش فرض با کامپایل برنامه از روی کدهای منبع انجام می‌شود. برای به روزرسانی از طریق بسته‌های باینری، از گزینه ‎-P استفاده کنید. portmaster قبل از اینکه شروع به عمل به روزرسانی کند، لیست پورت هایی که قرار است به روز شوند را چاپ می‌کند و شما می‌توانید با کلید y آنها را برای به روزرسانی تایید کنید. حالا فرض کنید یک برنامه حجیم مانند LibreOffice قرار است از نسخه ۴٫۰٫۱ به نسخه ۴٫۰٫۲ بروز شود. مسلما کامپایل چنین برنامه‌ای چندین ساعت زمان نیاز دارد و به علاوه اینکه احتمالا تغییر خاصی هم اتفاق نیفتاده و شما ترجیح می‌دهید از همان نسخه قدیمی استفاده کنید. برای اینکه مانع به روز شدن یک پورت خاص شوید، می‌توانید از گزینه ‎-x استفاده کنید. به عنوان مثال:

portmaster -x libreoffice -a

این گزینه را می‌توانید چندین بار برای مشخص کردن چندین پورت هم استفاده کنید.

ادامه دارد…