Har xil transport turlarining afzalliklari va kamchiliklari. Transport logistik transporti. Xalqaro avtomobil transporti

Standart Linux C kompilyatori gcc-dan to'g'ri foydalanish uchun buyruq satri parametrlari haqida bilib olishingiz kerak. Bundan tashqari, gcc C tilini kengaytiradi, hatto ushbu tilning ANSI standartiga rioya qilgan holda manba kodini yozmoqchi bo'lsangiz ham, ba'zi bir gcc kengaytmalari shunchaki Linux sarlavhalarini tushunish uchun bilishingiz kerak.

Buyruq satrining aksariyat variantlari C kompilyatorlari bilan bir xil, ba'zi bir variantlar uchun standartlar mavjud emas. Ushbu bobda biz kundalik dasturlashda ishlatiladigan eng muhim variantlarni ko'rib chiqamiz.

ISO C standartiga rioya qilishga intilish foydali, ammo C past darajadagi til bo'lgani uchun, standart vositalar etarlicha ifoda etilmaydigan holatlar mavjud. Gcc kengaytmalari keng qo'llaniladigan ikkita yo'nalish mavjud: yig'ish kodi bilan ishlash (qarang: http://www.delorie.com/djgpp/doc/brennan/) va birgalikda kutubxonalar qurish (8-bobga qarang). Sarlavha fayllari umumiy kutubxonalarning bir qismi bo'lganligi sababli, ba'zi bir kengaytmalar tizim sarlavhasi fayllarida ham paydo bo'ladi.

Albatta, kodlashda juda foydali bo'lishi mumkin bo'lgan boshqa har qanday dasturlashda foydali bo'lgan ko'plab kengaytmalar mavjud. Ushbu kengaytmalar haqida ko'proq ma'lumotni gcc Texinfo hujjatlarida topishingiz mumkin.

5.1. Gcc parametrlari

gcc buyruqning ko'plab variantlarini qabul qiladi. Yaxshiyamki, siz bilishingiz kerak bo'lgan variantlar to'plami unchalik katta emas va biz ularni ushbu bobda ko'rib chiqamiz.

Variantlarning aksariyati boshqa kompilyatorlarnikiga o'xshash yoki o'xshashdir, gcc info gcc orqali mavjud bo'lgan variantlarning ulkan hujjatlarini o'z ichiga oladi (man gcc ham bu ma'lumotni beradi, ammo man sahifalari Texinfo hujjatlari kabi yangilanmaydi).

- fayl nomi haqida Chiqish faylining nomini belgilaydi. Agar siz ob'ekt faylini kompilyatsiya qilsangiz, bu odatda kerak emas, ya'ni sukut bo'yicha filename.c filename.o bilan almashtiriladi. Ammo, agar siz bajariladigan faylni yaratsangiz, sukut bo'yicha (tarixiy sabablarga ko'ra) u a.out nomi ostida yaratiladi. Bu, shuningdek, chiqish faylini boshqa katalogga joylashtirmoqchi bo'lganingizda ham foydalidir.
- dan Buyruqlar satri uchun belgilangan manba faylini bog'lamasdan kompilyatsiya qiladi. Bu har bir manba fayl uchun ob'ekt faylini yaratadi. Make-dan foydalanilganda, odatda har bir ob'ekt fayli uchun gcc kompilyatori chaqiriladi; Shunday qilib, xatolik yuz berganda, qaysi faylni to'play olmaganligini aniqlash osonroq. Ammo, agar siz buyruqlarni qo'lda yozsangiz, ko'pincha bitta gcc chaqiruvida bir nechta fayllar ro'yxati keltirilgan. Agar buyruq satrida bir nechta faylni ko'rsatishda noaniqlik yuzaga kelsa, faqat bitta faylni ko'rsatish yaxshiroqdir. Masalan, gcc -c -o a.o a.c b.c o'rniga gcc -c -o a.o b.c.
-D foo Buyruqlar satrida preprocessor makroslarini belgilaydi. Qobiq maxsus deb hisoblanadigan belgilarni bekor qilishingiz kerak bo'lishi mumkin. Masalan, mag'lubiyatni belgilashda "tugatish belgilarini ishlatishdan saqlaning." Ikkala keng tarqalgan usul - "-Dfoo \u003d" bar "" va -Dfoo \u003d \\ "bar \\". Birinchi usul juda yaxshi ishlaydi, agar satrda bo'sh joy bo'lsa, chunki qobiq bo'shliqlarni maxsus usulda davolaydi.
Men katalog Fayllarni qidirish uchun kataloglar ro'yxatiga katalog qo'shadi.
-L katalogi Kutubxonalar qidirilgan kataloglar ro'yxatiga katalog qo'shadi, agar boshqacha ko'rsatilmagan bo'lsa, gcc umumiy kutubxonalarga statikdan ustunlik beradi.
-l foo Lib foo-ga qarshi havolalar. Agar boshqacha ko'rsatilmagan bo'lsa, gcc statik (lib foo .a) o'rniga umumiy kutubxonalar (lib foo .so) bilan bog'lanishni afzal ko'radi. Bog'lovchi ro'yxatdagi barcha kutubxonalarni funktsiyalarni ro'yxat tartibida izlaydi. Barcha kerakli funktsiyalar topilganda qidiruv tugaydi.
-statik Faqat statik kutubxonalarga havolalar. 8-bobga qarang.
-g, -ggdb Tuzatish ma'lumotlarini o'z ichiga oladi. -G parametri gcc-ni standart disk raskadrovka ma'lumotlarini qo'shishga majbur qiladi. -Ggdb opsiyasi yoqishni bildiradi katta miqdor faqat gdb tuzatuvchisi tushunadigan ma'lumot.
Agar disk maydoni cheklangan bo'lsa yoki ulanish tezligi uchun ba'zi funktsiyalardan voz kechmoqchi bo'lsangiz, -g dan foydalanishingiz kerak. Bunday holda, sizga gdb-dan tashqari tuzatuvchidan foydalanish kerak bo'lishi mumkin. Eng to'liq disk raskadrovka uchun -ggdb-ni belgilashingiz kerak. Bunday holda, gcc maksimal darajada tayyorlaydi batafsil ma'lumot gdb uchun. Shuni ta'kidlash kerakki, aksariyat kompilyatorlardan farqli o'laroq, gcc disk raskadrovka ma'lumotlarini optimallashtirilgan kodga kiritadi. Biroq, optimallashtirilgan kodni tuzatuvchida kuzatib borish juda qiyin bo'lishi mumkin, chunki ish vaqtida bajarilishi kutilayotgan kod qismlarining sakrashlari va sakrashlari bo'lishi mumkin. Biroq, siz olishingiz mumkin yaxshi taqdimot optimallashtiruvchi kompilyatorlar kodni bajarish usulini qanday o'zgartirishi haqida.
-O, -O n Kodni optimallashtirishga majbur qiladi. Odatiy bo'lib, gcc oz miqdordagi optimallashtirishni amalga oshiradi; raqamni (n) ko'rsatishda optimallashtirish ma'lum darajada amalga oshiriladi. Eng keng tarqalgan optimallashtirish darajasi - 2; hozirda gcc-ning standart versiyasida eng yuqori optimallashtirish darajasi - 3. Biz -O2 yoki -O3 dan foydalanishni tavsiya etamiz; -O3 dastur hajmini oshirishi mumkin, agar bu muhim bo'lsa, ikkalasini ham sinab ko'ring. Agar sizning dasturingiz uchun xotira va disk maydoni muhim bo'lsa, siz shuningdek, -Os parametridan foydalanishingiz mumkin, bu bajarilish vaqtini oshirish orqali kod hajmini minimallashtiradi. gcc faqat kamida minimal optimallashtirish (-O) qo'llanilganda ichki o'rnatilganlarni yoqadi.
-ansi Barcha ANSI standartlari (X3.159-1989) yoki ularning ISO ekvivalenti (ISO / IEC 9899: 1990) (odatda C89 yoki kamroq C90 deb nomlanadi) ning C dasturlarida qo'llab-quvvatlash. Shuni ta'kidlash kerakki, bu ANSI / ISO standartiga to'liq mos kelmaydi.
-Ansi opsiyasi odatda ANSI / ISO standartlariga zid bo'lgan gcc kengaytmalarini o'chiradi. (Ushbu kengaytmalar boshqa ko'plab C kompilyatorlari tomonidan qo'llab-quvvatlanganligi sababli, amalda bu muammo emas.) Bu shuningdek, sarlavha fayllari ANSI / ISO mos muhitini qo'llab-quvvatlash uchun foydalanadigan __STRICT_ANSI__ so'lini (ushbu kitobda keyinroq tasvirlangan) belgilaydi.
-pantik ANSI / ISO C til standarti talab qiladigan barcha ogohlantirishlar va xato xabarlarini aks ettiradi. Bu to'liq ANSI / ISO muvofiqligini ta'minlamaydi.
- Devor Odatda foydali bo'lgan barcha gcc ogohlantirishlarini yaratishga imkon beradi. Ammo bu muayyan holatlarda foydali bo'lishi mumkin bo'lgan variantlarni o'z ichiga olmaydi. Shunga o'xshash so'zlashuv darajasi sizning manba kodingizga nisbatan lint ajraluvchisi uchun o'rnatiladi, gcc har bir kompilyator ogohlantirishini qo'lda yoqish va o'chirishga imkon beradi. Barcha ogohlantirishlar gcc qo'llanmasida batafsil bayon etilgan.
5.2. Sarlavha fayllari
5.2.1. uzoq uzoq

Uzoq uzunlik, xotira bloki hech bo'lmaganda uzoqroq bo'lganligini ko'rsatadi. Intel i86 va boshqa 32-bitli platformalarda uzunlik 32 bit, uzun 64 bit. 64-bitli platformalarda ko'rsatgichlar va uzun uzunliklar 64 bitni tashkil qiladi, platformaga qarab uzoq 32 yoki 64 bit bo'lishi mumkin. Uzoq uzun tur C99 standartida (ISO / IEC 9899: 1999) qo'llab-quvvatlanadi va gcc tomonidan taqdim etilgan uzoq muddatli C kengaytmasi.

5.2.2. Ichki funktsiyalar

Linux sarlavhalarining ba'zi qismlarida (xususan, ma'lum bir tizimga xos bo'lganlar) o'rnatilgan funktsiyalar juda keng qo'llaniladi. Ular makroslar kabi tezkor (qo'ng'iroqlarni amalga oshirish uchun xarajat talab qilinmaydi) va oddiy funktsiya chaqiruvida mavjud bo'lgan har qanday tekshiruvni ta'minlaydi. Kirish funktsiyalari kodini chaqirish kamida minimal optimallashtirish (-O) yoqilgan bo'lishi kerak.

5.2.3. Muqobil rivojlangan kalit so'zlar

Gcc-da har bir kengaytirilgan kalit so'z (ANSI / ISO standartida tavsiflanmagan kalit so'zlar) ikkita versiyaga ega: o'zi kalit so'z va ikkala tomonni ikkita pastki chiziq bilan o'ralgan kalit so'z. Standart rejimda kompilyator ishlatilganda (odatda -ansi opsiyasi ishlatilganda) oddiy kengaytirilgan kalit so'zlar tan olinmaydi. Masalan, sarlavha faylidagi atribut kalit so'zi __attribute__ sifatida yozilishi kerak.

5.2.4. Xususiyatlar

Kengaytirilgan atribut kalit so'zi gcc-ga ANSI / ISO C kodi ruxsat berganidan ko'ra funktsiya, o'zgaruvchi yoki e'lon qilingan tur haqida ko'proq ma'lumot berish uchun ishlatiladi. Masalan, hizalanmış atribut gcc ga o'zgaruvchini yoki turini qanday tekislash kerakligini aytadi; qadoqlangan atribut hech qanday plomba ishlatilmasligini bildiradi; noreturn funktsiya hech qachon qaytmasligini belgilaydi, bu gcc-ni yaxshiroq optimallashtirishga va soxta ogohlantirishlardan qochishga imkon beradi.

Funktsiya atributlari ularni funktsiya deklaratsiyasiga qo'shish orqali e'lon qilinadi, masalan:

void die_die_die (int, char *) __attribute__ ((__noreturn__));

Atributlar deklaratsiyasi qavslar va nuqta-vergul orasiga joylashtirilgan va atribut kalit so'zini, so'ngra ikki qavsli atributlarni o'z ichiga oladi. Agar atributlar ko'p bo'lsa, vergul bilan ajratilgan ro'yxatdan foydalanish kerak.

int printm (char *, ...)

Atribut __ ((const,

format (printf, 1, 2)));

Ushbu misolda siz printm-ning ko'rsatilgan qiymatlardan boshqa hech qanday qiymatlarni hisobga olmasligini va kod ishlab chiqarish (const) bilan bog'liq nojo'ya ta'sirlarni ko'rmasligini ko'rishingiz mumkin, printm gcc funktsiya argumentlarini printf () argumentlari bilan bir xil tarzda tekshirishi kerakligini ko'rsatadi. Birinchi argument format satri, ikkinchisi esa birinchi almashtirish parametri (format).

Ba'zi xususiyatlar biz davom etayotganimizda muhokama qilinadi (masalan, 8-bobda umumiy kutubxonalar yig'ilishini tavsiflashda). Atributlar haqida to'liq ma'lumotni gcc Texinfo hujjatlarida topish mumkin.

Vaqti-vaqti bilan Linux sarlavhalarini ko'rib chiqishingiz mumkin. Ehtimol siz ANSI / ISOga mos kelmaydigan bir qator dizaynlarni topishingiz mumkin. Ulardan ba'zilari o'rganishga arziydi. Ushbu kitobda muhokama qilingan barcha konstruktsiyalar gcc hujjatlarida batafsil bayon etilgan.

Vaqti-vaqti bilan Linux sarlavhalarini ko'rib chiqishingiz mumkin. Ehtimol siz ANSI / ISOga mos kelmaydigan bir qator dizaynlarni topishingiz mumkin. Ulardan ba'zilari o'rganishga arziydi. Ushbu kitobda muhokama qilingan barcha konstruktsiyalar gcc hujjatlarida batafsil bayon etilgan.

Endi siz C standarti haqida bir-ikki narsani bilib oldingiz, endi siz yozgan S standartiga mos kelishingizni ta'minlash uchun gcc kompilyatori taklif qiladigan variantlarni ko'rib chiqamiz. Sizning C kodingiz standartlarga mos kelishini va kamchiliklardan xoli bo'lishini ta'minlashning uchta usuli mavjud: siz moslamoqchi bo'lgan standart versiyasini boshqarish variantlari, sarlavha fayllarini boshqarish bo'yicha ta'riflar va qattiqroq tekshiruvlarni boshlash uchun ogohlantirish parametrlari. ...

Gcc-ning ulkan variantlari mavjud va bu erda biz faqat eng muhim deb hisoblagan narsalarni ko'rib chiqamiz. Variantlarning to'liq ro'yxatini gcc onlayn qo'llanmasidagi sahifalarida topish mumkin. Shuningdek, siz foydalanishingiz mumkin bo'lgan ba'zi #define variantlarini qisqacha muhokama qilamiz; ular odatda #include satrlaridan oldin manba kodingizda yoki gcc buyruq satrida ko'rsatilgan bo'lishi kerak. Sizni zamonaviy standartdan foydalanishga majburlaydigan oddiy bayroq o'rniga amaldagi standartni tanlash variantlarining ko'pligi sizni hayratga solishi mumkin. Sababi shundaki, ko'plab eski dasturlar kompilyatorlarning tarixiy xatti-harakatlariga tayanadi va ularni eng so'nggi standartlarga moslashtirish uchun katta mehnat talab etiladi. Kamdan kam hollarda, agar siz kompilyatoringizni ishlaydigan kodni to'xtatib turishi uchun yangilashni xohlasangiz. Standartlar o'zgarganda, standartning eng so'nggi versiyasi bo'lmasa ham, ma'lum bir standartga qarshi ishlash imkoniyatiga ega bo'lish muhimdir.

Agar siz shaxsiy foydalanish uchun kichik dastur yozayotgan bo'lsangiz ham, standartlarga muvofiqlik bu qadar muhim bo'lmasligi mumkin, ko'pincha dasturni bajarishdan oldin kompilyatorni sizning kodingizdagi xatolarni qidirishga majbur qilish uchun qo'shimcha gcc ogohlantirishlarini kiritish mantiqan to'g'ri keladi. Bu har doim disk raskadrovka kodidan o'tib, muammo qayerda bo'lishi mumkinligini bilishdan ko'ra samaraliroq. Tuzuvchi oddiy standartlarni tekshirishdan tashqariga chiqadigan ko'plab variantlarga ega, masalan, standartga mos keladigan kodni aniqlash qobiliyati, ammo shubhali semantikaga ega bo'lishi mumkin. Masalan, dasturda o'zgaruvchiga uni ishga tushirishidan oldin kirish imkoniyatini beradigan ijro buyrug'i bo'lishi mumkin.

Agar siz umumiy foydalanish uchun dastur yozishingiz kerak bo'lsa, standartga muvofiqlik darajasi va kompilyatorning ogohlantirish turlarini etarli deb hisoblasangiz, biroz ko'proq harakat qilish va kodingizni hech qanday ogohlantirishsiz kompilyatsiya qilish juda muhimdir. Agar siz ba'zi ogohlantirishlarga yo'l qo'ysangiz va ularni e'tiborsiz qoldirishga odatlansangiz, bir kun siz yo'qolish xavfi bo'lgan jiddiyroq ogohlantirish bo'lishi mumkin. Agar sizning kodingiz doimo ogohlantiruvchi xabarlarsiz tuzilsa, yangi ogohlantirish sizning e'tiboringizni jalb qilishi muqarrar. Kodni ogohlantirishsiz kompilyatsiya qilish bortda yurish uchun yaxshi odatdir.

Standartlarni kuzatish uchun kompilyator variantlari

Ansi standartlarning eng muhim variantidir va kompilyatorni ISO C90 til standartiga muvofiq ishlashga majbur qiladi. U ba'zi nostandart mos keladigan gcc kengaytmalarini o'chiradi, C dasturlarida C ++ uslubidagi sharhlarni (//) o'chirib qo'yadi va ANSI trigraflarini (uch belgidan iborat ketma-ketliklar) qayta ishlashga imkon beradi. Bundan tashqari, u __ STRICT_ANSI__ so'lini o'z ichiga oladi, bu standart faylga mos kelmaydigan sarlavha fayllaridagi ba'zi kengaytmalarni o'chirib qo'yadi. Kompilyatorning keyingi versiyalarida qabul qilingan standart o'zgarishi mumkin.

Std \u003d - Ushbu parametr talab qilinadigan standartni aniq belgilaydigan parametrni taqdim etish orqali ishlatiladigan standart ustidan nozik nazoratni ta'minlaydi. Quyidagi asosiy variantlar:

C89 - C89 standartini qo'llab-quvvatlash;

Iso9899: 1999 - ISO standartining so'nggi versiyasini qo'llab-quvvatlaydi, C90;

Gnu89 - C89 standartini qo'llab-quvvatlang, ammo ba'zi GNU kengaytmalariga va ba'zi C99 funktsiyalariga ruxsat bering. Bu gcc-ning 4.2-versiyasida standart hisoblanadi.

Belgilangan direktivalarda standartni kuzatish variantlari

Buyruqlar satrida yoki dasturning manba kodidagi ta'riflar sifatida parametrlar bilan belgilanadigan doimiylar (#defines) mavjud. Biz ular kompilyator buyruq satridan foydalanayotgan deb o'ylaymiz.

STRICT_ANSI__ - sizni C ISO standartini qo'llashga majbur qiladi. -Ansi opsiyasi qachon kompilyator buyrug'i satrida ko'rsatilganligi aniqlanadi.

POSIX_C_SOURCE \u003d 2 - IEEE Std 1003.1 va 1003.2 tomonidan belgilangan funktsiyalarni yoqadi. Ushbu standartlarga biroz keyinroq ushbu bobda qaytamiz.

BSD_SOURCE - BSD tizimlarining ishlashini ta'minlaydi. Agar ular POSIX ta'riflariga zid bo'lsa, BSD ta'riflari ustunlikka ega.

GNU_SOURCE - keng xususiyatlar va funktsiyalarga, shu jumladan GNU kengaytmalariga ruxsat beradi. Agar ushbu ta'riflar POSIX ta'riflariga zid bo'lsa, ikkinchisi ustunlikka ega.

Ogohlantirishlar uchun kompilyator parametrlari

Ushbu parametrlar buyruq satridan kompilyatorga uzatiladi. Va yana biz faqat asosiylarini sanab o'tamiz, to'liq ro'yxat gcc onlayn ma'lumotnomasida topishingiz mumkin.

Pedantic - bu C kodining tozaligini tekshirishning eng kuchli variantidir.C standartiga muvofiqligini tekshirishni yoqish bilan bir qatorda, standart tomonidan taqiqlangan ba'zi an'anaviy C konstruktsiyalarini o'chirib qo'yadi va barcha GNU kengaytmalarini standartga mos kelmaydi. Ushbu parametr sizning C kodingizning portativligini maksimal darajada oshirish uchun ishlatilishi kerak.Muqobil tomoni shundaki, kompilyator dastur kodingizning tozaligi haqida juda qayg'uradi va ba'zida qolgan bir nechta ogohlantirishlar bilan shug'ullanish uchun miyangizni tirgaklashingiz kerak.

Wformat - printf oilasi funktsiyalarining argument turlari to'g'riligini tekshiradi.

Wparentheses - Qavslarni kerak bo'lmagan joylarda ham tekshiradi. Ushbu parametr murakkab tuzilmalarni maqsadga muvofiq ravishda ishga tushirilishini tekshirish uchun juda foydali.

Wswitch-default - odatda yaxshi kodlash uslubi deb hisoblangan switch bayonotlarida standart parametr mavjudligini tekshiradi.

Wunused - har xil holatlarni tekshiradi, masalan statik funktsiyalar e'lon qilingan, ammo tavsiflanmagan, ishlatilmagan parametrlar, bekor qilingan natijalar.

Devor - gcc ogohlantirish turlarining ko'pini, shu jumladan oldingi barcha W variantlarini o'z ichiga oladi (faqat --pedantic tomonidan qamrab olinmaydi). Uning yordami bilan dastur kodining tozaligiga erishish oson.

Eslatma

Ko'proq ogohlantirish variantlari mavjud, tafsilotlar uchun gcc veb-sahifalariga qarang. Odatda -Wall-dan foydalanishni tavsiya etamiz; yuqori sifatli dastur kodini ta'minlaydigan tekshiruvchi o'rtasida yaxshi kelishuv va kompilyator bekor qilish qiyin bo'ladigan juda ahamiyatsiz ogohlantirishlarni berishi kerak.

GCC har qanday tarqatish bilan ta'minlangan Linux va odatda sukut bo'yicha o'rnatiladi. GCC interfeysi - bu UNIX platformasidagi standart kompilyator interfeysi, o'tgan asrning 60-yillari oxiri, 70-yillari boshlarida - buyruq satri interfeysi. Xavotir olmang, o'tgan vaqt davomida foydalanuvchining o'zaro ta'sir mexanizmi bu holda mumkin bo'lgan mukammallikka qadar takomillashtirilgan va GCC bilan ishlash (agar bir nechta qo'shimcha yordam dasturlari va oqilona bo'lsa) matn muharriri) har qanday zamonaviy vizual IDE-larga qaraganda osonroq. To'plam mualliflari iloji boricha dasturlarni yig'ish va yig'ish jarayonini avtomatlashtirishga harakat qilishdi. Foydalanuvchi boshqaruv dasturini chaqiradi gcc, u berilgan buyruq qatori argumentlarini (variantlar va fayl nomlari) sharhlaydi va har bir kirish fayli uchun foydalanilgan dasturlash tiliga muvofiq o'z kompilyatorini ishga tushiradi, agar kerak bo'lsa, gcc avtomatik ravishda assembler va linker (linker) ni chaqiradi.

Qizig'i shundaki, kompilyatorlar fayl kengaytmalariga g'amxo'rlik qiladigan bir nechta UNIX dasturlaridan biridir. Kengaytirilgan holda, GCC oldida qanday fayl turini va u bilan nima qilish kerakligini (mumkin) aniqlaydi. Til manbasi fayllari C tilida .c kengaytmasi bo'lishi kerak C ++ixtiyoriy ravishda .cpp, nom fayllari tilda C .h, .o ob'ekt fayllari va boshqalar. Agar siz noto'g'ri kengaytmani ishlatsangiz, gcc to'g'ri ishlamaydi (agar siz umuman rozi bo'lsangiz, biror narsa qiling).

