کار با GNU Autotools
کار با GNU Autotools
چکیده
در این مستند به شرح نحوه ایجاد فایل configure و Makefile و قالب فایل های configure.ac و Makefile.am می پردازیم.
1 مقدمه
Autoconf ابزاریست برای تولید scriptهای پوسته که بسته های کد نرم افزار را بطور خودکار به منظور انطباق با انواع کثیری از سامانه های مشابه unix پیکربندی می نماید.
Scriptهای پیکربندی تولید شده توسط Autoconf در هنگام اجرا مستقل از Autoconf بوده بنابراین کاربران نیازی به داشتن Autoconf ندارند.
Script های پیکربندی تولید شده در هنگام اجرا نیازی به تعامل با کاربر ندارند و همچنین بطور معمول نیازی به مشخص کردن نوع سامانه از طریق آرگومان ها را ندارند. آن ها به بررسی وجود هریک از تسهیلات مورد نیاز بسته نرم افزاری می پردازند.
Script های پیکربندی تولید شده configure نامیده می شوند. در هنگام اجرا configure چندین فایل ایجاد می کند و پارامترهای پیکربندی را با مقادیر مناسبشان جایگزین می نماید. فایل های ایجاد شده توسط configure عبارتند از:
یک یا چند فایل Makefile، به ازای هر زیرشاخه یک فایل
یک فایل C Header بطور اختیاری که نام آن قابل تنظیم است و در بردارنده راهنماهای define# می باشد.
یک script پوسته به نام config.status که در هنگام اجرا فایل های لیست شده در بالا را دوباره ایجاد می کند.
یک script پوسته به نام config.cache که نتایج بررسی ها را ذخیره می کند.
یک فایل به نام config.log که در بردارنده پیغام های تولید شده توسط مترجم هاست.
جهت ساخت script پیکربندی توسط Autoconf لازم است که فایل ورودی به نام configure.in یا configure.ac ایجاد کرده و Autoconf را بر روی آن اجرا نمایید. ممکن است جهت تامین آنچه با Autoconf می آید بررسی های تسهیلاتی بنویسید، همچنین ممکن است فایل های aclocal.m4 و acsite.m4 را بنویسید. اگر از فایل C Header استفاده می کنید ممکن است acconfig.h را بنویسید و فایل config.h.in تولید شده توسط Autoconf را به همراه بسته نرم افزاری توزیع نمایید.
۲ نوشتن فایل configure.in
جهت تولید configure script برای بسته نرم افزاری فایلی به نام configure.in که در بردارنده ماکروهای Autoconf می باشد را ایجاد نمایید. این ماکروها بررسی تسهیلات سامانه که مورد نیاز بسته نرم افزاریست یا می تواند از آن ها استفاده کند را انجام می دهند.
ترتیب فراخوانی ماکروها در configure.in اهمیتی ندارند مگر با چند استثنا. تمامی configure.in ها باید شامل فراخوانی ماکرو AC_INIT قبل از بررسی ها باشند و همچنین فراخوانی ماکرو AC_OUTPUT در انتها. بعلاوه بعضی از ماکروها لازم دارند تا دیگر ماکروها پیش از آن ها فراخوانی شوند زیرا آن ها مقادیر برخی از متغیرهایی که از قبل تنظیم شده اند را جهت تصمیم گیری بررسی می کنند.
در ادامه ترتیب پیشنهادی برای فراخوانی ماکروها آمده است:
AC_INIT(file)
checks for programs
checks for libraries
checks for header files
checks for typedefs
checks for structures
checks for compiler characteristics
checks for library functions
checks for system services
AC_OUTPUT([file...])
۳ استفاده از autoscan جهت ایجاد configur.scan
برنامه autoscan می تواند شما در ایجاد فایل configure.in برای بسته نرم افزاری یاری نماید. Autoscan فایل های کد ساختار درختی شاخه ها که ریشه یا به عنوان آرگومان به آن داده شده است و یا بطور پیش فرض مسیر جاریست را امتحان می کند. این برنامه فایل های کد را مسایل انتقال پذیری جستجو می کند و فایل configure.scan که شالوده اولیه فایل configure.in برای بسته است را ایجاد می کند.
قبل از تغییر نام فایل configure.scan به configure.in بطور دستی آن را امتحان کنید زیرا احتمال دارد نیاز به برخی تنظیمات داشته باشد. معمولا autoscan ماکرویی که مرتبط با ماکروی دیگر است را با ترتیب غلط ایجاد می کند که باعث می شود autoconf به شما هشدار دهد. همچنین اگر شما بخواهید که بسته از فایل سرآنید پیکربندی استفاده کند، شما باید فراخوانی AC_CONFIG_HEADER را به آن اضافه کنید.
۴ استفاده از autoconf جهت ایجاد configure
جهت ایجاد configure از configure.in برنامه autoconf را بدون هیچ آرگومانی اجرا نمایید. Autoconf فایل configure.in را با استفاده از ماکروهای m4 پردازش می کند. اگر آرگومانی به autoconf بدهید بجای خواندن فایل configure.in فایل داده شده به عنوان آرگومان را می خواند و script پیکربندی را بجای نوشتن در فایل configure در خروجی استاندارد نمایش می دهد.
۵ یک پروژه واقعی
وارد شاخه pvm شده و فایل های ذیل را ایجاد نمایید:
AUTHORS, COPYING, ChangeLog, Makefile.am, NEWS, README, autogen.sh, configure.ac و زیرشاخه m4
برنامه autoscan را اجرا نمایید. پس از پایان اجرای برنامه فایل configure.scan ایجاد شده است، آن را به configure.ac تغییر نام داده و سپس آن را جهت ویرایش باز نمایید.
AC_PREREQ([2.63])
AC_INIT(pvm, 0.1.0, pvm@pdnsoft.com)
AC_CONFIG_SRCDIR(sball/sballd.cpp)
AC_CONFIG_HEADERS([config.h])
خطوط فوق کم و بیش کدهای ثابتی هستند و کارهای اولیه و آماده سازی آن را انجام می دهند.
AM_INIT_AUTOMAKE
خط بالا automake جهت استفاده آماده می سازد.
AC_PROG_CXX
این خط پشتیبانی مترجم C++ را فعال می سازد.
LT_INIT([disable-static])
این خط ایجاد کتابخانه های ایستا را غیرفعال می سازد.
AC_PROG_LIBTOOL
پشتیبانی libtool جهت ایجاد کتابخانه های پویا فقال می سازد.
PKG_CHECK_MODULES([UUID], [uuid])
وجود بسته uuid را بررسی کرده و در صورت وجود متغیرهای محیطی UUID_CFLAGS و UUID_LIBS را تعریف می کند.
AC_CHECK_LIB([cpg], [cpg_model_initialize])
وجود کتابخانه libcpg.so را بررسی می کند.
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/file.h sys/socket.h ...
وجود فایل های سرآیند را بررسی می کند.
AC_SUBST([LIBPUTIL_SO_VERSION], [1:0:0])
متغیر محیطی LIBPUTIL_SO_VERSION را تعریف می کند.
AC_OUTPUT(Makefile putil/Makefile sball/Makefile)
در صورت موفقیت عملیات فوق فایل های Makefile را ایجاد می کند.
فایلی ته نام autogen.sh ایجاد نمایید و خطوط زیر را بدان اضافه نمایید
#!/bin/sh
autoreconf --force --install
rm -rf autom4te*.cache
برنامه autoreconf باعث می شود فایل configure دوباره ایجاد گردد و فایل های مورد نیاز به درون شاخه پروه اتقال گردد.
در شاخه اصلی پروژه فایلی به نام Makefile.am ایجاد نمایید و خطوط زیر را بدان اضافه نمایید:
ACLOCAL_AMFLAGS = -I m4
به autoconf می گوید شاخه m4 را جهت یافتن ماکروهای اضافی جستجو کند.
SUBDIRS = . putil sball
نام زیرشاخه هایی که دربردارنده فایل Makefile.am هستند ذکر می گردد.
EXTRA_DIST = autogen.sh
به automake می گوید فایل autogen.sh را در آرشیو توزیع قرار دهد.
در شاخه putil فایل Makefile.am را ایجاد کرده و خطوط زیر را بدان اضافه نمایید:
AM_CPPFLAGS= -I../include -I../include/putil $(LIBXMLXX_CFLAGS)
شاخه جستجو فایل های سرآیند و تنظیمات متفرقه دیگر برای مترجم و پیش پردازنده را مشخص می کند.
lib_LTLIBRARIES= libputil.la
نام کتابخانه یا کتابخانه های خروجی را مشخص می کند.
libputil_la_SOURCES= daemon.cpp sysmonitor.cpp exception.cpp logs.cpp \
فایل های کد کتابخانه libputil را مشخص می کند.
libputil_la_LDFLAGS= -version-info $(LIBPUTIL_SO_VERSION)
تنظیمات پیوند دهنده را مشخص می کند.
در شاخه sball فایل Makefile.am را ایجاد کرده و خطوط زیر را بدان اضافه نمایید:
AM_CPPFLAGS= -I../include -I../include/putil -I../include/sball \
$(LIBXMLXX_CFLAGS)
lib_LTLIBRARIES= libpnm.la libpmm.la
libpnm_la_SOURCES= cpg.cpp nm.cpp
libpnm_la_LDFLAGS= -version-info $(LIBPNM_SO_VERSION) \
-Wl,--rpath -Wl,../putil/.libs
libpnm_la_LIBADD= -L../putil/.libs -lputil
libpmm_la_SOURCES= mm.cpp
libpmm_la_LDFLAGS= -version-info $(LIBPMM_SO_VERSION) \
-Wl,--rpath -Wl,../putil/.lib \
-Wl,--rpath -Wl,../putil/.libss
libpmm_la_LIBADD= -L../putil/.libs -lputil
همانند فایل Makefile.am در شاخه putil می باشد با این تفاوت که در اینجا دو کتابخانه به نام های libpmm و libpnm ایجاد می گردند.
bin_PROGRAMS= sballd
نام فایل اجرایی خروجی
sballd_SOURCES= ../glbparams.cpp sballd.cpp
فایل های کد برنامه
sballd_LDFALGS= -Wl,--rpath -Wl,../putil/.libs -Wl,--rpath -Wl,.
تنظیمات پیوند دهنده
sballd_LDADD= -L../putil/.libs -lputil -L.libs -lpnm -lpmm $(LIBXMLXX_LIBS)
شاخه جستجو کتابخانه ها
اکنون همه چیز آماده است، دستورات زیر را در شاخه اصلی pvm اجرا نمایید:
./autogen.sh
./configure
make