Amaliyotga o'tamiz. Keling, ba'zi oddiy dasturlarni yozamiz, kompilyatsiya qilamiz va bajaramiz. Biz tilimizdagi misol dasturining manba fayli sifatida asl bo'lmaymiz C Quyidagi tarkibli fayl yarataylik:

/ * salom.c * /

# shu jumladan

Asosiy ( bekor )
{

Printf ("Salom Dunyo \\ n");

qaytish 0 ;

Endi c hello.c katalogida buyruq bering:

$ gcc salom.c

Bir necha soniyadan so'ng, katalogda a.out fayli paydo bo'ladi:

$ ls
salom.c

Bu bizning dasturimizning tugallangan bajariladigan faylidir. Odatiy gcc chiqadigan bajariladigan faylga a.out nomini beradi (bir vaqtlar bu nom anglatardi) assembler chiqishi).

$ file a.out
a.out: ELF 64-bitli LSB bajariladigan, x86-64, versiya 1 (SYSV), dinamik ravishda bog'langan (umumiy liblardan foydalaniladi), GNU / Linux 2.6.15 uchun, echilmagan

Olingan natijani ishga tushiramiz dasturiy ta'minot:

$ ./a.out
Salom Dunyo


Nima uchun joriy katalogdan faylni bajarish buyrug'ida faylga yo'lni aniq belgilash kerak? Agar bajariladigan faylga yo'l aniq ko'rsatilmagan bo'lsa, qobiq buyruqlarni sharhlab, faylni PATH tizim o'zgaruvchisiga kiritilgan kataloglardan qidiradi.

$ echo $ PATH
/ usr / local / sbin: / usr / local / bin: / usr / sbin: / usr / bin: / sbin: / bin: / usr / games

Ro'yxatdagi kataloglar ikki nuqta belgisi bilan ajratilgan. Fayllarni qidirishda, qobiq kataloglarni ro'yxatdagi tartibda izlaydi. Odatiy bo'lib, xavfsizlik sababli, joriy katalog. ro'yxatga kiritilmagan, shuning uchun qobiq undagi bajariladigan fayllarni qidirmaydi.

Nima uchun buni qilish tavsiya etilmaydi. PATHda? Haqiqiy ko'p foydalanuvchi tizimida har doim yomon foydalanuvchi bo'lishi mumkin, chunki u jamoat katalogiga zararli dasturni bajariladigan fayl nomi bilan qo'shib qo'yadi, u tez-tez superuser huquqlari bilan mahalliy administrator tomonidan chaqiriladigan ba'zi buyruqlar nomiga to'g'ri keladi ... Agar fitna muvaffaqiyatli bo'lsa. kataloglar ro'yxatining boshida joylashgan.


Qulaylik fayl faylning buyruq satrida uzatilgan turi (tizim nuqtai nazaridan) haqidagi ma'lumotlarni aks ettiradi, ba'zi fayl turlari uchun fayl tarkibiga oid qo'shimcha ma'lumotlarni aks ettiradi.

$ file hello.c
salom.c: ASCII C dastur matni
$ fayl annotation.doc
annotation.doc: CDF V2 Document, Little Endian, Os: Windows, Versiya 5.1, Kod sahifasi: 1251, Muallif: MIH, Andoza: Normal.dot, Oxirgi marta saqlangan: MIH, Qayta ko'rib chiqilgan raqam: 83, Ilova yaratish nomi: Microsoft Office Word, Jami tahrirlash vaqti: 09:37:00, Oxirgi bosilgan sanasi: 2009 yil 22-yanvar, 07:31:00, Yaratilish vaqti / sanasi: dushanba, 12-yanvar, 07:36:00, oxirgi saqlangan vaqt / sana: 22-yanvar, dushanba. 07:34:00 2009 yil, Sahifalar soni: 1, so'zlar soni: 3094, belgilar soni: 17637, xavfsizlik: 0

Muvaffaqiyatli dastur uchun foydalanuvchidan talab qilinadigan narsa shu. gcc :)

Chiqariladigan bajariladigan faylning nomi (shuningdek, yaratilgan boshqa har qanday fayl) gcc) bilan o'zgartirilishi mumkin imkoniyatlari -o:

$ gcc -o salom salom.c
$ ls
salom salom.c
$ ./ salom
Salom Dunyo


Bizning misolimizda main () funktsiyasi keraksiz ko'rinadigan 0 qiymatini qaytaradi. UNIX-ga o'xshash tizimlarda dastur tugagandan so'ng qobiqga butun sonni qaytarish odat tusiga kiradi - agar u muvaffaqiyatli bo'lsa nol, aks holda boshqa usul. Qobiq tarjimoni avtomatik ravishda olingan qiymatni nomlangan muhit o'zgaruvchisiga beradi? ... Siz echo $ yordamida uning tarkibini ko'rishingiz mumkin? :

$ ./ salom
Salom Dunyo
$ echo $?
0

Yuqorida aytilgan edi gcc bu kompilyatsiya jarayonini avtomatlashtirish uchun mo'ljallangan boshqaruv dasturi. Keling, gcc hello.c buyrug'ining bajarilishi natijasida aslida nima sodir bo'lishini ko'rib chiqamiz.

Kompilyatsiya jarayonini 4 asosiy bosqichga bo'lish mumkin: oldindan ishlov berish, kompilyatsiya o'zi, yig'ish, bog'lash (bog'lash).

Tanlovlar gcc ushbu bosqichlarning har qandayida jarayonni to'xtatishga imkon bering.

Dastlabki protsessor kompilyatsiya uchun manba faylini tayyorlaydi - u sharhlarni kesib tashlaydi, sarlavha fayllari tarkibini qo'shadi (#prosessor yo'riqnomasi #include), makroslarning kengayishini amalga oshiradi (ramziy konstantalar, protsessor ko'rsatmasi #define).

Fursatdan foydalanib variant - E keyingi harakatlar gcc siz protsessor tomonidan ishlov berilgan faylning tarkibini to'xtatishingiz va ko'rishingiz mumkin.

$ gcc -E -o salom.i salom.c
$ ls
salom.c salom.i
$ kamroq salom.i
. . .
# 1 "/usr/include/stdio.h" 1 3 4
# 28 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
. . .
typedef imzosiz char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
. . .
extern int printf (__const char * __ cheklash __format, ...);
. . .
# 4 "salom.c" 2
asosiy (bekor)
{
printf ("Salom Dunyo \\ n");
qaytish 0;
}

Dastlabki protsessor tomonidan ishlov berilgandan so'ng, dasturimizning manba kodi shishib ketdi va o'qib bo'lmaydigan shaklga ega bo'ldi. Bir vaqtlar o'z qo'llarimiz bilan yozgan kod faylning oxirida bir necha qatorga qadar qaynab ketdi. Sababi - standart kutubxonaning sarlavha faylini o'z ichiga oladi C... Stdio.h sarlavha faylining o'zi juda ko'p turli xil narsalarni o'z ichiga oladi va boshqa sarlavha fayllarini kiritishni talab qiladi.

Hello.i faylining kengayishiga e'tibor bering. Shartnomalar bo'yicha gcc .i kengaytmasi til manba fayllariga mos keladi C oldindan ishlov berishni talab qilmaydigan. Bunday fayllar protsessorni chetlab o'tib tuziladi:

$ gcc -o salom salom.i
$ ls
salom salom.c salom.i
$ ./ salom
Salom Dunyo

Oldindan ishlov berilgandan so'ng, kompilyatsiya navbati. Kompilyator yuqori darajadagi dasturning manba kodini assotsiatsiya tili kodiga o'zgartiradi.

Kompilyatsiya so'zining ma'nosi loyqa. Masalan, vikipediyachilar, ishonib, murojaat qilishadi xalqaro standartlarbu kompilyatsiya "bu kompilyator dasturi tomonidan yuqori darajadagi dasturlash tilida yozilgan dasturning asl matnini mashinaga yaqin tilga yoki ob'ekt kodiga aylantirish". Printsipial jihatdan ushbu ta'rif bizga mos keladi, chunki assambleya tili mashina tiliga nisbatan haqiqatan ham yaqinroq C... Ammo kundalik hayotda kompilyatsiya ko'pincha dasturning har qanday dasturlash tilidagi manba kodini bajariladigan kodga o'zgartiradigan har qanday operatsiya sifatida tushuniladi. Ya'ni, yuqoridagi barcha to'rt bosqichni o'z ichiga olgan jarayonni kompilyatsiya deb ham atash mumkin. Hozirgi matnda ham xuddi shunday noaniqlik mavjud. Boshqa tomondan, dasturning manba kodini assotsiatsiya tili kodiga aylantirish operatsiyasini tarjima so'zi bilan ham belgilash mumkin - "dasturlash tillaridan birida taqdim etilgan dasturni boshqa tildagi dasturga aylantirish va ma'lum ma'noda birinchisiga tenglashtirish".

Kompilyatsiya tugagandan so'ng bajariladigan faylni yaratish jarayonini to'xtatishga imkon beradi variant -S:

$ gcc -S salom.c
$ ls
salom.c salom.s
$ file hello.s
salom.s: ASCII assembler dasturi matni
$ salom salom
.fayl "salom.c"
.boshim .rodata
.LC0:
.string "Salom Dunyo"
.matn
.globl main
.type main, @funktsiya
asosiy:
pushl% ebp
movl% esp,% ebp
andl $ -16,% esp
subl $ 16,% esp
movl $ .LC0, (% esp)
qo'ng'iroq qo'yadi
movl $ 0,% eax
qoldiring
ret
.siz asosiy, .- asosiy


Dasturni assotsiatsiya tilida bajarilishini o'z ichiga olgan katalogda hello.s fayli paydo bo'ldi. Bilan chiqish faylining nomini belgilashga e'tibor bering imkoniyatlari -o bu holda bu talab qilinmadi, gcc .c kengaytmasini asl fayl nomidagi .s bilan almashtirib, uni avtomatik ravishda yaratdi. Ko'pgina asosiy operatsiyalar uchun gcc chiqish faylining nomi xuddi shunday almashtirish bilan hosil bo'ladi. .S kengaytmasi yig'ilish tili manba fayllari uchun standartdir.

Albatta, siz bajariladigan kodni hello.s faylidan olishingiz mumkin:

$ gcc -o salom salom.s
$ ls
salom salom.c salom.s
$ ./ salom
Salom Dunyo

O'rnatish operatsiyasining keyingi bosqichi - yig'ilish tili kodini mashina kodiga tarjima qilish. Amaliyot natijasi ob'ekt fayli hisoblanadi. Ob'ekt faylida bajarishga tayyor bo'lgan mashina kodlari bloklari, ma'lumotlar bloklari, shuningdek faylda aniqlangan funktsiyalar va tashqi o'zgaruvchilar ro'yxati mavjud ( belgilar jadvali ), lekin unda funktsiyalarning mutlaq manzillari va ma'lumotlar havolalari ko'rsatilmagan. Ob'ekt faylini to'g'ridan-to'g'ri bajarish uchun ishga tushirish mumkin emas, lekin keyinchalik (bog'lash bosqichida) uni boshqa ob'ekt fayllari bilan birlashtirish mumkin (bu holda, belgilar jadvallariga muvofiq, o'zaro faoliyat ma'lumotlarning fayllari o'rtasida mavjud bo'lgan manzillar hisoblab chiqiladi va to'ldiriladi). Variant gcc -c, yig'ish bosqichi oxirida jarayonni to'xtatadi:

$ gcc -c salom.c
$ ls
salom.c salom.o
$ file hello.o
salom.o: ELF 64-bitli LSB ko'chirilishi mumkin, x86-64, versiya 1 (SYSV), echilmagan

Ob'ekt fayllari uchun standart kengaytma .o.

Natijada paydo bo'lgan ob'ekt fayli hello.o bog'lovchiga uzatilsa, bog'lovchi havolalarning manzillarini hisoblab chiqadi, dasturni boshlash va tugatish kodini, kutubxona funktsiyalarini chaqirish kodini qo'shadi va natijada bizda dasturning tayyor bajariladigan fayli bo'ladi.

$ gcc -o salom salom.o
$ ls
salom salom.c salom.o
$ ./ salom
Salom Dunyo

Hozir nima qildik (aniqrog'i) gcc biz uchun buni amalga oshirdi) va oxirgi bosqichning mazmuni bor - bog'lash (bog'lash, bog'lash).

Xo'sh, bu kompilyatsiya haqida va shu bilan. Endi ba'zi bir muhim variantlarga to'xtalamiz gcc.

Variant Men path / to / directory / bilan / headers / files - ko'rsatilgan katalogni sarlavha faylini qidirish yo'llari ro'yxatiga qo'shadi. Tanlov bo'yicha qo'shilgan katalog Men avval qidirildi, so'ng standart tizim kataloglarida qidirish davom etmoqda. Agar imkoniyatlari bo'lsa Men ular tomonidan ko'rsatilgan bir nechta kataloglar chapdan o'ngga qarab skanerlanadi, chunki variantlar paydo bo'ladi.

Variant - Devor - dasturda kompilyatsiya qilishga xalaqit bermaydigan, lekin kompilyatorning fikriga ko'ra, uning bajarilishida muayyan muammolarga olib kelishi mumkin bo'lgan koddagi yuzaga kelishi mumkin bo'lgan xatolardan kelib chiqqan ogohlantirishlarni namoyish etadi. Muhim va foydali variant, ishlab chiquvchilar gcc har doim foydalanishni tavsiya eting. Masalan, quyidagi kabi faylni kompilyatsiya qilishda ko'plab ogohlantirishlar beriladi:

1 / * remark.c * /
2
3 statik int k \u003d 0;
4 statik int l ( int a);
5
6 asosiy ()
7 {
8
9 int a;
10
11 int b, c;
12
13 b + 1;
14
15 b \u003d c;
16
17 int * p;
18
19 b \u003d * p;
20
21 }


$ gcc -o remark remark.c
$ gcc -Wall -o remark.c
remark.c: 7: ogohlantirish: standart parametrlarni "int" ga qaytarish

remark.c: 13: ogohlantirish: hech qanday ta'siri bo'lmagan bayonot
remark.c: 9: ogohlantirish: ishlatilmaydigan 'a' o'zgaruvchisi
remark.c: 21: ogohlantirish: boshqaruv bo'sh bo'lmagan funktsiya oxiriga etadi
remark.c: Yuqori darajada:
remark.c: 3: ogohlantirish: "k" aniqlangan, ammo ishlatilmaydi
remark.c: 4: ogohlantirish: "l" "statik" deb e'lon qilingan, ammo hech qachon aniqlanmagan
remark.c: "asosiy" funktsiyasida:
remark.c: 15: ogohlantirish: "c" ushbu funktsiyada boshlang'ichsiz ishlatiladi
remark.c: 19: ogohlantirish: "p" ushbu funktsiyada boshlang'ichsiz ishlatiladi

Variant - Xato - barcha ogohlantirishlarni xatolarga aylantiradi. Agar ogohlantirish bo'lsa, kompilyatsiya jarayonini bekor qiladi. Bilan birgalikda ishlatiladi variant - Devor.

$ gcc -Werror -o remark remark.c
$ gcc -Werror -Wall - remark remark.c
cc1: ogohlantirishlar xato deb hisoblanadi
remark.c: 7: xato: standart qiymatlarni "int" ga qaytarish
remark.c: "asosiy" funktsiyasida:
remark.c: 13: xato: hech qanday ta'siri bo'lmagan bayonot
remark.c: 9: xato: ishlatilmaydigan 'a' o'zgaruvchisi

-G variant - tuzatuvchining ishlashi uchun zarur bo'lgan ma'lumotlarni ob'ektga yoki bajariladigan faylga joylashtiradi gdb... Keyingi disk raskadrovka uchun loyihani qurishda, variant -g kompilyatsiya vaqtida ham, bog'lanish vaqtida ham qo'shilishi kerak.

Variantlar -O1, -O2, -O3 - kompilyator tomonidan yaratilgan kodni optimallashtirish darajasini belgilash. Raqam ortishi bilan optimallashtirish darajasi oshadi. Variantlarning harakatini ushbu misolda ko'rish mumkin.

Asl fayl:

/ * circle.c * /

Asosiy ( bekor )
{

int men;

uchun (i \u003d 0; i< 10 ; ++i)
;

qaytish men;

Standart optimallashtirish darajasi bilan kompilyatsiya:

$ gcc -S circle.c
$ kamroq doira.s
.file "circle.c"
.matn
.globl main
.type main, @funktsiya
asosiy:
pushl% ebp
movl% esp,% ebp
subl $ 16,% esp
movl $ 0, -4 (% ebp)
Jmp .L2
.L3:
addl $ 1, -4 (% ebp)
.L2:
cmpl $ 9, -4 (% ebp)
.l
movl -4 (% ebp),% eax
qoldiring
ret
.siz asosiy, .- asosiy
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack, "", @ progbits

Maksimal optimallashtirish darajasi bilan kompilyatsiya:

$ gcc -S -O3 doirasi.c
$ kamroq doira.s
.file "circle.c"
.matn
.p2align 4.15
.globl main
.type main, @funktsiya
asosiy:
pushl% ebp
movl $ 10,% eax
movl% esp,% ebp
popl% ebp
ret
.siz asosiy, .- asosiy
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack, "", @ progbits

Ikkinchi holda, natijada olingan kodda halqa haqida ham ma'lumot yo'q. Darhaqiqat, i qiymatini tuzish bosqichida hisoblash mumkin.

Afsuski, haqiqiy loyihalar uchun turli darajadagi optimallashtirish ko'rsatkichlari farqi deyarli sezilmaydi ...

Variant -O0 - har qanday kodni optimallashtirishni bekor qiladi. Variantni disk raskadrovka bosqichida talab qilinadi. Yuqorida ko'rsatilganidek, optimallashtirish dastur tuzilishini tanib bo'lmaydigan darajada o'zgarishiga olib kelishi mumkin, bajariladigan va manba kodlari o'rtasidagi bog'liqlik aniq bo'lmaydi, shuning uchun dasturni bosqichma-bosqich disk raskadrovka qilish mumkin bo'lmaydi. Variant yoqilganda -g, va ni qo'shish tavsiya etiladi -O0.

Variant -Os - optimallashtirishni kod samaradorligi bilan emas, balki olingan fayl hajmi bo'yicha belgilaydi. Bunday holda, dasturning ishlashi standart optimallashtirish darajasi bilan kompilyatsiya paytida olingan kodning ishlashi bilan taqqoslanishi kerak.

Variant -march \u003d arxitektura - maqsadli protsessor arxitekturasini belgilaydi. Qo'llab-quvvatlanadigan arxitekturalar ro'yxati, masalan, protsessor oilasi uchun kengdir Intel / AMD Siz so'rashingiz mumkin i386, pentium, preskott, opteron-sse3 va hokazo. Ikkilik tarqatish foydalanuvchilari dasturlarning belgilangan parametr bilan to'g'ri ishlashi uchun barcha bog'langan kutubxonalarning bir xil variant bilan tuzilishi maqsadga muvofiqligini yodda tutishlari kerak.

Linkerga berilgan variantlar quyida muhokama qilinadi.

Kichik qo'shimcha:

Yuqorida aytilgan edi gcc uzatilgan fayllarning turini (dasturlash tilini) kengaytmasi bilan aniqlaydi va taxmin qilingan turga (tilga) muvofiq ular ustida amallarni bajaradi. Foydalanuvchi yaratilgan fayllarning kengaytmalarini ularni kelishuv talabiga binoan tanlab, kuzatib borishi shart gcc... Aslida gcc o'zboshimchalik bilan nomlangan fayllarni siljitish mumkin. Gcc -x opsiyasi tuzilgan fayllarning dasturlash tilini aniq belgilashga imkon beradi. Ushbu parametr buyruqda keltirilgan barcha keyingi fayllarga tegishli (keyingi variant paydo bo'lguncha) -x). Mumkin bo'lgan variant argumentlari:

c c-header c-cpp-output

c ++ c ++ - sarlavha c ++ - cpp-chiqish

ob'ektiv-c ob'ektiv-c-sarlavha ob'ektiv-c-cpp-chiqish

ob'ektiv-c ++ ob'ektiv-c ++ - maqsad-c ++ sarlavhasi - cpp-chiqish

cpp bilan birlashtiruvchi assembler

ada

f77 f77-cpp-kirish

f95 f95-cpp-kirish

java

Argumentlarning maqsadi ularning yozilishidan aniq bo'lishi kerak (bu erda cpp hech qanday aloqasi yo'q C ++, bu oldindan qayta ishlangan manba kodi fayli). Tekshiramiz:

$ mv salom.c salom.txt
$ gcc -Wall -x c -o salom salom.txt
$ ./ salom
Salom Dunyo

Alohida kompilyatsiya

Tillarning mustahkamligi C / C ++ bu dasturning manba kodini bir nechta fayllarga bo'lish qobiliyati. Hatto ko'proq gapirish mumkin - alohida kompilyatsiya qilish imkoniyati tilning asosidir samarali foydalanish C o'ylab bo'lmaydi. Bu sizni amalga oshirishga imkon beradigan ko'p faylli dasturlash C kabi yirik loyihalar Linux (bu erda so'z ostida Linux ham yadroni, ham butun tizimni anglatadi). Alohida kompilyatsiya dasturchiga nima beradi?

1. Dastur (loyiha) kodini yanada o'qish imkoniyatini beradi. Bir necha o'nlab ekranlar uchun manba fayli deyarli to'liq bo'lmay qoladi. Agar ba'zi (oldindan o'ylangan) mantiqqa muvofiq, siz uni bir nechta kichik qismlarga (har biri alohida faylda) ajratsangiz, loyihaning murakkabligi bilan kurashish ancha oson bo'ladi.

2. Loyihani qayta kompilyatsiya qilish vaqtini qisqartirishga imkon beradi. Agar bitta faylga o'zgartirishlar kiritilgan bo'lsa, butun loyihani qayta kompilyatsiya qilishning ma'nosi yo'q, faqat shu o'zgartirilgan faylni qayta kompilyatsiya qilish kifoya.

3. Loyihadagi ishlarni bir nechta ishlab chiquvchilar o'rtasida taqsimlashga imkon beradi. Har bir dasturchi loyihaning o'z qismini yaratadi va disk raskadrovka qiladi, ammo istalgan vaqtda yakuniy mahsulotga olingan barcha ishlanmalarni to'plash (tiklash) mumkin bo'ladi.

4. Alohida kompilyatsiz kutubxonalar bo'lmaydi. Kodni qayta ishlatish va tarqatish C / C ++va kod ikkilik bo'lib, bu bir tomondan ishlab chiquvchilarga uni o'z dasturlariga kiritish uchun oddiy mexanizmni taqdim etishiga, boshqa tomondan ulardan aniq ijro tafsilotlarini yashirishga imkon beradi. Loyiha ustida ishlayotganda, har doim o'ylab ko'rishga arziydimi va kelajakda allaqachon amalga oshirilgan narsalardan hech narsa kerak emasmi? Ehtimol, siz kodning bir qismini oldindan kutubxona sifatida tanlashingiz va tartibga solishingiz kerakmi? Mening fikrimcha, ushbu yondashuv hayotni sezilarli darajada soddalashtiradi va ko'p vaqtni tejaydi.

Gcc, albatta, alohida kompilyatsiyani qo'llab-quvvatlaydi va foydalanuvchidan maxsus ko'rsatmalarni talab qilmaydi. Umuman olganda, hamma narsa juda oddiy.

Mana amaliy misol (juda va juda shartli bo'lsa ham).

Manba kodi fayli o'rnatilgan:

/ * main.c * /

# shu jumladan

# "first.h" ni kiriting
# "second.h" ni kiriting

int asosiy ( bekor )
{

Birinchisi ();
ikkinchi ();

Printf ("Asosiy funktsiya ... \\ n");

qaytish 0 ;


/ * birinchi.h * /

bekor birinchi ( bekor );


/ * first.c * /

# shu jumladan

# "first.h" ni kiriting

bekor birinchi ( bekor )
{

Printf ("Birinchi funktsiya ... \\ n");


/ * soniya. soat * /

bekor ikkinchi ( bekor );


/ * second.c * /

# shu jumladan

# "second.h" ni kiriting

bekor ikkinchi ( bekor )
{

Printf ("Ikkinchi funktsiya ... \\ n");

Umuman olganda, bizda quyidagilar mavjud:

$ ls
birinchi.c birinchi.h asosiy.c ikkinchi.c ikkinchi.h

Ushbu iqtisodiyotning barchasi bitta buyruqqa to'planishi mumkin:

$ gcc -Wall -o main main.c first.c second.c
$ ./main
Birinchi funktsiya ...
Ikkinchi funktsiya ...
Asosiy funktsiya ...

Faqat bu bizga deyarli hech qanday bonuslarni bermaydi, bir nechta fayllarga tarqalgan tuzilgan va o'qiladigan kodlar bundan mustasno. Yuqorida sanab o'tilgan barcha afzalliklar kompilyatsiyaga ushbu yondashuvda paydo bo'ladi:

$ gcc -Wall -c main.c
$ gcc -Wall -c first.c
$ gcc -Wall -c second.c
$ ls
birinchi.c birinchi.h birinchi.o asosiy.c asosiy.o ikkinchi.c ikkinchi.h ikkinchi.o
$ gcc -o main main.o first.o second.o
$ ./main
Birinchi funktsiya ...
Ikkinchi funktsiya ...
Asosiy funktsiya ...

Biz nima qildik? Har bir manba faylidan (variant bilan kompilyatsiya qilish -c) ob'ekt faylini oldi. Keyin ob'ekt fayllari yakuniy bajariladigan faylga bog'langan. Albatta jamoalar gcc ko'proq bo'ldi, lekin hech kim loyihalarni qo'lda to'plamaydi, buning uchun kollektor yordam dasturlari mavjud (eng ommabop) qilish). Yuqorida sanab o'tilgan alohida kompilyatsiyaning barcha afzalliklari yig'ish dasturlaridan foydalanish orqali namoyon bo'ladi.

Savol tug'iladi: qanday qilib bog'lovchi qo'ng'iroqlarning manzilini to'g'ri hisoblab, ob'ekt fayllarini birlashtira oladi? Qanday qilib u second.o faylida second () funktsiya kodi borligini va main.o faylining kodida uning chaqiruvi borligini qayerdan biladi? Ko'rinib turibdiki, hamma narsa oddiy - ob'ekt fayli so'zda o'z ichiga oladi ramzlar jadvali , shu jumladan ba'zi kod pozitsiyalarining nomlari (funktsiyalar va tashqi o'zgaruvchilar). Bog'lovchi har bir ob'ekt faylining belgilar jadvalini skanerdan o'tkazadi, umumiy (mos keladigan nomlar bilan) pozitsiyalarni qidiradi, shu asosda foydalanilgan funktsiyalar (yoki ma'lumotlar bloklari) kodining haqiqiy joylashuvi to'g'risida xulosa chiqaradi va shunga muvofiq bajariladigan fayldagi qo'ng'iroq manzillarini qayta hisoblab chiqadi.

Yordamchi dastur yordamida ramzlar jadvalini ko'rishingiz mumkin nm.

$ nm main.o
U birinchi
00000000 T asosiy
U qo'yadi
U ikkinchi
$ nm birinchi.o
Avval 00000000 T
U qo'yadi
$ nm soniya.o
U qo'yadi
00000000 T sekund

Put chaqiruvining ko'rinishi kompilyatsiya vaqtida Put () ga aylangan printf () standart kutubxona funktsiyasidan foydalanish bilan izohlanadi.

Belgilar jadvali nafaqat ob'ekt faylida, balki bajariladigan faylda ham yoziladi:

$ nm asosiy
08049f20 d _DINAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
080484fc R _IO_stdin_used
w _Jv_RegisterClasses
08049f10 d __CTOR_END__
08049f0c d __CTOR_LIST__
08049f18 D __DTOR_END__
08049f14 d __DTOR_LIST__
08048538 r __FRAME_END__
08049f1c d __JCR_END__
08049f1c d __JCR_LIST__
0804a014 A __bss_start
0804a00c D __data_start
080484b0 t __do_global_ctors_aux
08048360 t __do_global_dtors_aux
0804a010 D __dso_handle
w__gmon_start__
080484aa T __i686.get_pc_thunk.bx
08049f0c d __init_array_end
08049f0c d __init_array_start
08048440 T __libc_csu_fini
08048450 T __libc_csu_init
U [elektron pochta bilan himoyalangan]@ GLIBC_2.0
0804a014 A _edata
0804a01c A _end
080484dc T _fini
080484f8 R _fp_hw
080482b8 T _init
08048330 T _start
0804a014 b yakunlandi
0804a00c Vt ma'lumotni boshlash
0804a018 b dtor_idx.7023
Avvalo 0804840c T
080483c0 t frame_dummy
080483e4 T asosiy
U [elektron pochta bilan himoyalangan]@ GLIBC_2.0
08048420 T soniya

Belgilangan jadvalni bajariladigan dasturga qo'shilishi, disk raskadrovka jarayonini engillashtirish uchun juda zarur. Aslida, dasturni ishga tushirish uchun aslida kerak emas. Turli xil kutubxonalardan foydalangan holda, ko'plab funktsiyalar ta'riflari va tashqi o'zgaruvchilarga ega bo'lgan haqiqiy dasturlarning bajariladigan fayllari uchun ramzlar jadvali juda keng bo'ladi. Chiqish faylining hajmini kamaytirish uchun uni yordamida o'chirib tashlash mumkin gcc -s opsiyasi bilan.

$ gcc -s -o main main.o first.o second.o
$ ./main
Birinchi funktsiya ...
Ikkinchi funktsiya ...
Asosiy funktsiya ...
$ nm asosiy
nm: main: belgilar yo'q

Shuni ta'kidlash kerakki, ulanish paytida bog'lovchi funktsiya chaqiruvi kontekstida hech qanday tekshiruv o'tkazmaydi, qaytish qiymatining turini yoki qabul qilingan parametrlarning turi va sonini kuzatmaydi (va bunday ma'lumotni olish uchun joy yo'q). Barcha qo'ng'iroqlarni tekshirish kompilyatsiya vaqtida amalga oshirilishi kerak. Ko'p faylli dasturlashda bu uchun til sarlavhasi fayl mexanizmidan foydalanish kerak C.

Kutubxonalar

Kutubxona - tilda C, bog'lanish bosqichida kutubxona yordamida dasturga ulanishi mumkin bo'lgan ob'ekt kodini o'z ichiga olgan fayl. Aslida, kutubxona - bu maxsus tarzda bog'langan ob'ekt fayllari to'plami.

Kutubxonalarning maqsadi dasturchiga oddiy va ishonchli kodni qayta ishlatish uchun standart mexanizm bilan ta'minlashdir.

Operatsion tizim va dasturiy ta'minot nuqtai nazaridan kutubxonalar statik va birgalikda (dinamik ).

Statik kutubxona kodi ikkinchisini bog'lash paytida bajariladigan faylga kiritilgan. Kutubxona faylga "qattiq simli" bo'lib chiqadi, kutubxona kodi qolgan fayl kodi bilan "birlashtiriladi". Statik kutubxonalardan foydalanadigan dastur mustaqil bo'lib qoladi va mos arxitektura va operatsion tizimga ega deyarli har qanday kompyuterda ishlaydi.

Umumiy kutubxona kodi dasturning talabiga binoan operatsion tizim tomonidan yuklanadi va dastur kodiga ulanadi. Dinamik kutubxona kodi dasturning bajariladigan fayliga kiritilmagan, faqat bajariladigan faylga kutubxonaga havola kiritilgan. Natijada, umumiy kutubxonalardan foydalanadigan dastur mustaqil bo'lishni to'xtatadi va faqatgina tegishli kutubxonalar o'rnatilgan tizimda muvaffaqiyatli ishlashi mumkin.

Umumiy kutubxona paradigmasi uchta muhim foyda keltiradi:

1. Bajariladigan fayl hajmi juda kichraytirilgan. Xuddi shu koddan foydalangan holda ko'plab ikkiliklarni o'z ichiga olgan tizimda har bir bajariladigan fayl uchun ushbu kodning nusxasini saqlashga hojat yo'q.

2. Bir nechta dasturlar tomonidan ishlatiladigan umumiy kutubxona kodi bir nusxada RAMda saqlanadi (aslida hammasi ham shunchalik oddiy emas ...), natijada tizimning mavjud operativ xotiraga bo'lgan ehtiyoji kamayadi.

3. Har bir bajariladigan faylni ular uchun umumiy kutubxona kodi o'zgargan taqdirda qayta tiklashga hojat yo'q. Dinamik kutubxona kodiga kiritilgan o'zgartirishlar va tuzatishlar undan foydalanadigan dasturlarning har birida avtomatik ravishda aks etadi.

Umumiy kutubxona paradigmasi bo'lmasa, oldindan tuzilgan (ikkilik) tarqatmalar bo'lmaydi Linux (ha, nima bo'lishidan qat'iy nazar). Har bir ikkilik standart kutubxonaning kodini o'z ichiga olgan tarqatish hajmini tasavvur qiling C (va boshqa barcha kutubxonalar). Tasavvur qiling, keng qo'llaniladigan kutubxonalardan birida muhim zaiflikni tuzatgandan so'ng tizimni yangilash uchun nima qilish kerak edi ...

Endi ozgina mashq qiling.

Tasvirlash uchun avvalgi misoldan olingan manba fayllar to'plamidan foydalanamiz. Biz birinchi () va second () funktsiyalarning kodini (amalga oshirilishini) uy quradigan kutubxonamizga joylashtiramiz.

Linuxda quyidagi kutubxona fayllarini nomlash sxemasi qabul qilingan (har doim ham kuzatilmasa ham) - kutubxona fayli nomi lib prefiksidan, so'ngra .a kengaytmasi kutubxona nomidan boshlanadi. arxiv ) - statik kutubxona uchun .so ( umumiy ob'ekt ) - umumiy (dinamik) uchun, kengaytirilgandan so'ng versiya raqamlari nuqta orqali ro'yxatlanadi (faqat dinamik kutubxonalar uchun). Sarlavha fayllari kutubxonasiga mos keladigan nom (yana odatda) kutubxona nomidan (prefiks va versiyasiz) va .h kengaytmasidan iborat. Masalan: libogg.a, libogg.so.0.7.0, ogg.h.

Birinchidan, statik kutubxona yaratamiz va undan foydalanamiz.

Birinchi () va ikkinchi () funktsiyalar bizning libhello kutubxonamiz tarkibini yaratadi. Kutubxona faylining nomi mos ravishda libhello.a bo'ladi. Keling, hello.h sarlavha faylini kutubxona bilan taqqoslaymiz.

/ * salom.h * /

bekor birinchi ( bekor );
bekor ikkinchi ( bekor );

Albatta, satrlar:

# "first.h" ni kiriting


# "second.h" ni kiriting

main.c, first.c va second.c fayllarida quyidagilarni almashtirish kerak:

# "salom.h" ni o'z ichiga oladi

Endi quyidagi buyruqlar ketma-ketligini kiriting:

$ gcc -Wall -c first.c
$ gcc -Wall -c second.c
$ ar crs libhello.a birinchi.o ikkinchi.o
$ file libhello.a
libhello.a: joriy arxiv

Yuqorida aytib o'tilganidek, kutubxona ob'ekt fayllari to'plamidir. Dastlabki ikkita buyruq bilan biz ushbu ob'ekt fayllarini yaratdik.

Keyinchalik, ob'ekt fayllarini to'plamga bog'lashingiz kerak. Buning uchun arxivlovchi ishlatiladi ar - yordamchi dastur bir nechta fayllarni bittaga "yopishtiradi", natijada arxivga har bir alohida faylni tiklash (ajratish) uchun zarur bo'lgan ma'lumotlar (shu jumladan egalik, kirish huquqi, vaqti) kiradi. Arxiv tarkibidagi har qanday "siqish" yoki saqlanadigan ma'lumotlarning boshqa transformatsiyasi amalga oshirilmaydi.

C arname opsiyasi - arxiv yarating, agar arname nomli arxiv mavjud bo'lmasa, u yaratiladi, aks holda fayllar mavjud arxivga qo'shiladi.

Variant - arxivni yangilash rejimini o'rnatadi, agar ko'rsatilgan nomdagi fayl arxivda allaqachon mavjud bo'lsa, u o'chiriladi va yangi fayl arxiv oxiriga qo'shiladi.

Variant - arxiv indeksini qo'shadi (yangilaydi). Bunday holda, arxiv indekslari jadval bo'lib, unda arxivlangan fayllarda aniqlangan har bir ramziy nom (funktsiya yoki ma'lumotlar blokining nomi) uchun mos keladigan ob'ekt fayli nomi bog'langan. Arxiv indekslari kutubxona bilan ishlashni tezlashtirish uchun zarurdir - kerakli ta'rifni topish uchun barcha arxiv fayllarining belgilar jadvallarini ko'rib chiqishning hojati yo'q, kerakli nomni o'z ichiga olgan faylga to'g'ridan-to'g'ri o'tishingiz mumkin. Siz allaqachon tanish bo'lgan yordamchi dastur yordamida arxiv indeksini ko'rishingiz mumkin nm undan foydalanish -s opsiyasi bilan (arxivning barcha ob'ekt fayllarining belgilar jadvallari ham ko'rsatiladi):

$ nm -s libhello.a
Arxiv ko'rsatkichi:
birinchi navbatda birinchi
sekundiga ikkinchi

birinchi.o:
Avval 00000000 T
U qo'yadi

ikkinchisi:
U qo'yadi
00000000 T sekund

Arxiv indeksini yaratish uchun maxsus yordamchi dastur mavjud ranlib... Libhello.a kutubxonasi shunday yaratilishi mumkin edi:

$ ar cr libhello.a birinchi.o ikkinchi.o
$ ranlib libhello.a

Biroq, kutubxona arxiv indeksisiz yaxshi ishlaydi.

Endi kutubxonamizdan foydalanamiz:

$ gcc -Wall -c main.c
$
$ ./main
Birinchi funktsiya ...
Ikkinchi funktsiya ...
Asosiy funktsiya ...

Ishlar ...

Xo'sh, endi sharhlar ... Ikkita yangi variant mavjud gcc:

-L nomi opsiyasi - bog'lovchiga uzatilgan, libname kutubxonasini bajariladigan faylga ulash zarurligini bildiradi. Ulanish uchun falon kutubxonada falon funktsiyalar (tashqi o'zgaruvchilar) aniqlanganligini bildiruvchi vositalar mavjud. Bizning misolimizda kutubxona statik bo'lib, barcha ramziy nomlar to'g'ridan-to'g'ri bajariladigan faylda joylashgan kodga murojaat qiladi. Variantlarga e'tibor bering -l kutubxona nomi lib prefiksisiz ism sifatida ko'rsatilgan.

Variant -L / path / to / directory / with / library - bog'lovchiga uzatildi, bog'langan kutubxonalarni o'z ichiga olgan katalogga yo'lni belgilaydi. Bizning holatlarimizda gap . , bog'lovchi avval kutubxonalarni joriy katalogdan, so'ngra tizimda belgilangan kataloglardan qidiradi.

Bu erda kichik bir eslatma qilish kerak. Haqiqat shundaki, bir qator variantlar uchun gcc buyruq satrida ularning paydo bo'lish tartibi muhim ahamiyatga ega. Buyruqning satrida keltirilgan kutubxonalarda fayl belgisi jadvalida ko'rsatilgan nomlarga mos keladigan kodni bog'lovchi shunday izlaydi. keyin ushbu faylning nomi. Bog'lovchi fayl nomidan oldin berilgan kutubxonalar tarkibini e'tiborsiz qoldiradi:

$ gcc -Wall -c main.c
$ gcc -o main -L. - salom main.o
main.o: "main" funktsiyasida:
main.c :(. text + 0xa): "birinchi" ga aniqlanmagan havola
main.c :(. text + 0xf): "ikkinchi" ga aniqlanmagan havola

$ gcc -o asosiy asosiy.o -L. - salom
$ ./main
Birinchi funktsiya ...
Ikkinchi funktsiya ...
Asosiy funktsiya ...

Xulq-atvorning bunday xususiyati gcc ishlab chiquvchilarning foydalanuvchini turli xil usullar bilan fayllarni kutubxonalar bilan birlashtirish qobiliyatini ta'minlash, kesishgan nomlardan foydalanish istagi tufayli ... Menimcha, iloji bo'lsa, bu bilan ovora bo'lmaslik yaxshiroqdir. Umuman olganda, bog'langan kutubxonalar ularga tegishli fayl nomidan keyin ro'yxatga olinishi kerak.

Mavjud muqobil usul tizimdagi kutubxonalarning joylashishini belgilash. Taqsimotga qarab LD_LIBRARY_PATH yoki LIBRARY_PATH muhit o'zgaruvchisi yo'g'on ichak bilan ajratilgan kataloglar ro'yxatini saqlashi mumkin, bunda bog'lovchi kutubxonalarni qidirishi kerak. Odatiy bo'lib, bu o'zgaruvchi umuman aniqlanmagan, ammo uning yaratilishiga hech narsa to'sqinlik qilmaydi:

$ echo $ LD_LIBRARY_PATH

/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../../i686-pc-linux-gnu/bin/ld: -lolo topolmayapman
collect2: ld bajarilishi qaytish kodi 1 bilan chiqdi
$ eksport LIBRARY_PATH \u003d.
$ gcc -o main main.o -allo
$ ./main
Birinchi funktsiya ...
Ikkinchi funktsiya ...
Asosiy funktsiya ...

O'zingizning kutubxonalaringizni tuzishda va disk raskadrovka paytida, shuningdek ba'zi bir nostandart (eskirgan, yangilangan, o'zgartirilgan - tarqatishga kiritilganidan farq qiluvchi) umumiy kutubxonani dasturga ulashingiz kerak bo'lsa, atrof-muhit o'zgaruvchilari bilan manipulyatsiya qilish foydalidir.

Endi dinamik kutubxona yaratamiz va undan foydalanamiz.

Asl fayllar to'plami o'zgarishsiz qoladi. Biz buyruqlarni kiritamiz, nima bo'lganini ko'rib chiqamiz, sharhlarni o'qiymiz:

$ gcc -Wall -fPIC -c first.c
$ gcc -Wall -fPIC -c second.c
$ gcc -shared -o libhello.so.2.4.0.5 -Wl, -soname, libhello.so.2 first.o second.o

Natijada siz nimaga erishdingiz?

$ file libhello.so.2.4.0.5
libhello.so.2.4.0.5: ELF 64-bitli LSB umumiy ob'ekti, x86-64, versiya 1 (SYSV), dinamik ravishda bog'langan, echilmagan

Libhello.so.2.4.0.5 fayli bizning umumiy kutubxonamiz. Uni qanday ishlatish haqida quyida gaplashamiz.

Endi sharhlar:

-FPIC opsiyasi - ob'ekt fayllarini yaratishda kompilyatorni yaratishni talab qiladi pozitsiyadan mustaqil kod (PIC - pozitsiya mustaqil kodi ), uning asosiy farqi manzillarni namoyish qilish usulidir. Ruxsat etilgan (statik) pozitsiyalarni ko'rsatish o'rniga, barcha manzillar berilgan ofsetlar asosida hisoblanadi global ofset jadvali (global ofset jadvali - GOT ). Pozitsiyadan mustaqil kod formati yuklanayotganda bajariladigan modullarni asosiy dasturning kodiga ulashga imkon beradi. Shunga ko'ra pozitsiyadan mustaqil kodning asosiy maqsadi dinamik (umumiy) kutubxonalarni yaratishdir.

-Shared variant - bildiradi gccnatija bajariladigan fayl emas, balki umumiy ob'ekt - dinamik kutubxona bo'lishi kerak.

Variant -Wl, -soname, libhello.so.2 - to'plamlar soname kutubxonalar. Soname haqida keyingi xatboshida batafsil gaplashamiz. Endi variant formatini muhokama qilamiz. Bir qarashda g'alati tuyulishi, vergul bilan qurilishi foydalanuvchining to'g'ridan-to'g'ri bog'lovchi bilan o'zaro aloqasi uchun mo'ljallangan. Kompilyatsiya paytida gcc bog'lovchini o'z xohishiga ko'ra avtomatik ravishda, avtomatik ravishda chaqiradi, gcc ishni muvaffaqiyatli yakunlash uchun zarur bo'lgan variantlardan o'tadi. Agar foydalanuvchi ulanish jarayoniga o'zi aralashishi kerak bo'lsa, u maxsus variantni ishlatishi mumkin gcc -Wl, -option, value1, value2 ...... Bog'lovchiga o'tish nimani anglatadi ( -Wl) variant - variant dalillar bilan qiymati1, qiymati2 va hokazo. Bizning holatlarimizda, variant bog'lovchiga o'tkazildi -soname argument bilan libhello.so.2.

Endi soname haqida. Kutubxonalarni yaratish va tarqatishda moslik va versiyalarni boshqarish muammosi mavjud. Tizim, xususan, dinamik kutubxona yuklagichi dasturni kompilyatsiya qilishda kutubxonaning qaysi versiyasidan foydalanilganligi va shunga muvofiq uning muvaffaqiyatli ishlashi uchun zarur bo'lganligi to'g'risida tasavvurga ega bo'lishi uchun maxsus identifikator taqdim etildi - soname , kutubxonaning o'zi va dasturning bajariladigan faylida joylashtirilgan. Soname identifikatori - bu lib, nuqta, kengaytma so, yana nuqta va kutubxona versiyasining bir yoki ikkita (nuqta bilan ajratilgan) raqamlari bilan qo'shilgan kutubxona nomini o'z ichiga olgan mag'lubiyat. Lib .so. x. y. Ya'ni soname kutubxona fayli nomiga versiya raqamining birinchi yoki ikkinchi raqamiga mos keladi. Amalga oshiriladigan kutubxonamiz nomi libhello.so.2.4.0.5 bo'lsin, keyin kutubxonaning soname libhello.so.2 bo'lishi mumkin. Kutubxona interfeysini o'zgartirganda uning sonini o'zgartirish kerak! Oldingi nashrlarga mos kelmaydigan har qanday kodni o'zgartirish yangi soname bilan birga bo'lishi kerak.

Hammasi qanday ishlaydi? Aytaylik, ba'zi bir dasturlarning muvaffaqiyatli bajarilishi uchun tizimda bitta mavjud, masalan, kutubxona fayli nomi libhello.so.2.4.0.5 va unda yozilgan libhello.so.2 kutubxonasining sonomi, salom deb nomlangan kutubxona kerak. Ilovani kompilyatsiya qilish bosqichida, variantga ko'ra, bog'lovchi - salom, tizimda libhello.so nomli faylni qidiradi. Haqiqiy tizimda libhello.so - bu libhello.so.2.4.0.5 ga ramziy havola. Kutubxona fayliga kirish huquqini olgan bog'lovchi unda yozilgan soname qiymatini o'qiydi va boshqa narsalar qatori dasturning bajariladigan fayliga joylashtiradi. Ilova ishga tushirilgach, dinamik kutubxona yuklagichi bajariladigan fayldan soname o'qilgan kutubxonani qo'shish haqida so'rov oladi va tizimda fayl nomi sonamega mos keladigan kutubxonani topishga harakat qiladi. Ya'ni, yuklovchi libhello.so.2 faylini topishga harakat qiladi. Agar tizim to'g'ri tuzilgan bo'lsa, unda libhello.so.2 libhello.so.2.4.0.5 fayliga ramziy havola bo'lishi kerak, yuklovchi kerakli kutubxonaga kiradi va keyin ikkilanmasdan (va boshqa hech narsani tekshirmasdan) uni dasturga ulaydi. Endi tasavvur qiling, biz shu tarzda tuzilgan dasturni faqat libhello.so.1 soname bilan kutubxonaning avvalgi versiyasi joylashgan boshqa tizimga ko'chiramiz. Dasturni ishga tushirishga urinish xatoga olib keladi, chunki bu tizimda libhello.so.2 nomli fayl yo'q.

Shunday qilib, kompilyatsiya bosqichida bog'lovchiga lib name .so nomli kutubxona fayli (yoki kutubxona fayliga ramziy havola) taqdim etilishi kerak .so, ish vaqtida yuklagichga lib name .so nomli fayl (yoki ramziy havola) kerak. x. y. Lib nomi .so ismining nomi nimani anglatadi. x. y ishlatilgan kutubxonaning soname qatoriga mos kelishi kerak.

Ikkilik tarqatishda, qoida tariqasida, libhello.so.2.4.0.5 kutubxona fayli va unga bog'langan libhello.so.2 libhello paketiga joylashtiriladi va faqatgina kompilyatsiya qilish uchun zarur bo'lgan libhello.so havolasi, hello.h kutubxonasining sarlavhali fayl bilan birga bo'ladi. libhello-devel paketiga qadoqlangan (devel to'plami libhello.a kutubxonasining statik versiyasining faylini o'z ichiga oladi, statik kutubxonadan faqat kompilyatsiya bosqichida foydalanish mumkin). Paketni ochishda barcha sanab o'tilgan fayllar va havolalar (hello.h dan tashqari) bitta katalogda bo'ladi.

Keling, berilgan soname satri bizning kutubxona faylimizda haqiqatan ham yozilganligiga ishonch hosil qilaylik. Keling, mega yordam dasturidan foydalanamiz objdump variant bilan -p :

$ objdump -p libhello.so.2.4.0.5 | grep SONAME
SONAME libhello.so.2


Qulaylik objdump - ob'ekt yoki bajariladigan faylning ichki tarkibi (va qurilmasi) haqida keng qamrovli ma'lumot olishga imkon beruvchi kuchli vosita. Utility man sahifasida aytilgan objdump birinchi navbatda, har qanday dastur dasturlarini yozishni emas, balki disk raskadrovka va kompilyatsiya vositalarini yaratadigan dasturchilar uchun foydali bo'ladi :) Xususan, variant bilan -d bu qismlarga ajratuvchi. Biz variantni ishlatdik -p - ob'ekt fayli haqida turli xil meta-ma'lumotlarni namoyish etish.

Kutubxona yaratishning ushbu misolida biz alohida kompilyatsiya tamoyillariga tinimsiz amal qildik. Albatta, kutubxonani bitta qo'ng'iroq bilan shunday tuzish mumkin edi gcc:

$ gcc -shared -Wall -fPIC -o libhello.so.2.4.0.5 -Wl, -soname, libhello.so.2 first.c second.c

Endi olingan kutubxonadan foydalanishga harakat qilaylik:

$ gcc -Wall -c main.c
$
/ usr / bin / ld: -lolo topolmayapman
collect2: ld 1 chiqish holatini qaytardi

Bog'lovchi qasam ichadi. Ramziy aloqalar to'g'risida yuqorida aytilganlarni eslang. Libhello.so saytini yarating va qaytadan urining:

$ ln -s libhello.so.2.4.0.5 libhello.so
$ gcc -o asosiy asosiy.o -L. - salom -Wl, -path,.

Endi hamma xursand. Biz yaratilgan ikkilikni ishga tushiramiz:

Xato ... Yuklovchi la'natlamoqda, libhello.so.2 kutubxonasini topa olmadi. Libhello.so.2-ga havola haqiqatan ham bajariladigan faylda ro'yxatdan o'tganligiga ishonch hosil qilaylik:

$ objdump -p main | grep KERAK
2. KERAKLI libhello.so.2
6. KERAKLI libc.so.6

$ ln -s libhello.so.2.4.0.5 libhello.so.2
$ ./main
Birinchi funktsiya ...
Ikkinchi funktsiya ...
Asosiy funktsiya ...

Ishladi ... Endi yangi variantlarga sharhlar gcc.

Variant -Wl, -rpath,. - allaqachon tanish bo'lgan qurilish, variantni bog'lovchiga o'tkazing - yo'l argument bilan . ... Yordamida - yo'l dasturning bajariladigan faylida siz qo'shimcha yo'llarni yozishingiz mumkin, ular bo'ylab umumiy kutubxona yuklagichi kutubxona fayllarini qidiradi. Bizning holatda, yo'l ro'yxatdan o'tgan . - kutubxona fayllarini qidirish joriy katalogdan boshlanadi.

$ objdump -p main | grep RPATH
RPATH.

Ushbu parametr tufayli dasturni ishga tushirishda atrof-muhit o'zgaruvchilarini o'zgartirishga hojat yo'q. Agar dasturni boshqa katalogga ko'chirsangiz va uni ishga tushirishga harakat qilsangiz, kutubxona fayli topilmasligi va yuklovchi xato xabari paydo bo'lishi aniq:

$ mv asosiy ..
$ ../main
Birinchi funktsiya ...
Ikkinchi funktsiya ...
Asosiy funktsiya ...

Yordamchi dastur yordamida dastur qaysi umumiy kutubxonalarga kerakligini bilib olishingiz mumkin ldd:

$ ldd asosiy
linux-vdso.so.1 \u003d\u003e (0x00007fffaddff000)
libhello.so.2 \u003d\u003e ./libhello.so.2 (0x00007f9689001000)
libc.so.6 \u003d\u003e /lib/libc.so.6 (0x00007f9688c62000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9689205000)

Chiqish ldd har bir talab qilinadigan kutubxona uchun uning sozlamalariga muvofiq aniqlangan uning nomi va kutubxona fayliga to'liq yo'l ko'rsatilgan.

Endi tizim kutubxona fayllarini qaerga joylashtirishi kerakligi, yuklagich ularni qaerdan topishga urinishi va bu jarayonni boshqarish haqida gaplashadigan vaqt keldi.

Shartnomalarga muvofiq FHS (Fayl tizimi iyerarxiyasi standarti) tizimda kutubxona fayllarini saqlash uchun ikkita (kamida) katalog bo'lishi kerak:

/ lib - bu erda / bin va / sbin dasturlari ishlashi uchun zarur bo'lgan asosiy tarqatish kutubxonalari to'plangan;

/ usr / lib - / usr / bin va / usr / sbin dasturlari uchun zarur bo'lgan kutubxonalar bu erda saqlanadi;

Kutubxonalarga mos keladigan sarlavha fayllari / usr / include katalogida joylashgan bo'lishi kerak.

Standart yuklovchi ushbu kataloglardan kutubxona fayllarini qidiradi.

Yuqorida sanab o'tilganlardan tashqari, tizimda / usr / local / lib katalogi bo'lishi kerak - foydalanuvchi tomonidan paketlarni boshqarish tizimini chetlab o'tib mustaqil ravishda tarqatiladigan kutubxonalar bo'lishi kerak (tarqatish to'plamiga kiritilmagan). Masalan, ushbu katalogda sukut bo'yicha manbalardan yig'ilgan kutubxonalar mavjud bo'ladi (manbalardan o'rnatilgan dasturlar / usr / local / bin va / usr / local / sbin-ga joylashtiriladi, albatta biz ikkitomonlama tarqatish haqida gaplashamiz). Bunday holda, kutubxona sarlavhalari / usr / local / include ichiga joylashtiriladi.

Bir qator tarqatishda (ichida Ubuntu) loader / usr / local / lib katalogini ko'rib chiqish uchun tuzilmagan, shuning uchun agar foydalanuvchi kutubxonani manbadan o'rnatsa, tizim uni ko'rmaydi. Bu tarqatish to'plamining mualliflari tomonidan foydalanuvchiga faqat paketlarni boshqarish tizimi orqali dasturiy ta'minotni o'rnatishni o'rgatish uchun maxsus amalga oshiriladi. Bunday holatda qanday harakat qilish kerakligi quyida tavsiflanadi.

Aslida kutubxona fayllarini qidirish jarayonini soddalashtirish va tezlashtirish uchun yuklovchi har kirilganda yuqoridagi kataloglarga qaramaydi, lekin /etc/ld.so.cache faylida (kutubxona keshi) saqlangan ma'lumotlar bazasiga tayanadi. Unda berilgan sonamega mos keladigan kutubxona fayli tizimda qaerda joylashganligi to'g'risida ma'lumotlar mavjud. Muayyan dastur uchun zarur bo'lgan kutubxonalar ro'yxatini (bajariladigan dastur faylida ko'rsatilgan soname kutubxonalari ro'yxati) olgan yuklovchi /etc/ld.so.cache-dan foydalanib, har bir kerakli kutubxonaning faylga yo'lini aniqlaydi va xotiraga yuklaydi. Bundan tashqari, yuklovchi LD_LIBRARY_PATH, LIBRARY_PATH tizim o'zgaruvchilarida va bajariladigan faylning RPATH maydonida ko'rsatilgan kataloglarni ko'rishi mumkin (yuqoriga qarang).

Kutubxona keshini boshqarish va yangilab turish uchun yordam dasturidan foydalaniladi ldconfig... Agar siz qochsangiz ldconfig hech qanday imkoniyatlarsiz dastur buyruq satrida ko'rsatilgan kataloglarni, ishonchli kataloglarni / lib va \u200b\u200b/ usr / lib /etet/ld.so.conf faylida ko'rsatilgan kataloglarni skanerdan o'tkazadi. Belgilangan kataloglardagi har bir kutubxona fayli uchun soname o'qiladi, soname asosida simvol bog'lanadi, /etc/ld.so.cache-dagi ma'lumotlar yangilanadi.

Yuqoridagilarga ishonch hosil qilaylik:

$ ls
salom.h libhello.so libhello.so.2.4.0.5 main.c
$
$ sudo ldconfig / full / path / to / kataogu / c / example
$ ls
salom.h libhello.so libhello.so.2 libhello.so.2.4.0.5 main main.c
$ ./main
Birinchi funktsiya ...
Ikkinchi funktsiya ...
Asosiy funktsiya ...

Birinchi qo'ng'iroq ldconfig biz kutubxonamizni keshga qo'shdik, uni ikkinchi qo'ng'iroq bilan chiqarib tashladik. Asosiy kompilyatsiya qilishda parametr o'tkazib yuborilganligini unutmang -Wl, -path,., natijada yuklovchi kerakli kutubxonalarni faqat keshdan qidirdi.

Endi kutubxonani manbadan o'rnatgandan so'ng tizim ko'rmasa nima qilish kerakligi aniq bo'lishi kerak. Avvalo, to'liq yo'lni /etc/ld.so.conf faylida kutubxona fayllari bilan (sukut bo'yicha / usr / local / lib) katalogga qo'shishingiz kerak. /Etc/ld.so.conf formati - faylda kataloglar ro'yxati joylashgan bo'lib, ular ikki nuqta, bo'sh joy, yorliq yoki yangi qator bilan ajratilgan bo'lib, unda kutubxonalarni qidirish kerak. Keyin qo'ng'iroq qiling ldconfig hech qanday variantsiz, lekin superuser huquqlari bilan. Hamma narsa ishlashi kerak.

Xo'sh, oxirida kutubxonalarning statik va dinamik versiyalari qanday yashashi haqida to'xtalamiz. Haqiqiy savol nima? Yuqorida kutubxona fayllarining qabul qilingan nomlari va joylashuvi muhokama qilinganda kutubxonaning statik va dinamik versiyalarining fayllari bir xil katalogda saqlanishi aytilgan edi. Qanaqasiga gcc kutubxonaning qaysi turidan foydalanmoqchi ekanligimizni bilib olamiz? Sukut bo'yicha dinamik kutubxonaga afzallik beriladi. Agar bog'lovchi dinamik kutubxona faylini topsa, uni dasturning bajariladigan fayliga bog'lashdan tortinmaydi:

$ ls
salom.h libhello.a libhello.so libhello.so.2 libhello.so.2.4.0.5 main.c
$ gcc -Wall -c main.c
$ gcc -o asosiy asosiy.o -L. - salom -Wl, -path,.
$ ldd asosiy
linux-vdso.so.1 \u003d\u003e (0x00007fffe1bb0000)
libhello.so.2 \u003d\u003e ./libhello.so.2 (0x00007fd50370b000)
libc.so.6 \u003d\u003e /lib/libc.so.6 (0x00007fd50336c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd50390f000)
$ du -h main
12K asosiy

Bajariladigan dastur hajmiga e'tibor bering. Bu mumkin bo'lgan eng kichik narsa. Amaldagi barcha kutubxonalar dinamik ravishda bog'langan.

Mavjud gcc -statik variant - bog'lovchiga dastur uchun zarur bo'lgan barcha kutubxonalarning faqat statik versiyalaridan foydalanishni buyurish:

$ gcc -static -o main main.o -L. - salom
$ file main
asosiy: ELF 64-bitli LSB bajariladigan, x86-64, versiya 1 (GNU / Linux), statik ravishda bog'langan, GNU / Linux 2.6.15 uchun, echilmagan
$ ldd asosiy
dinamik bajariladigan dastur emas
$ du -h main
728K asosiy

Bajariladigan faylning hajmi oldingi misolga qaraganda 60 baravar katta - bu faylga standart til kutubxonalari kiritilgan C... Endi bizning dasturimiz katalogdan katalogga va hattoki boshqa mashinalarga xavfsiz tarzda uzatilishi mumkin, salom kutubxona kodi fayl ichida, dastur to'liq avtonom.

Agar ishlatilgan kutubxonalarning faqat bir qismini statik ravishda bog'lash kerak bo'lsa-chi? Mumkin bo'lgan variant echimlar - kutubxonaning statik versiyasi nomini umumiy nomidan farq qiladi va dasturni tuzishda bu safar qaysi versiyadan foydalanmoqchi ekanligimizni ko'rsating:

$ mv libhello.a libhello_s.a
$ gcc -o asosiy asosiy.o -L. -salam_s
$ ldd asosiy
linux-vdso.so.1 \u003d\u003e (0x00007fff021f5000)
libc.so.6 \u003d\u003e /lib/libc.so.6 (0x00007fd0d0803000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd0d0ba4000)
$ du -h main
12K asosiy

Libello kutubxonasining kod hajmi ahamiyatsiz bo'lgani uchun,

$ du -h libhello_s.a
4.0K libhello.a

natijada bajariladigan fayl hajmi deyarli dinamik bog'lanish yordamida yaratilgan fayl hajmidan farq qilmaydi.

Xo'sh, barchasi shu. Shu nuqtada o'qishni tugatgan barchaga katta rahmat.

GCC ishlash ko'rsatkichlari bo'yicha boshqa kompilyatorlardan orqada qolmoqda degan fikr keng tarqalgan. Ushbu maqolada biz qabul qilinadigan ishlashga erishish uchun qaysi asosiy GCC kompilyatori optimallashtirishlarini qo'llash kerakligini tushunishga harakat qilamiz.

GCC-da standart parametrlar qanday?

(1) Odatiy bo'lib, GCC "-O0" optimallashtirish darajasidan foydalanadi. Bu aniq ishlashi uchun maqbul emas va yakuniy mahsulotni tuzish uchun tavsiya etilmaydi.
GCC "-march \u003d native" opsiyasi o'tguncha kompilyatsiya qilinadigan arxitekturani tan olmaydi. Odatiy bo'lib, GCC o'zining konfiguratsiyasi paytida ko'rsatilgan parametrdan foydalanadi. GCC konfiguratsiyasini bilish uchun quyidagilarni bajaring:

Bu shuni anglatadiki, GCC sizning tanlovingizga "-march \u003d corei7" qo'shadi (agar boshqa me'morchilik ko'rsatilmagan bo'lsa).
X86 uchun GCC kompilyatorlarining aksariyati (64 bitli Linux uchun asos) berilgan parametrlarga quyidagilarni qo'shadi: "-mtune \u003d generic -march \u003d x86-64", chunki konfiguratsiyada me'morchilik parametrlari ko'rsatilmagan. Siz har doim GCC-ni ishga tushirishda o'tgan barcha parametrlarni va uning ichki parametrlarini quyidagi buyruq yordamida bilib olishingiz mumkin:

Natijada, tez-tez ishlatiladigan:

Amaldagi me'morchilik ishlash uchun muhimdir. Faqatgina kutubxona funktsiyalarining chaqiruvi deyarli barcha boshlang'ich vaqtlarini talab qiladigan dasturlarni hisobga olish mumkin. GLIBC ishlash vaqtida berilgan me'morchilik uchun maqbul funktsiyani tanlashi mumkin. Shuni ta'kidlash kerakki, statik ravishda bog'langan holda, ba'zi GLIBC funktsiyalari turli xil arxitektura uchun versiyalanmagan. Ya'ni, GLIBC funktsiyalarining tezligi muhim bo'lsa, dinamik yig'ilish yaxshiroqdir..
(2) Odatiy bo'lib, 32 bitli rejimda x86 uchun ko'pgina GCC kompilyatorlari x87 suzuvchi nuqta modelidan foydalanadi, chunki ular "-mfpmath \u003d sse" holda tuzilgan. Faqat GCC konfiguratsiyasi "--with-mfpmath \u003d sse" ni o'z ichiga olgan bo'lsa:

kompilyator SSE modelini sukut bo'yicha ishlatadi .. Boshqa barcha holatlarda 32 bitli rejimda "-mfpmath \u003d sse" parametrini qo'shish yaxshiroqdir.
Shunday qilib, tez-tez ishlatiladi:

"-Mfpmath \u003d sse" parametrini qo'shish 32 bitli rejimda muhimdir! Konfiguratsiyasida "--with-mfpmath \u003d sse" bo'lgan kompilyator istisno.

32 bitmi yoki 64 bitmi?

32-bitli rejim odatda foydalaniladigan xotira hajmini kamaytirish uchun ishlatiladi va natijada u bilan ishlashni tezlashtiradi (ko'proq ma'lumotlar keshga joylashtiriladi).
64 bitli rejimda (32 bitli rejim bilan taqqoslaganda) mavjud umumiy registrlar soni 6 dan 14 gacha, XMM registrlar 8 dan 16 gacha ko'payadi. Shuningdek, barcha 64 bitli arxitektura SSE2 kengaytmasini qo'llab-quvvatlaydi, shuning uchun 64 bitli rejimda siz "-mfpmath" parametrini qo'shishingiz shart emas \u003d sse ”.
Vazifalarni hisoblash uchun 64 bitli, mobil ilovalar uchun esa 32 bitli rejimdan foydalanish tavsiya etiladi.

Qanday qilib eng yaxshi ko'rsatkichni qo'lga kiritasiz?

Maksimal ishlash uchun maxsus variantlar to'plami mavjud emas, ammo GCC-da sinash uchun ko'plab imkoniyatlar mavjud. Quyida "-O2" opsiyasiga nisbatan Intel Atom va 2-avlod Intel Core i7 protsessorlari uchun tavsiya etilgan variantlar va o'sish prognozlari keltirilgan jadval keltirilgan. Bashoratlar GCC 4.7 versiyasi bilan tuzilgan muayyan muammolar to'plamining natijalarining geometrik o'rtacha qiymatiga asoslanadi. Shuningdek, kompilyatorning konfiguratsiyasi x86-64 generic uchun qilingan deb taxmin qilinadi.
Ish samaradorligini oshirish prognozi mobil ilovalar "-O2" ga nisbatan (faqat 32-bitli rejimda, chunki u mobil segment uchun asosiy hisoblanadi):

"-O2" ga nisbatan hisoblash topshiriqlari bo'yicha ishlash ko'rsatkichlarining prognozi (64 bitli rejimda):
-m64 -Fast -flto ~17%
-m64 -Ofast -flto -march \u003d mahalliy ~21%
-m64 -Ofast -flto -march \u003d native -funroll-looplar ~22%

"-O2 -mfpmath \u003d sse" parametrlari bilan hisoblash vazifalari uchun 64 bitli rejimning 32 bitdan ustunligi taxminan 5% ni tashkil qiladi.
Maqoladagi barcha ma'lumotlar ma'lum bir mezon ko'rsatkichlari natijalariga asoslangan prognozdir.
Quyida maqolada ishlatiladigan variantlarning tavsifi berilgan. To'liq tavsifi (ingliz tilida): http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Optimize-Options.html "
  • "-O3-" tezkor-matematikaga o'xshash "-Ofast" yuqori darajadagi optimallashtirish va arifmetik hisob-kitoblar uchun yanada tajovuzkor optimallashtirish imkonini beradi (masalan, haqiqiy qayta assotsiatsiya)
  • "-flto" o'zaro faoliyat modullarni optimallashtirish
  • "-m32" 32 bitli rejim
  • "-mfpmath \u003d sse" XMM registrlarini haqiqiy arifmetikada ishlatishga imkon beradi (x87 rejimidagi haqiqiy to'plam o'rniga)
  • "-funroll-loops" ro'yxatdan o'tishni o'chirishga imkon beradi

Transport logistikasi (transportning turli turlarini tahlil qilish: afzalliklari, kamchiliklari)

Transport - bu odamlar va tovarlarni tashiydigan moddiy ishlab chiqarishning bir bo'lagi. ijtimoiy ishlab chiqarish tarkibida transport moddiy xizmatlar ishlab chiqarishni nazarda tutadi.

Asosiy xom ashyo manbasidan yakuniy iste'molga qadar materiallar oqimining harakatlanish yo'lidagi logistika operatsiyalarining muhim qismi har xil usullardan foydalangan holda amalga oshiriladi. transport vositasi... Ushbu operatsiyalar bo'yicha xarajatlar umumiy logistika xarajatlarining 50% gacha.

Maqsadga ko'ra transportning ikkita asosiy guruhi ajratiladi: jamoat transporti - bu xalq xo'jaligining barcha tarmoqlari va aholining yuk va yo'lovchilar tashish ehtiyojlarini qondiradigan tarmoq. Jamoat transporti muomalaga va aholiga xizmat qiladi. Uni ko'pincha magistral deb atashadi (avtomagistral ba'zi tizimlarda, bu holda aloqa tizimida asosiy, asosiy yo'nalish hisoblanadi). Jamoat transporti tushunchasi temir yo'l transporti, suv transporti (dengiz va daryo), avtomobil, havo transporti va quvur transporti).

Jamoat bo'lmagan transport vositalari - sanoat ichidagi transport vositalari, shuningdek, transportga tegishli bo'lmagan tashkilotlarga tegishli barcha turdagi transport vositalari.

Tovarlar harakatini jamoat bo'lmagan transport vositalarida tashkil etish ishlab chiqarish logistikasining predmeti hisoblanadi. Tarqatish kanallarini tanlash muammosi tarqatish logistikasi sohasida hal qilinadi.

Shunday qilib, transportning quyidagi asosiy turlari mavjud:

temir yo'l

ichki suv yo'li daryosi

mashina

havo

quvur liniyasi

Transport turlarining har biri logistika menejmenti jihatidan o'ziga xos xususiyatlarga ega, uning logistika tizimida foydalanish imkoniyatlarini belgilaydigan afzalliklari va kamchiliklari. Turli xil transport turlari transport majmuasini tashkil etadi. Rossiyaning transport kompleksi uning hududida ro'yxatdan o'tgan yuridik va jismoniy shaxslar - transportning barcha turlarida transport-ekspeditorlik faoliyatini amalga oshiruvchi, temir yo'llarni, avtomobil yo'llari va ulardagi inshootlarni, quvurlarni, ishlarni loyihalash, qurish, ta'mirlash va texnik xizmat ko'rsatishni amalga oshiradigan tadbirkorlar tomonidan shakllantiriladi. suzib yuriladigan gidrotexnik inshootlarga texnik xizmat ko'rsatish, suv va havo yo'llari bilan aloqa ilmiy tadqiqotlar transport tizimining bir qismi bo'lgan xodimlarni, transport vositalarini ishlab chiqaradigan korxonalarni, shuningdek transport jarayoni bilan bog'liq boshqa ishlarni bajaradigan tashkilotlarni tayyorlash. Rossiya TK 160 ming km dan ortiq magistral temir yo'l va kirish yo'llari, 750 ming km qattiq yo'llar, 1,0 mln km dengiz tashish liniyalari, 101 ming km ichki suv yo'llari, 800 ming km aviakompaniyalardir. Faqatgina ushbu kommunikatsiyalar orqali jamoat transporti orqali kuniga taxminan 4,7 million tonna yuk tashiladi (2000 yil holatiga ko'ra), TKda 4 milliondan ortiq kishi ishlaydi va transportning mamlakat yalpi ichki mahsulotidagi ulushi qariyb 9 foizni tashkil qiladi. Shunday qilib, transport mamlakatimiz infratuzilmasi va butun ijtimoiy va ishlab chiqarish salohiyatining ajralmas qismidir.

Jadval 1 (4, 295) Har xil transport turlarining qiyosiy logistik tavsiflari berilgan.

Jadval 1 Transport turlarining xususiyatlari

Transport turi

Afzalliklari

kamchiliklar

temir yo'l

Yuqori tashish va tashish hajmi. Iqlim sharoitidan, yil va kun vaqtidan mustaqillik.

Yuk tashishning yuqori muntazamligi. Nisbatan past stavkalar; tranzit jo'natmalar uchun sezilarli chegirmalar. Tovarlarni uzoq masofalarga etkazib berishning yuqori tezligi.

Cheklangan tashuvchilar soni. Ishlab chiqarish texnik bazasiga katta kapital qo'yilmalar. Yuqori material sarfi va transportning energiya sarfi. Savdolarning oxirgi nuqtalariga (iste'molga) past darajada erishish.

Yukning xavfsizligi etarli emas.

Tarkiblararo tashish imkoniyati. Uzoq masofalarga transportning arzonligi. Yuqori tashish va tashish hajmi. Transportning past kapital intensivligi.

Cheklangan transport.

Etkazib berish tezligining pastligi (tranzitning uzoq muddati).

Geografik, navigatsion va ob-havo sharoitlariga bog'liqlik.

Murakkab port infratuzilmasini yaratish zarurati.

Ichki suv (daryo)

Chuqur daryolar va suv havzalarida yuqori tashish qobiliyati.

Transportning arzonligi. Kam kapital intensivligi.

Cheklangan transport. Yuklarni etkazib berishning past tezligi.

Daryo va suv omborlarining notekis chuqurliklariga, navigatsiya sharoitlariga bog'liqlik. Mavsumiylik. Yuklarni tashish ishonchliligi va xavfsizligi etarli emas.

mashina

Mavjudligi yuqori.

Uyma-uy yuklarni etkazib berish imkoniyati

Yuqori manevrlik, moslashuvchanlik, dinamizm. Yetkazib berishning yuqori tezligi. Turli marshrutlardan va etkazib berish sxemalaridan foydalanish qobiliyati.

Yuklarning yuqori xavfsizligi. Yuklarni kichik partiyalarda yuborish qobiliyati.

Yomon ishlash. Ob-havo va yo'l sharoitlariga bog'liqlik. uzoq masofalarga transportning nisbatan yuqori narxi.

Ekologik poklik etarli emas.

Havo

Yuklarni etkazib berishning eng yuqori tezligi. Yuqori ishonchlilik.

Yuklarning yuqori xavfsizligi.

Eng qisqa transport yo'nalishlari.

Yuk tashish narxi yuqori, boshqa transport turlari orasida eng yuqori tariflar. Transportning yuqori kapital intensivligi, moddiy va energiya sarfi. Ob-havo sharoitlariga bog'liqlik. Geografik imkoniyatlar etarli emas.

quvur liniyasi

Arzon narx. Yuqori ishlash (ishlash). Yuklarning yuqori xavfsizligi. Kam kapital intensivligi.

Cheklangan yuk turlari (gaz, neft mahsulotlari, xom ashyo emulsiyalari). Tashilayotgan tovarlarning kichik hajmlari etarli emasligi.

Shunday qilib, birinchi navbatda, logistika menejeri o'z transport parkini yaratish yoki yollangan transport vositalaridan (jamoat yoki xususiy) foydalanish to'g'risida qaror qabul qilishi kerak. Muqobil variantni tanlashda ular odatda ma'lum bir mezon tizimidan kelib chiqadi, ular quyidagilarni o'z ichiga oladi: O'zingizning transport vositalar parkingizni yaratish va ulardan foydalanish xarajatlari. Transport, ekspeditorlik kompaniyalari va boshqa logistika vositachilarining transport xizmatlari uchun to'lov narxi transportda tezligi

Tashish sifati (etkazib berish ishonchliligi, yuk xavfsizligi va boshqalar)

Ko'pgina hollarda ishlab chiqaruvchi firmalar ixtisoslashgan transport firmalarining xizmatlaridan foydalanadilar.