InggrisPerancisSpanyol

Ad


favorit OnWorks

kontra - Online di Cloud

Jalankan kontra di penyedia hosting gratis OnWorks melalui Ubuntu Online, Fedora Online, emulator online Windows, atau emulator online MAC OS

Ini adalah kekurangan perintah yang dapat dijalankan di penyedia hosting gratis OnWorks menggunakan salah satu dari beberapa workstation online gratis kami seperti Ubuntu Online, Fedora Online, emulator online Windows atau emulator online MAC OS

PROGRAM:

NAMA


Kontra - Sistem Konstruksi Perangkat Lunak

DESKRIPSI


Panduan dan referensi untuk versi 2.2.0

Hak Cipta (c) 1996-2000 Free Software Foundation, Inc.

Program ini adalah perangkat lunak gratis; Anda dapat mendistribusikan ulang dan/atau memodifikasinya di bawah ketentuan
Lisensi Publik Umum GNU sebagaimana diterbitkan oleh Free Software Foundation; salah satu
versi 2 dari Lisensi, atau (sesuai pilihan Anda) versi yang lebih baru.

Program ini disebarluaskan dengan harapan dapat bermanfaat, namun TANPA JAMINAN APAPUN;
bahkan tanpa jaminan tersirat tentang KELAYAKAN DIPERDAGANGKAN atau KESESUAIAN UNTUK TUJUAN TERTENTU.
Lihat Lisensi Publik Umum GNU untuk lebih jelasnya.

Anda seharusnya telah menerima salinan GNU General Public License bersama dengan program ini;
lihat file MENYALIN. Jika tidak, tulis ke Free Software Foundation, Inc., 59 Temple
Tempat - Suite 330, Boston, MA 02111-1307, AS.

Pengantar


Kekurangan adalah sistem untuk membangun, terutama, perangkat lunak, tetapi sangat berbeda dari
sistem konstruksi perangkat lunak sebelumnya. Kontra dirancang dari bawah ke atas untuk menangani
mudah dengan pembangunan perangkat lunak yang tersebar di beberapa direktori sumber. Kontra
memudahkan pembuatan skrip build yang sederhana, mudah dipahami, dan dapat dipelihara.
Kontra memastikan bahwa perangkat lunak yang kompleks dapat direproduksi dengan mudah dan akurat.

Kontra menggunakan sejumlah teknik untuk mencapai semua ini. Skrip konstruksi hanya
Skrip Perl, membuatnya mudah dipahami dan sangat fleksibel. Lingkup global
variabel diganti dengan mekanisme impor/ekspor untuk berbagi informasi antara
skrip, secara signifikan meningkatkan keterbacaan dan pemeliharaan setiap skrip.
Konstruksi lingkungan diperkenalkan: ini adalah objek Perl yang menangkap
informasi yang diperlukan untuk mengontrol proses pembuatan. Beberapa lingkungan digunakan
ketika semantik yang berbeda diperlukan untuk menghasilkan produk di pohon build. Kontra
mengimplementasikan analisis ketergantungan otomatis dan menggunakannya untuk mengurutkan keseluruhan secara global
membangun. Varian build mudah dibuat dari satu source tree. Bangunan cerdas
subsetting dimungkinkan, saat mengerjakan perubahan yang dilokalkan. Override dapat diatur ke
dengan mudah menimpa instruksi pembuatan tanpa memodifikasi skrip apa pun. Kriptografi MD5
tanda tangan dikaitkan dengan file turunan, dan digunakan untuk menentukan secara akurat apakah
file yang diberikan perlu dibangun kembali.

Sambil menawarkan semua hal di atas, dan banyak lagi, Kontra tetap sederhana dan mudah digunakan. Ini akan,
mudah-mudahan, menjadi jelas saat Anda membaca sisa dokumen ini.

Mengapa Kontra? Mengapa tidak Membuat?


Kontra adalah membuat penggantian. Dalam paragraf berikut, kita melihat beberapa dari
karakteristik yang tidak diinginkan dari make--dan lingkungan build yang khas berdasarkan make--itu
memotivasi pengembangan Kontra.

Membangun kompleksitas

Sistem berbasis make tradisional dengan ukuran berapa pun cenderung menjadi sangat kompleks. Buatan asli
utilitas dan turunannya telah berkontribusi pada kecenderungan ini dalam beberapa cara. Buat adalah
tidak pandai menangani sistem yang tersebar di banyak direktori. Berbagai pekerjaan-
sekitar digunakan untuk mengatasi kesulitan ini; pilihan yang biasa adalah membuat untuk dipanggil
sendiri secara rekursif untuk setiap sub-direktori build. Ini mengarah ke kode yang rumit, di
yang seringkali tidak jelas bagaimana suatu variabel diatur, atau apa pengaruh pengaturan suatu variabel
akan ada di build secara keseluruhan. Bahasa skrip make telah diperpanjang secara bertahap
untuk memberikan lebih banyak kemungkinan, tetapi ini sebagian besar telah berfungsi untuk mengacaukan
bahasa yang berlebihan. Seringkali, pembangunan dilakukan dalam beberapa lintasan untuk memberikan
produk yang sesuai dari satu direktori ke direktori lain. Ini mewakili lebih lanjut
peningkatan kompleksitas bangunan.

Membangun reproduksibilitas

Kutukan dari semua merek selalu menjadi penanganan dependensi yang benar. Paling sering, dan
upaya dilakukan untuk melakukan pekerjaan ketergantungan yang wajar dalam satu direktori, tetapi tidak ada
upaya serius dilakukan untuk melakukan pekerjaan antar direktori. Bahkan ketika ketergantungan adalah
bekerja dengan benar, mengandalkan perbandingan cap waktu sederhana untuk menentukan apakah
sebuah file kedaluwarsa sehubungan dengan tanggungannya, secara umum, tidak memadai untuk
menentukan kapan file harus diturunkan. Jika perpustakaan eksternal, misalnya, adalah
dibangun kembali dan kemudian ``snapped'' ke tempatnya, stempel waktu pada file yang baru dibuat mungkin
sebaiknya lebih awal dari bangunan lokal terakhir, karena dibangun sebelum terlihat.

Varian membangun

Make hanya menyediakan fasilitas terbatas untuk menangani build varian. Dengan proliferasi
platform perangkat keras dan kebutuhan akan kode yang dapat di-debug vs. dioptimalkan, kemampuan untuk
mudah membuat varian ini sangat penting. Lebih penting lagi, jika varian dibuat, itu
penting untuk dapat memisahkan varian atau untuk dapat mereproduksi
asli atau varian sesuka hati. Dengan make, sangat sulit untuk memisahkan build menjadi
beberapa direktori build, terpisah dari sumbernya. Dan jika teknik ini tidak digunakan,
itu juga hampir tidak mungkin untuk menjamin pada waktu tertentu varian mana yang ada
pohon, tanpa menggunakan pembangunan kembali yang lengkap.

Repositori

Make hanya menyediakan dukungan terbatas untuk membangun perangkat lunak dari kode yang ada di a
struktur direktori repositori pusat. Fitur VPATH dari GNU make (dan beberapa lainnya
make implementasi) dimaksudkan untuk menyediakan ini, tetapi tidak berfungsi seperti yang diharapkan: itu
mengubah jalur file target ke nama VPATH terlalu dini dalam analisisnya, dan karenanya
mencari semua dependensi di direktori VPATH. Untuk memastikan perkembangan yang benar
build, penting untuk dapat membuat file di direktori build lokal dan memiliki
file apa pun dalam repositori kode (direktori VPATH, dalam istilah make) yang bergantung pada lokal
file dapat dibangun kembali dengan benar. Ini tidak mungkin dengan VPATH, tanpa banyak coding
pengetahuan repositori kompleks langsung ke makefile.

Penyimpanan it sederhana


Beberapa kesulitan dengan make telah disebutkan di atas. Dalam ini dan selanjutnya
bagian, kami akan memperkenalkan Kontra dan menunjukkan bagaimana masalah ini ditangani.

Perl script

Kontra berbasis Perl. Yaitu, skrip Kontra--wajib militer dan Membangun file, setara
untuk Makefile or makefile--semuanya ditulis dalam Perl. Ini memberikan manfaat langsung:
bahasa untuk menulis skrip adalah salah satu yang akrab. Bahkan jika Anda tidak menjadi Perl
programmer, mengetahui bahwa Perl pada dasarnya hanyalah bahasa deklaratif sederhana,
dengan aliran kontrol yang terdefinisi dengan baik, dan semantik yang familiar. Ini memiliki variabel yang berperilaku
pada dasarnya seperti yang Anda harapkan, subrutin, aliran kontrol, dan sebagainya. Di sana
tidak ada sintaks khusus yang diperkenalkan untuk Kontra. Penggunaan Perl sebagai bahasa scripting
menyederhanakan tugas mengungkapkan solusi yang tepat untuk yang sering kompleks
persyaratan suatu bangunan.

Halo, Dunia!

Untuk membumikan diskusi berikut, inilah cara Anda dapat membangun Halo, Dunia! C
aplikasi dengan Kontra:

$env = kontra baru();
Program $env 'halo', 'hello.c';

Jika Anda menginstal skrip ini di direktori, beri nama skrip Membangun, dan buat
halo.c file sumber di direktori yang sama, maka Anda dapat mengetik `cons hello' untuk membangun
Aplikasi:

% kontra halo
cc -c halo.c -o halo.o
cc -o halo halo.o

Konstruksi lingkungan

Penyederhanaan kunci dari Kontra adalah gagasan a konstruksi lingkungan Hidup. Sebuah konstruksi
lingkungan adalah sebuah obyek dicirikan oleh satu set pasangan kunci/nilai dan satu set metode.
Untuk memberi tahu Kontra cara membangun sesuatu, Anda memanggil metode yang sesuai melalui an
lingkungan konstruksi yang sesuai. Perhatikan contoh berikut:

$env = kontra baru(
CC => 'gcc',
LIBS => 'libworld.a'
);

Program $env 'halo', 'hello.c';

Dalam hal ini, daripada menggunakan lingkungan konstruksi default, seperti yang kita miliki
mengganti nilai `CC' sehingga setara GNU C Compiler digunakan, sebagai gantinya. Sejak
versi ini Halo, Dunia! membutuhkan perpustakaan, libworld.a, kami telah menetapkan bahwa setiap
program yang ditautkan di lingkungan ini harus ditautkan dengan perpustakaan itu. Jika perpustakaan
sudah ada, baik dan bagus, tetapi jika tidak, maka kita juga harus menyertakan pernyataan:

Perpustakaan $env 'libworld', 'world.c';

Sekarang jika Anda mengetik `cons hello', perpustakaan akan dibangun sebelum program ditautkan, dan,
tentu saja, `gcc' akan digunakan untuk mengkompilasi kedua modul:

% kontra halo
gcc -c halo.c -o halo.o
gcc -c dunia.c -o dunia.o
ar r libworld.a dunia.o
ar: membuat libworld.a
ranlib libworld.a
gcc -o halo halo.o libworld.a

secara otomatis dan lengkap ketergantungan analisis

Dengan Kontra, dependensi ditangani secara otomatis. Melanjutkan contoh sebelumnya, perhatikan
bahwa ketika kita memodifikasi dunia.c, dunia.o dikompilasi ulang, libworld.a diciptakan kembali, dan halo
ditautkan kembali:

%vi dunia.c
[EDIT]
% kontra halo
gcc -c dunia.c -o dunia.o
ar r libworld.a dunia.o
ar: membuat libworld.a
ranlib libworld.a
gcc -o halo halo.o libworld.a

Ini adalah contoh yang relatif sederhana: Kontra `` tahu'' dunia.o tergantung pada dunia.c, Karena
ketergantungan secara eksplisit diatur oleh metode `Perpustakaan'. Itu juga tahu itu libworld.a
tergantung pada dunia.o dan bahwa halo tergantung pada libworld.a, semua untuk alasan yang sama.

Sekarang ternyata halo.c juga termasuk file definisi antarmuka, dunia.h:

% emacs dunia.h
[EDIT]
% kontra halo
gcc -c halo.c -o halo.o
gcc -o halo halo.o libworld.a

Bagaimana Kontra tahu itu? halo.c termasuk dunia.h, dan itu halo oleh karena itu harus
dikompilasi ulang? Untuk saat ini, cukuplah untuk mengatakan itu ketika mempertimbangkan apakah atau tidak halo sudah naik-
sampai saat ini, Kontra memanggil pemindai untuk ketergantungannya, halo.c. Pemindai ini menghitung:
file disertakan oleh halo.c untuk membuat daftar dependensi lebih lanjut, di luar itu
dibuat eksplisit oleh skrip Cons. Proses ini bersifat rekursif: semua file yang disertakan oleh
file yang disertakan juga akan dipindai.

Bukankah ini mahal? Jawabannya adalah, tergantung. Jika Anda melakukan pembangunan penuh dari sistem besar,
waktu pemindaian tidak signifikan. Jika Anda membangun kembali sistem besar, maka Kontra akan
menghabiskan cukup banyak waktu untuk memikirkannya sebelum memutuskan bahwa tidak ada yang harus terjadi
selesai (walaupun belum tentu lebih banyak waktu daripada membuat!). Kabar baiknya adalah bahwa Kontra membuatnya
sangat mudah untuk membuat subset build Anda secara cerdas, saat Anda mengerjakan perubahan yang dilokalkan.

secara otomatis global membangun pengurutan

Karena Cons melakukan analisis ketergantungan yang lengkap dan akurat, dan melakukan ini secara global, untuk
seluruh bangunan, Kontra dapat menggunakan informasi ini untuk mengambil kendali penuh dari pengurutan
dari membangun. Urutan ini terbukti dalam contoh di atas, dan setara dengan apa
Anda harapkan untuk membuat, mengingat set lengkap dependensi. Dengan Kontra, ini meluas
sepele untuk lebih besar, membangun multi-direktori. Akibatnya, semua kerumitan terlibat
dalam memastikan bahwa build diatur dengan benar--termasuk hierarki multi-pass
build--dihilangkan. Kita akan membahas ini lebih lanjut di bagian selanjutnya.

Bangunan besar pohon--masih hanya as sederhana


A hirarki of membangun script

Bangunan yang lebih besar, di Kontra, diatur dengan membuat hierarki membangun script. Di atas
dari pohon adalah skrip yang disebut Membangun. Skrip lainnya, menurut konvensi, adalah masing-masing
bernama wajib militer. Script ini dihubungkan bersama, sangat sederhana, dengan `Build',
Perintah `Ekspor', dan `Impor'.

Grafik Membangun Command

Perintah `Build' mengambil daftar wajib militer nama file, dan mengaturnya menjadi
termasuk dalam membangun. Sebagai contoh:

Bangun qw(
driver/tampilan/Wajib
driver/mouse/Wajib
pengurai/Wajib
utilitas/Wajib
);

Ini adalah hierarki skrip build dua tingkat sederhana: semua anak perusahaan wajib militer arsip
disebutkan di tingkat atas Membangun mengajukan. Perhatikan bahwa tidak semua direktori di pohon
tentu memiliki skrip build yang terkait dengannya.

Ini juga dapat ditulis sebagai skrip multi-level. Misalnya, Membangun file mungkin
berisi perintah ini:

Bangun qw(
pengurai/Wajib
pengemudi/Wajib
utilitas/Wajib
);

dan wajib militer file di driver direktori mungkin berisi ini:

Bangun qw(
tampilan / wajib militer
tikus/Wajib
);

Pengalaman menunjukkan bahwa model sebelumnya sedikit lebih mudah dipahami, karena
seluruh pohon konstruksi diletakkan di depan Anda, di tingkat atas. Skema hibrida adalah
juga mungkin. Komponen yang dipelihara secara terpisah yang perlu dimasukkan ke dalam a
build tree, misalnya, mungkin terhubung ke build tree di satu tempat, tetapi tentukan sendiri
hierarki konstruksi.

Secara default, Cons tidak mengubah direktori kerjanya ke direktori yang berisi a
anak perusahaan wajib militer file itu termasuk. Perilaku ini dapat diaktifkan untuk build by
menentukan, di tingkat atas Membangun File:

wajib militer_chdir 1;

Saat diaktifkan, Kontra akan berubah menjadi anak perusahaan wajib militer direktori yang berisi file
saat membaca di file itu, dan kemudian ubah kembali ke direktori tingkat atas setelah file
telah diproses.

Diharapkan bahwa perilaku ini akan menjadi default di beberapa versi Kontra di masa mendatang.
Untuk mempersiapkan transisi ini, build yang mengharapkan Cons tetap berada di atas build
saat membaca di anak perusahaan wajib militer file harus secara eksplisit menonaktifkan fitur ini sebagai
berikut:

wajib militer_chdir 0;

Relatif, kerabat atas, dan mutlak fillet nama

Anda mungkin telah memperhatikan bahwa nama file yang ditentukan untuk perintah Build relatif terhadap
lokasi skrip yang dipanggil. Ini umumnya berlaku untuk nama file lain
argumen untuk perintah lain juga, meskipun kami mungkin juga menyebutkan di sini bahwa jika Anda memulai
nama file dengan tanda hash, ``#'', maka file tersebut diinterpretasikan relatif ke atas-
direktori level (di mana Membangun file berada). Dan, tidak mengherankan, jika Anda memulainya
dengan ``/'', maka itu dianggap sebagai nama path absolut. Ini benar bahkan pada sistem
yang menggunakan garis miring ke belakang daripada garis miring ke depan untuk memberi nama jalur absolut.

Menggunakan modul in membangun script

Anda dapat menarik modul ke masing-masing wajib militer file menggunakan Perl `use' atau `require' normal
pernyataan:

gunakan Bahasa Inggris;
membutuhkan Saya::Modul;

Setiap `penggunaan' atau `memerlukan' hanya mempengaruhi satu wajib militer file di mana ia muncul. Untuk menggunakan
modul dalam beberapa wajib militer file, Anda harus memasukkan pernyataan `use' atau `require' di setiap file
yang membutuhkan modul.

Cakupan of variabel

Tingkat atas Membangun file dan semuanya wajib militer file mulai hidup dalam Perl . yang umum dan terpisah
paket. Kekurangan mengontrol tabel simbol untuk paket sehingga, tabel simbol untuk
setiap skrip kosong, kecuali untuk Membangun file, yang mendapatkan beberapa baris perintah
argumen. Semua variabel yang disetel atau digunakan, oleh karena itu, disetel oleh skrip
sendiri--bukan oleh beberapa skrip eksternal.

Variabel dapat secara eksplisit impor oleh skrip dari skrip induknya. Untuk mengimpor
variabel, itu pasti diekspor oleh orang tua dan diinisialisasi (jika tidak, kesalahan
akan terjadi).

Grafik Ekspor Command

Perintah `Export' digunakan seperti pada contoh berikut:

$env = kontra baru();
$TERMASUK = "#ekspor/sertakan";
$LIB = "#ekspor/lib";
Ekspor qw( env TERMASUK LIB );
Bangun qw( util/Wajib);

Nilai dari variabel sederhana yang disebutkan dalam daftar `Ekspor' akan dihilangkan
oleh perintah `Build' berikutnya. Perintah `Ekspor' hanya akan mengekspor Perl skalar
variabel, yaitu variabel yang namanya diawali dengan `$'. Variabel lain, objek, dll.
dapat diekspor dengan referensi--tetapi semua skrip akan merujuk ke objek yang sama, dan ini
objek harus dianggap sebagai hanya-baca oleh skrip tambahan dan oleh aslinya
mengekspor skrip. Namun, dapat diterima untuk menetapkan nilai baru ke skalar yang diekspor
variabel--yang tidak akan mengubah variabel dasar yang direferensikan. Urutan ini, untuk
contoh, OK:

$env = kontra baru();
Ekspor qw( env TERMASUK LIB );
Bangun qw( util/Wajib);
$env = kontra baru(CFLAGS => '-O');
Bangun qw(lain/Wajib);

Tidak masalah apakah variabel disetel sebelum atau sesudah perintah `Ekspor'. NS
yang penting adalah nilai variabel pada saat perintah `Build' dijalankan.
Ini adalah apa yang akan squirreled pergi. Omong-omong, perintah `Ekspor' berikutnya,
batalkan yang pertama: Anda harus menyebutkan semua variabel yang ingin Anda ekspor pada masing-masing
Perintah 'Ekspor'.

Grafik impor Command

Variabel yang diekspor oleh perintah `Ekspor' dapat diimpor ke skrip anak perusahaan oleh
Perintah 'Impor'. Skrip anak perusahaan selalu mengimpor variabel langsung dari
naskah unggul. Pertimbangkan contoh ini:

Impor qw( env TERMASUK );

Ini hanya legal jika skrip induk mengekspor `$env' dan `$INCLUDE'. Itu juga harus
telah memberikan masing-masing nilai variabel ini. Tidak apa-apa untuk skrip anak perusahaan saja
impor subset dari variabel yang diekspor (dalam contoh ini, `$LIB', yang diekspor oleh
contoh sebelumnya, tidak diimpor).

Semua variabel yang diimpor secara otomatis diekspor kembali, jadi urutannya:

Impor qw ( env TERMASUK );
Build qw (under-me/Conscript);

akan memasok `$env' dan `$INCLUDE' ke file anak perusahaan. Andai saja `$env' menjadi
diekspor, maka berikut ini sudah cukup:

Impor qw ( env TERMASUK );
Ekspor qw ( env );
Build qw (under-me/Conscript);

Tak perlu dikatakan, variabel dapat dimodifikasi secara lokal sebelum memanggil `Build' pada
naskah anak perusahaan.

Membangun naskah evaluasi urutan

Satu-satunya kendala dalam pemesanan skrip build adalah skrip superior adalah
dievaluasi sebelum skrip inferior mereka. Tingkat atas Membangun file, misalnya, adalah
dievaluasi terlebih dahulu, diikuti oleh skrip yang lebih rendah. Ini semua yang benar-benar perlu Anda ketahui
tentang urutan evaluasi, karena urutan umumnya tidak relevan. Pertimbangkan berikut ini
Perintah 'Bangun':

Bangun qw(
driver/tampilan/Wajib
driver/mouse/Wajib
pengurai/Wajib
utilitas/Wajib
);

Kami telah memilih untuk menempatkan nama skrip dalam urutan abjad, hanya karena itu yang paling
nyaman untuk tujuan pemeliharaan. Mengubah urutan tidak akan membuat perbedaan pada
membangun.

A Model untuk berbagi arsip


Beberapa sederhana konvensi

Dalam sistem perangkat lunak yang kompleks, metode untuk berbagi produk build harus
didirikan. Kami mengusulkan seperangkat konvensi sederhana yang sepele untuk diterapkan dengan
Kontra, tapi sangat efektif.

Aturan dasarnya adalah mengharuskan semua produk build yang perlu dibagikan di antara
direktori dibagikan melalui direktori perantara. Kami biasanya menyebut ini
ekspor, dan, dalam lingkungan C, menyediakan sub-direktori konvensional dari direktori ini,
seperti memasukkan, lib, bin, Dll

Direktori ini ditentukan oleh top-level Membangun mengajukan. Sederhana Membangun file untuk
a Halo, Dunia! aplikasi, diatur menggunakan beberapa direktori, mungkin terlihat seperti ini:

# Buat file untuk Halo, Dunia!

# Tempat meletakkan semua produk bersama kami.
$EKSPOR = '#ekspor';

Ekspor qw( KONTRA TERMASUK LIB BIN );

# Direktori standar untuk berbagi produk.
$TERMASUK = "$EKSPOR/termasuk";
$LIB = "$EKSPOR/lib";
$BIN = "$EKSPOR/bin";

# Lingkungan konstruksi standar.
$CONS = kontra baru (
CPPPATH => $INCLUDE, # Sertakan path untuk Kompilasi C
LIBPATH => $LIB, # Jalur perpustakaan untuk menghubungkan program
LIBS => '-lworld', # Daftar pustaka standar
);

Bangun qw(
halo/Wajib
dunia/Wajib
);

Grafik dunia direktori wajib militer filenya terlihat seperti ini:

# File wajib militer untuk dunia direktori
Impor qw( KONTRA TERMASUK LIB );

# Instal produk dari direktori ini
Instal $CONS $LIB, 'libworld.a';
Instal $CONS $INCLUDE, 'world.h';

# Produk internal
Perpustakaan $CONS 'libworld.a', 'world.c';

dan halo direktori wajib militer filenya terlihat seperti ini:

# File wajib militer untuk direktori hello
Impor qw( KONTRA BIN );

# Produk yang diekspor
Instal $CONS $BIN, 'halo';

# Produk internal
Program $CONS 'halo', 'hello.c';

Untuk membangun a Halo, Dunia! program dengan struktur direktori ini, pergi ke tingkat atas
direktori, dan memanggil `kontra' dengan argumen yang sesuai. Dalam contoh berikut, kita
beri tahu Kontra untuk membangun direktori ekspor. Untuk membangun direktori, Kontra membangun semua secara rekursif
produk yang dikenal dalam direktori itu (hanya jika mereka perlu membangun kembali, tentu saja). Jika salah satu dari
produk-produk itu bergantung pada produk lain di direktori lain, maka itu akan dibangun,
juga.

% kontra ekspor
Instal world/world.h sebagai export/include/world.h
cc -Iekspor/sertakan -c halo/hello.c -o halo/hello.o
cc -Iekspor/termasuk -c dunia/dunia.c -o dunia/dunia.o
ar r dunia/libworld.a dunia/dunia.o
ar: menciptakan dunia/libworld.a
dunia ranlib/libworld.a
Instal world/libworld.a sebagai export/lib/libworld.a
cc -o halo/halo halo/halo.o -Lexport/lib -lworld
Instal halo/halo sebagai ekspor/bin/halo

Bersih, dimengerti, lokasi-independen script

Anda akan perhatikan bahwa keduanya wajib militer file sangat bersih dan to-the-point. Mereka hanya
tentukan produk direktori dan cara membuat produk tersebut. Instruksi membangun
minimal: mereka menentukan lingkungan konstruksi mana yang akan digunakan, nama produk,
dan nama inputnya. Perhatikan juga bahwa skrip tidak bergantung pada lokasi: jika Anda
ingin mengatur ulang pohon sumber Anda, Anda bebas melakukannya: Anda hanya perlu mengubah
Membangun file (dalam contoh ini), untuk menentukan lokasi baru dari wajib militer file. Itu
penggunaan pohon ekspor membuat tujuan ini mudah.

Perhatikan juga, bagaimana Cons menangani detail kecil untuk Anda. Semua ekspor direktori, untuk
misalnya, dibuat secara otomatis. Dan file yang terinstal benar-benar tertaut ke dalam
direktori ekspor masing-masing, untuk menghemat ruang dan waktu. Perhatian terhadap detail ini menghemat
pekerjaan yang cukup besar, dan membuatnya lebih mudah untuk menghasilkan skrip yang sederhana dan dapat dipelihara.

Memisahkan sumber dan membangun pohon


Seringkali diinginkan untuk menyimpan file turunan apa pun dari build yang benar-benar terpisah dari
file sumber. Ini membuatnya lebih mudah untuk melacak apa yang dimaksud dengan file sumber, dan
juga membuatnya lebih mudah untuk ditangani varian build, terutama jika Anda menginginkan varian build
untuk hidup berdampingan.

Memisahkan membangun dan sumber direktori menggunakan itu Link Command

Kontra menyediakan mekanisme sederhana yang menangani semua persyaratan ini. `Tautan'
perintah dipanggil seperti dalam contoh ini:

Tautan 'membangun' => 'src';

Direktori yang ditentukan `` ditautkan'' ke direktori sumber yang ditentukan. Mari kita misalkan
bahwa Anda menyiapkan direktori sumber, src, dengan sub-direktori dunia dan halo di bawahnya,
seperti pada contoh sebelumnya. Anda kemudian dapat mengganti garis build asli dengan
sebagai berikut:

Bangun qw(
membangun/dunia/Wajib
membangun/halo/Wajib
);

Perhatikan bahwa Anda memperlakukan wajib militer file seolah-olah ada di direktori build. Sekarang jika
Anda mengetik perintah yang sama seperti sebelumnya, Anda akan mendapatkan hasil sebagai berikut:

% kontra ekspor
Instal build/world/world.h sebagai export/include/world.h
cc -Iekspor/sertakan -c build/hello/hello.c -o build/hello/hello.o
cc -Iexport/include -c build/dunia/dunia.c -o build/dunia/dunia.o
di build/world/libworld.a build/world/world.o
ar: membuat build/world/libworld.a
ranlib build/dunia/libworld.a
Instal build/world/libworld.a sebagai export/lib/libworld.a
cc -o bangun/halo/halo bangun/halo/hello.o -Lexport/lib -lworld
Instal build/hello/hello sebagai export/bin/hello

Sekali lagi, Kontra telah mengurus detailnya untuk Anda. Secara khusus, Anda akan melihat bahwa semua
build dilakukan menggunakan file sumber dan file objek dari direktori build. Untuk
contoh, membangun/dunia/dunia.o dikompilasi dari membangun/dunia/dunia.c, dan
ekspor/sertakan/dunia.h diinstal dari bangun/dunia/dunia.h. Ini dicapai pada sebagian besar
sistem dengan cara sederhana ``keras'' menghubungkan file yang diperlukan dari setiap sumber
direktori ke dalam direktori build yang sesuai.

Tautan dikelola dengan benar oleh Kontra, apa pun yang Anda lakukan ke direktori sumber.
Jika Anda memodifikasi file sumber, editor Anda dapat melakukan ini ``di tempat'' atau mungkin mengganti namanya
pertama dan buat file baru. Dalam kasus terakhir, tautan keras apa pun akan hilang. Kontra akan
mendeteksi kondisi ini pada saat file sumber diperlukan, dan akan menautkannya kembali
tepat

Omong-omong, Anda juga akan memperhatikan bahwa tidak perubahan diperlukan untuk yang mendasarinya wajib militer
file. Dan kita bisa melangkah lebih jauh, seperti yang akan kita lihat di bagian selanjutnya.

Varian membangun


Halo, Dunia! untuk pisang dan Persik OS

Varian build hanya memerlukan ekstensi sederhana lainnya. Mari kita ambil contoh a
persyaratan untuk memungkinkan build untuk sistem operasi baNaNa dan peAcH. Pada kasus ini,
kami menggunakan sistem file terdistribusi, seperti NFS untuk mengakses sistem tertentu, dan
hanya satu atau yang lain dari sistem yang harus dikompilasi untuk permintaan tertentu dari
'kontra'. Inilah salah satu cara kita dapat mengatur Membangun file untuk kami Halo, Dunia!
Aplikasi:

# Buat file untuk Halo, Dunia!

die qq(OS harus ditentukan) kecuali $OS = $ARG{OS};
die qq(OS harus "persik" atau "pisang")
if $OS ne "peach" && $OS ne "banana";

# Tempat meletakkan semua produk bersama kami.
$EKSPOR = "#ekspor/$OS";

Ekspor qw( KONTRA TERMASUK LIB BIN );

# Direktori standar untuk berbagi produk.
$TERMASUK = "$EKSPOR/termasuk";
$LIB = "$EKSPOR/lib";
$BIN = "$EKSPOR/bin";

# Lingkungan konstruksi standar.
$CONS = kontra baru (
CPPPATH => $INCLUDE, # Sertakan path untuk Kompilasi C
LIBPATH => $LIB, # Jalur perpustakaan untuk menghubungkan program
LIBS => '-lworld', # Daftar pustaka standar
);

# $BUILD adalah tempat kita akan mendapatkan segalanya.
$BUILD = "#build/$OS";

# Beri tahu kontra di mana file sumber untuk $BUILD berada.
Tautan $BUILD => 'src';

Membangun (
"$BUILD/halo/Wajib",
"$BUILD/world/Wajib",
);

Sekarang jika kita login ke sistem peAcH, kita dapat membangun Halo, Dunia! aplikasi untuk itu
peron:

% kontra ekspor OS=peach
Instal build/peach/world/world.h sebagai export/peach/include/world.h
cc -Iexport/peach/include -c build/peach/hello/hello.c -o build/peach/hello/hello.o
cc -Iexport/peach/include -c build/peach/world/world.c -o build/peach/world/world.o
ar r build/peach/world/libworld.a build/peach/world/world.o
ar: membuat build/peach/world/libworld.a
ranlib build/peach/world/libworld.a
Instal build/peach/world/libworld.a sebagai export/peach/lib/libworld.a
cc -o build/peach/hello/hello build/peach/hello/hello.o -Lexport/peach/lib -lworld
Instal build/peach/hello/hello sebagai ekspor/peach/bin/hello

Variasi on a tema

Variasi lain dari model ini dimungkinkan. Misalnya, Anda mungkin memutuskan bahwa Anda ingin
untuk memisahkan file penyertaan Anda menjadi file yang bergantung pada platform dan tidak bergantung pada platform.
Dalam hal ini, Anda harus menentukan alternatif untuk `$INCLUDE' untuk platform-dependent
file. Paling wajib militer file, menghasilkan file termasuk platform-independen murni, akan
tidak harus berubah.

Anda mungkin juga ingin dapat mengkompilasi seluruh sistem Anda dengan debugging atau profil,
misalnya, diaktifkan. Anda dapat melakukan ini dengan opsi baris perintah yang sesuai, seperti
`DEBUG = aktif'. Ini kemudian akan diterjemahkan ke dalam platform-spesifik yang sesuai
persyaratan untuk mengaktifkan debugging (ini mungkin termasuk mematikan pengoptimalan, untuk
contoh). Anda dapat secara opsional memvariasikan ruang nama untuk berbagai jenis sistem ini,
tapi, seperti yang akan kita lihat di bagian selanjutnya, itu tidak penting untuk melakukan ini, karena Kontra itu cantik
pintar tentang membangun kembali hal-hal ketika Anda mengubah opsi.

Tanda tangan


MD5 kriptografi tanda tangan

Setiap kali Cons membuat file turunan, ia menyimpan tanda tangan untuk file itu. Tanda tangan
disimpan dalam file terpisah, satu per direktori. Setelah contoh sebelumnya dikompilasi,
itu .memperuntukkan file di membangun/persik/dunia direktori tampak seperti ini:

world.o:834179303 23844c0b102ecdc0b4548d1cd1cbd8c6
libworld.a:834179304 9bf6587fa06ec49d864811a105222c00

Angka pertama adalah stempel waktu--untuk sistem UNIX, ini biasanya jumlah
detik sejak 1 Januari 1970. Nilai kedua adalah checksum MD5. NS Sambutan dari Manajer Umum PT. LUHAI INDUSTRIAL intisari
Algoritma adalah algoritme yang, diberikan string input, menghitung kriptografi yang kuat
tanda tangan untuk string itu. Checksum MD5 disimpan di .memperuntukkan file, pada dasarnya, adalah
intisari semua informasi ketergantungan untuk file yang ditentukan. Jadi, misalnya, untuk
dunia.o file, ini termasuk setidaknya dunia.c file, dan juga file header apa pun yang Kontra
tahu tentang itu termasuk, secara langsung atau tidak langsung oleh dunia.c. Bukan hanya itu, tetapi juga
baris perintah aktual yang digunakan untuk menghasilkan dunia.o juga dimasukkan ke dalam perhitungan
tanda tangan. Demikian pula, libworld.a mendapat tanda tangan yang ``mencakup'' semua
tanda tangan konstituennya (dan karenanya, secara transitif, tanda tangan dari mereka
konstituen), serta baris perintah yang membuat file.

Tanda tangan dari file yang tidak diturunkan dihitung, secara default, dengan mengambil arus
waktu modifikasi file dan nama entri file (kecuali jika ada
arus .memperuntukkan entri untuk file itu, di mana tanda tangan itu digunakan).

Perhatikan bahwa file turunan tidak perlu bergantung pada hal tertentu Membangun or
wajib militer file--jika perubahan pada file ini memengaruhi file yang dimaksud, maka ini akan menjadi
secara otomatis tercermin dalam tanda tangannya, karena bagian yang relevan dari baris perintah adalah
dicantumkan dalam tanda tangan. Perubahan yang tidak terkait tidak akan berpengaruh.

Ketika Cons mempertimbangkan apakah akan menurunkan file tertentu, maka, pertama-tama ia menghitung
tanda tangan yang diharapkan dari file tersebut. Kemudian membandingkan waktu modifikasi terakhir file dengan
waktu yang tercatat dalam .memperuntukkan masuk, jika ada. Jika waktu ini cocok, maka
tanda tangan disimpan di .memperuntukkan file dianggap akurat. Jika file sebelumnya
tanda tangan tidak cocok dengan tanda tangan baru yang diharapkan, maka file harus diturunkan kembali.

Perhatikan bahwa file akan diturunkan setiap kali ada perubahan tentang file dependen. Di dalam
tertentu, perhatikan bahwa Apa pun perubahan ke waktu modifikasi dari dependen (maju atau
mundur dalam waktu) akan memaksa kompilasi ulang dari file yang diturunkan.

Penggunaan tanda tangan ini adalah metode yang sangat sederhana, efisien, dan efektif untuk
meningkatkan - secara dramatis - reproduktifitas sistem.

Kami akan menunjukkan ini dengan contoh sederhana:

# Sederhana "Halo, Dunia!" Buat file
$CFLAGS = '-g' jika $ARG{DEBUG} eq 'on';
$CONS = kontra baru(CFLAGS => $CFLAGS);
Program $CONS 'halo', 'hello.c';

Perhatikan bagaimana Cons mengkompilasi ulang pada waktu yang tepat:

% kontra halo
cc -c halo.c -o halo.o
cc -o halo halo.o
% kontra halo
kontra: "halo" up-to-date.
% kontra DEBUG=pada halo
cc -g -c halo.c -o halo.o
cc -o halo halo.o
% kontra DEBUG=pada halo
kontra: "halo" up-to-date.
% kontra halo
cc -c halo.c -o halo.o
cc -o halo halo.o

Kode Repositori


Banyak organisasi pengembangan perangkat lunak akan memiliki satu atau lebih direktori repositori pusat
pohon yang berisi kode sumber saat ini untuk satu atau lebih proyek, serta turunan
file objek, perpustakaan, dan executable. Untuk mengurangi kompilasi ulang yang tidak perlu,
berguna untuk menggunakan file dari repositori untuk membangun perangkat lunak pengembangan--dengan asumsi, dari
tentu saja, bahwa tidak ada file dependensi yang lebih baru di pohon build lokal.

Gudang

Kontra menyediakan mekanisme untuk menentukan daftar repositori kode yang akan dicari,
in-order, untuk file sumber dan file turunan yang tidak ditemukan di pohon direktori build lokal.

Baris berikut dalam a Membangun file akan menginstruksikan Kontra untuk melihat terlebih dahulu di bawah
/usr/eksperimen/repositori direktori dan kemudian di bawah /usr/produk/repositori direktori:

Gudang qw (
/usr/eksperimen/repositori
/usr/produk/repositori
);

Direktori repositori yang ditentukan mungkin berisi file sumber, file turunan (objek,
library dan executable), atau keduanya. Jika tidak ada file lokal (sumber atau turunan) di bawah
direktori di mana Cons dijalankan, kemudian salinan pertama dari file dengan nama yang sama ditemukan
di bawah direktori repositori akan digunakan untuk membangun file turunan lokal apa pun.

Kontra memelihara satu daftar global direktori repositori. Kontra akan menghilangkan
direktori saat ini, dan direktori yang tidak ada, dari daftar.

Temuan itu Membangun fillet in a Gudang

Kontra juga akan mencari Membangun dan wajib militer file di pohon repositori atau pohon.
Ini mengarah ke situasi ayam-dan-telur: bagaimana Anda melihat di pohon repositori
untuk Membangun mengajukan jika Membangun file memberi tahu Anda di mana repositori itu? Mendapatkan
sekitar ini, repositori dapat ditentukan melalui opsi `-R' pada baris perintah:

% kontra -R /usr/experiment/repository -R /usr/product/repository .

Direktori repositori apa pun yang ditentukan dalam Membangun or wajib militer file akan ditambahkan
ke direktori repositori yang ditentukan oleh opsi baris perintah `-R'.

Gudang sumber arsip

Jika kode sumber (sertakan wajib militer file) untuk versi perpustakaan dari Halo,
Dunia! Aplikasi C ada dalam repositori (tanpa file turunan), Kontra akan menggunakan
file sumber repositori untuk membuat file objek lokal dan file yang dapat dieksekusi:

% kontra -R /usr/src_only/repositori halo
gcc -c /usr/src_only/repository/hello.c -o halo.o
gcc -c /usr/src_only/repository/world.c -o world.o
ar r libworld.a dunia.o
ar: membuat libworld.a
ranlib libworld.a
gcc -o halo halo.o libworld.a

Membuat file sumber lokal akan menyebabkan Kontra membangun kembali file turunan yang sesuai atau
file:

% pico dunia.c
[EDIT]
% kontra -R /usr/src_only/repositori halo
gcc -c dunia.c -o dunia.o
ar r libworld.a dunia.o
ar: membuat libworld.a
ranlib libworld.a
gcc -o halo halo.o libworld.a

Dan menghapus file sumber lokal akan menyebabkan Kontra kembali ke bangunan turunan
file dari sumber repositori:

% rm dunia.c
% kontra -R /usr/src_only/repositori halo
gcc -c /usr/src_only/repository/world.c -o world.o
ar r libworld.a dunia.o
ar: membuat libworld.a
ranlib libworld.a
gcc -o halo halo.o libworld.a

Gudang berasal arsip

Jika pohon repositori berisi file turunan (biasanya file objek, perpustakaan, atau
executable), Kontra akan melakukan perhitungan tanda tangan normal untuk memutuskan apakah
file repositori up-to-date atau file turunan harus dibangun secara lokal. Ini berarti bahwa,
untuk memastikan perhitungan tanda tangan yang benar, pohon repositori juga harus berisi
.memperuntukkan file yang dibuat oleh Kontra saat membuat file turunan.

Ini biasanya akan dicapai dengan membangun perangkat lunak dalam repositori (atau,
sebagai alternatif, di direktori build, lalu menyalin hasilnya ke repositori):

% cd /usr/semua/repositori
% kontra halo
gcc -c halo.c -o halo.o
gcc -c dunia.c -o dunia.o
ar r libworld.a dunia.o
ar: membuat libworld.a
ranlib libworld.a
gcc -o halo halo.o libworld.a

(Ini aman bahkan jika Membangun daftar file /usr/all/repositori direktori di a
Perintah `Repositori' karena Kontra akan menghapus direktori saat ini dari repositori
Daftar.)

Sekarang jika kita ingin membuat salinan aplikasi dengan milik kita sendiri halo.c file, kita hanya perlu
untuk membuat satu file sumber yang diperlukan, dan gunakan opsi `-R' agar Kontra menggunakan yang lain
file dari repositori:

% mkdir $HOME/build1
% cd $HOME/bangunan1
% ed halo.c
[EDIT]
% kontra -R /usr/all/repositori halo
gcc -c halo.c -o halo.o
gcc -o halo halo.o /usr/all/repository/libworld.a

Perhatikan bahwa Kontra tidak repot-repot membuat ulang lokal libworld.a perpustakaan (atau kompilasi ulang
dunia.o module), tetapi menggunakan versi yang sudah dikompilasi dari repositori.

Karena tanda tangan MD5 yang dimasukkan Kontra ke dalam .memperuntukkan file berisi stempel waktu untuk
file turunan, stempel waktu tanda tangan harus cocok dengan stempel waktu file agar tanda tangan dapat
dianggap sah.

Beberapa sistem perangkat lunak dapat mengubah stempel waktu pada file repositori (dengan menyalinnya,
misalnya), dalam hal ini Kontra akan, secara default, menganggap tanda tangan repositori tidak valid
dan membangun kembali file yang tidak perlu. Perilaku ini dapat diubah dengan menentukan:

Repositori_Sig_Times_OK 0;

Ini memberitahu Kontra untuk mengabaikan cap waktu saat memutuskan apakah tanda tangan valid. (Catatan
bahwa menghindari pemeriksaan kewarasan ini berarti harus ada kontrol yang tepat atas repositori
tree untuk memastikan bahwa file turunan tidak dapat dimodifikasi tanpa memperbarui .memperuntukkan
tanda tangan.)

Bahan Makanan Lokal salinan of arsip

Jika pohon repositori berisi hasil lengkap dari sebuah build, dan kami mencoba membangun dari
repositori tanpa file apa pun di pohon lokal kami, sesuatu yang cukup mengejutkan
terjadi:

% mkdir $HOME/build2
% cd $HOME/bangunan2
% kontra -R /usr/all/repositori halo
kontra: "halo" up-to-date.

Mengapa Kontra mengatakan bahwa halo program terbaru ketika tidak ada halo program di
direktori build lokal? Karena repositori (bukan direktori lokal) berisi
mutakhir halo program, dan Kontra dengan benar menentukan bahwa tidak ada yang perlu dilakukan untuk
membangun kembali salinan file terbaru ini.

Namun demikian, sering kali tepat untuk memastikan bahwa salinan lokal dari a
berkas selalu ada. Skrip pengemasan atau pengujian, misalnya, dapat mengasumsikan bahwa
file yang dihasilkan ada secara lokal. Alih-alih membuat skrip anak perusahaan ini menyadari
direktori repositori, perintah `Lokal' dapat ditambahkan ke a Membangun or wajib militer file untuk
tentukan bahwa file atau file tertentu harus muncul di direktori build lokal:

qw lokal (
halo
);

Kemudian, jika kita menjalankan kembali perintah yang sama, Kontra akan membuat salinan lokal program dari
salinan repositori (memberi tahu Anda bahwa ia melakukannya):

% kontra -R /usr/all/repositori halo
Salinan lokal hello dari /usr/all/repository/hello
kontra: "halo" up-to-date.

Perhatikan bahwa, karena tindakan membuat salinan lokal tidak dianggap sebagai "pembuatan" dari
halo file, Kontra masih melaporkan bahwa itu mutakhir.

Membuat salinan lokal paling berguna untuk file yang sedang diinstal ke dalam
direktori perantara (untuk berbagi dengan direktori lain) melalui perintah `Instal'.
Mendampingi perintah `Instal' untuk file dengan perintah `Lokal' pendamping begitu
umum bahwa Cons menyediakan perintah `Install_Local' sebagai cara mudah untuk melakukan keduanya:

Install_Local $env, '#ekspor', 'halo';

persis sama dengan:

Instal $env '#ekspor', 'halo';
'#ekspor/halo' lokal;

Baik perintah `Lokal' dan `Instal_Lokal' memperbarui lokal .memperuntukkan file dengan
tanda tangan file yang sesuai, sehingga pembuatan di masa mendatang dilakukan dengan benar.

Gudang ketergantungan analisis

Karena pemindaian bawaannya, Kontra akan mencari pohon repositori yang ditentukan untuk disertakan
.h file. Kecuali jika kompiler juga tahu tentang pohon repositori, itu akan menjadi
tidak dapat ditemukan .h file yang hanya ada di repositori. Jika, misalnya, halo.c
file termasuk halo.h file di direktori saat ini:

% kontra -R /usr/all/repositori halo
gcc -c /usr/all/repository/hello.c -o halo.o
/usr/all/repository/hello.c:1: hello.h: Tidak ada file atau direktori seperti itu

Memecahkan masalah ini memaksa beberapa persyaratan pada lingkungan konstruksi
didefinisikan dan pada cara direktif praprosesor C `#include' digunakan untuk menyertakan file.

Untuk memberi tahu kompiler tentang pohon repositori, Kontra akan menambahkan `-I' yang sesuai
menandai perintah kompilasi. Ini berarti bahwa variabel `CPPPATH' di
lingkungan konstruksi harus secara eksplisit menentukan semua subdirektori yang akan dicari
untuk file yang disertakan, termasuk direktori saat ini. Akibatnya, kita dapat memperbaiki hal di atas
misalnya dengan mengubah penciptaan lingkungan di Membangun file sebagai berikut:

$env = kontra baru(
CC => 'gcc',
CPPPATH => '.',
LIBS => 'libworld.a',
);

Karena definisi variabel `CPPPATH', ini menghasilkan, ketika kita menjalankan kembali
perintah:

% kontra -R /usr/all/repositori halo
gcc -c -I. -I/usr/all/repositori /usr/all/repositori/hello.c -o hello.o
gcc -o halo halo.o /usr/all/repository/libworld.a

Urutan flag `-I' direplikasi, untuk preprosesor C, repositori yang sama-
jalur pencarian direktori yang digunakan Cons untuk analisis ketergantungannya sendiri. Jika ada
beberapa repositori dan beberapa direktori `CPPPATH', Kontra akan menambahkan repositori
direktori ke awal setiap direktori `CPPPATH', dengan cepat mengalikan nomornya
dari bendera `-I'. Sebagai contoh ekstrim, Membangun berkas yang berisi:

Gudang qw(
/u1
/u2
);

$env = kontra baru(
CPPPATH => 'a:b:c',
);

Akan menghasilkan perintah kompilasi dari:

cc -Ia -I/u1/a -I/u2/a -Ib -I/u1/b -I/u2/b -Ic -I/u1/c -I/u2/c -c hello.c -o halo.o

Karena Cons bergantung pada flag `-I' compiler untuk mengomunikasikan urutannya
direktori repositori harus dicari, penanganan kontra direktori repositori adalah
pada dasarnya tidak sesuai dengan penggunaan tanda kutip ganda pada arahan `#include' di C . Anda
Kode sumber:

#include "file.h" /* JANGAN GUNAKAN KUTIPAN GANDA SEPERTI INI */

Ini karena sebagian besar praprosesor C, ketika dihadapkan dengan arahan seperti itu, akan selalu menjadi yang pertama
cari direktori yang berisi file sumber. Ini merusak `-I' yang rumit
opsi yang dibuat Cons untuk membuat praprosesor sesuai dengan pencarian yang disukainya
jalan.

Akibatnya, saat menggunakan pohon repositori di Kontra, selalu gunakan kurung sudut untuk disertakan
file:

#termasuk /* GUNAKAN ANGLE-BRACKET BUKAN */

Daftar_Repositori

Kontra menyediakan perintah `Repository_List' untuk mengembalikan daftar semua direktori repositori
dalam urutan pencarian mereka saat ini. Ini dapat digunakan untuk debugging, atau untuk melakukan Perl . yang lebih kompleks
hal-hal:

@daftar = Daftar_Repositori;
print join(' ', @daftar), "\n";

Gudang interaksi dengan lain Kekurangan fitur

Penanganan kontra dari pohon repositori berinteraksi dengan benar dengan fitur Kontra lainnya--yaitu
untuk mengatakan, umumnya melakukan apa yang Anda harapkan.

Terutama, pohon repositori berinteraksi dengan benar, dan agak kuat, dengan 'Link'
memerintah. Pohon repositori mungkin berisi satu atau lebih subdirektori untuk versi build
dibuat melalui `Link' ke subdirektori sumber. Kontra akan mencari file turunan di
subdirektori build yang sesuai di bawah pohon repositori.

Default target


Sampai sekarang, kami telah mendemonstrasikan pemanggilan Kontra dengan target eksplisit untuk membangun:

% kontra halo

Biasanya, Kontra tidak membangun apa pun kecuali target ditentukan, tetapi menentukan '.'
(direktori saat ini) akan membangun semuanya:

% kontra # tidak membangun apa-apa

% kontra . # membangun semuanya di bawah direktori tingkat atas

Menambahkan metode `Default' ke sembarang Membangun or wajib militer file akan menambahkan yang ditentukan
target ke daftar target default. Kontra akan membangun default ini jika tidak ada
target yang ditentukan pada baris perintah. Jadi tambahkan baris berikut ke level teratas
Membangun file akan meniru perilaku khas Make dalam membangun semuanya secara default:

Bawaan '.';

Berikut ini akan menambahkan halo dan selamat tinggal perintah (dalam direktori yang sama dengan
Membangun or wajib militer file) ke daftar default:

qw bawaan (
halo
selamat tinggal
);

Metode `Default' dapat digunakan lebih dari sekali untuk menambahkan target ke daftar default.

Selektif membangun


Kontra menyediakan dua metode untuk mengurangi ukuran build yang diberikan. Yang pertama adalah dengan menentukan
target pada baris perintah, dan yang kedua adalah metode untuk memangkas pohon build. Sehat
pertimbangkan spesifikasi target terlebih dahulu.

Selektif penargetan

Seperti make, Cons memungkinkan spesifikasi ``target'' pada baris perintah. Kontra target
dapat berupa file atau direktori. Ketika sebuah direktori ditentukan, ini hanyalah sebuah short-
notasi tangan untuk setiap produk turunan--yang diketahui Kontra--dalam spesifikasi
direktori dan di bawahnya. Sebagai contoh:

% kontra build/hello/hello.o

berarti membangun halo dan segala sesuatu yang halo mungkin membutuhkan. Ini dari sebelumnya
versi Halo, Dunia! program di mana halo tergantung pada
ekspor/sertakan/dunia.h. Jika file itu tidak up-to-date (karena seseorang memodifikasi
src/dunia/dunia.h), maka itu akan dibangun kembali, meskipun berada di direktori yang jauh dari
membangun/halo.

Dalam contoh ini:

% kontra membangun

Segala sesuatu di membangun direktori dibangun, jika perlu. Sekali lagi, ini dapat menyebabkan lebih banyak file
untuk dibangun. Secara khusus, keduanya ekspor/sertakan/dunia.h dan ekspor/lib/libworld.a adalah
dibutuhkan oleh membangun/halo direktori, dan mereka akan dibangun jika mereka kedaluwarsa.

Jika kita melakukannya, sebagai gantinya:

% kontra ekspor

maka hanya file yang harus diinstal di direktori ekspor yang akan dibangun kembali, jika
diperlukan, dan kemudian diinstal di sana. Perhatikan bahwa `cons build' mungkin membuat file yang `cons
export' tidak membangun, dan sebaliknya.

Tidak ``khusus'' target

Dengan Kontra, target ``khusus'' gaya make tidak diperlukan. Analog paling sederhana dengan Kontra
adalah menggunakan khusus ekspor direktori, sebagai gantinya. Anggaplah, misalnya, Anda memiliki
seluruh rangkaian pengujian unit yang terkait dengan kode Anda. Tes hidup di
direktori sumber di dekat kode. Biasanya, bagaimanapun, Anda tidak ingin membangun tes ini.
Salah satu solusinya adalah menyediakan semua instruksi build untuk membuat tes, dan kemudian untuk
instal tes ke bagian terpisah dari pohon. Jika kami memasang tes di tingkat atas
direktori bernama tes, kemudian:

% kontra tes

akan membangun semua tes.

% kontra ekspor

akan membangun versi produksi sistem (tetapi bukan pengujian), dan:

% kontra membangun

mungkin harus dihindari (karena akan mengkompilasi tes yang tidak perlu).

Jika Anda ingin membuat hanya satu pengujian, Anda dapat secara eksplisit menamai pengujian tersebut (dalam
baik tes direktori atau membangun direktori). Anda juga dapat menggabungkan tes
ke dalam hierarki yang nyaman dalam direktori tes. Hirarki ini tidak perlu
harus cocok dengan hierarki sumber, dengan cara yang hampir sama dengan hierarki penyertaan
mungkin tidak cocok dengan hierarki sumber (hierarki penyertaan tidak mungkin lebih
dari dua tingkat dalam, untuk program C).

Jika Anda benar-benar ingin membangun semua yang ada di pohon (tergantung pada opsi apa pun yang Anda inginkan
pilih), Anda dapat menggunakan:

% kontra .

Ini tidak terlalu efisien, karena akan berjalan berlebihan di semua pohon,
termasuk pohon sumber. Pohon sumber, tentu saja, mungkin memiliki objek yang dapat dibangun di
itu--tidak ada yang menghentikan Anda untuk melakukan ini, bahkan jika Anda biasanya membangun di build terpisah
pohon.

Membangun Pemangkasan


Dalam hubungannya dengan pemilihan sasaran, membangun pemangkasan dapat digunakan untuk mengurangi ruang lingkup
membangun. Pada contoh peAcH dan baNaNa sebelumnya, kita telah melihat bagaimana script-driven
build pruning dapat digunakan untuk membuat hanya setengah dari build potensial yang tersedia untuk semua yang diberikan
pemanggilan `kontra'. Kontra juga menyediakan, sebagai kenyamanan, konvensi baris perintah yang
memungkinkan Anda untuk menentukan yang wajib militer file benar-benar mendapatkan ``built''--yaitu, dimasukkan
ke dalam pohon bangunan. Sebagai contoh:

% kontra membangun +dunia

Argumen `+' memperkenalkan ekspresi reguler Perl. Ini harus, tentu saja, dikutip di
tingkat shell jika ada karakter meta shell dalam ekspresi. NS
ekspresi dicocokkan dengan masing-masing wajib militer file yang telah disebutkan dalam `Build'
pernyataan, dan hanya skrip dengan nama yang cocok yang benar-benar dimasukkan ke dalam
membangun pohon. Beberapa argumen seperti itu diperbolehkan, dalam hal ini cocok dengan salah satu dari mereka
cukup untuk menyebabkan skrip dimasukkan.

Pada contoh di atas, halo program tidak akan dibangun, karena Kontra tidak akan ada
pengetahuan tentang naskah halo/Wajib. itu libworld.a arsip akan dibangun, namun, jika
perlu.

Ada beberapa kegunaan untuk membangun pemangkasan melalui baris perintah. Mungkin yang paling berguna
adalah kemampuan untuk membuat perubahan lokal, dan kemudian, dengan pengetahuan yang cukup tentang
konsekuensi dari perubahan itu, batasi ukuran pohon build untuk mempercepat
waktu membangun kembali. Penggunaan kedua untuk pemangkasan bangunan adalah untuk secara aktif mencegah kompilasi ulang
dari file tertentu yang Anda tahu akan dikompilasi ulang karena, misalnya, file header yang dimodifikasi.
Anda mungkin tahu bahwa perubahan pada file header tidak penting, atau bahwa
perubahan dapat diabaikan dengan aman untuk sebagian besar pohon, untuk tujuan pengujian. Dengan Kontra,
Pandangan ini adalah pragmatis untuk mengakui jenis perilaku ini, dengan pemahaman bahwa
pada pembangunan penuh berikutnya semua yang perlu dibangun kembali akan. Tidak ada yang setara
ke perintah ``make touch'', untuk menandai file sebagai yang terbaru secara permanen. Jadi resiko apapun itu
yang ditimbulkan oleh pemangkasan bangunan dimitigasi. Untuk pekerjaan berkualitas rilis, tentu saja, kami merekomendasikan
bahwa Anda tidak menggunakan pemangkasan build (tidak apa-apa untuk digunakan selama integrasi, namun,
untuk memeriksa kompilasi, dll. Pastikan untuk melakukan build yang tidak dibatasi sebelum melakukan
integrasi).

Sementara menimpa


Kontra menyediakan mekanisme yang sangat sederhana untuk mengesampingkan aspek build. intinya adalah
bahwa Anda menulis file override yang berisi satu atau lebih perintah `Override', dan Anda
tentukan ini di baris perintah, saat Anda menjalankan `kontra':

% kontra -o lebih dari ekspor

akan membangun ekspor direktori, dengan semua file turunan tunduk pada penggantian yang ada
dalam lebih mengajukan. Jika Anda mengabaikan opsi `-o', maka semua yang diperlukan untuk dihapus
semua override akan dibangun kembali.

Utama lingkungan Hidup variabel

File override dapat berisi dua jenis override. Yang pertama adalah lingkungan masuk
variabel. Ini biasanya dapat diakses oleh Membangun file dari hash `%ENV'
variabel. Ini dapat dengan mudah ditimpa dalam file override dengan mengatur
elemen yang sesuai dari `%ENV' (ini juga dapat diganti di lingkungan pengguna,
tentu saja).

Grafik Mengesampingkan Command

Tipe kedua dari override dilakukan dengan perintah `Override', yang terlihat seperti
ini:

Mengesampingkan , => , => , ...;

Ekspresi reguler regexp dicocokkan dengan setiap file turunan yang merupakan kandidat
untuk membangun. Jika file turunan cocok, maka pasangan variabel/nilai digunakan untuk
menimpa nilai dalam lingkungan konstruksi yang terkait dengan file turunan.

Misalkan kita memiliki lingkungan konstruksi seperti ini:

$KON = kontra baru(
COPT => '',
CDBG => '-g',
CFLAGS => '%COPT %CDBG',
);

Kemudian jika kita memiliki file override lebih berisi perintah ini:

Ganti '\.o$', COPT => '-O', CDBG => '';

maka permintaan `kontra' apa pun dengan `-o over' yang membuat .o file melalui lingkungan ini akan
menyebabkan mereka dikompilasi dengan `-O 'dan tanpa `-g'. Penimpaannya tentu saja bisa
dibatasi ke satu direktori dengan pilihan ekspresi reguler yang sesuai.

Inilah versi asli Hello, World! program, dibangun dengan lingkungan ini.
Perhatikan bahwa Kontra membangun kembali bagian yang sesuai saat penggantian diterapkan atau dihapus:

% kontra halo
cc -g -c halo.c -o halo.o
cc -o halo halo.o
% kontra -o daripada halo
cc -O -c halo.c -o halo.o
cc -o halo halo.o
% kontra -o daripada halo
kontra: "halo" up-to-date.
% kontra halo
cc -g -c halo.c -o halo.o
cc -o halo halo.o

Sangat penting bahwa perintah `Override' hanya digunakan untuk sementara, on-the-fly
penggantian yang diperlukan untuk pengembangan karena penggantian tidak independen dari platform dan
karena mereka terlalu mengandalkan pengetahuan mendalam tentang cara kerja skrip. Untuk
penggunaan sementara, namun, mereka persis seperti yang Anda inginkan.

Perhatikan bahwa masih berguna untuk memberikan, katakanlah, kemampuan untuk membuat sepenuhnya dioptimalkan
versi sistem untuk penggunaan produksi--dari Membangun dan wajib militer file. Cara ini
Anda dapat menyesuaikan sistem yang dioptimalkan ke platform. Di mana trade-off pengoptimal perlu
dibuat (file tertentu mungkin tidak dikompilasi dengan optimasi penuh, misalnya), maka
ini dapat direkam untuk anak cucu (dan reproduktifitas) langsung di skrip.

More on konstruksi lingkungan


Default konstruksi variabel

Kami telah menyebutkan, dan menggunakan, konsep a konstruksi lingkungan Hidup, berkali-kali dalam
halaman sebelumnya. Sekarang saatnya untuk membuat ini sedikit lebih konkret. Dengan berikut ini
pernyataan:

$env = kontra baru();

referensi ke lingkungan konstruksi default baru dibuat. Ini berisi nomor
variabel konstruksi dan beberapa metode. Pada tulisan ini, daftar default dari
variabel konstruksi didefinisikan sebagai berikut:

CC => 'cc',
CFLAGS => '',
CCCOM => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
INCDIRPREFIX => '-saya',
CXX => '%CC',
CXXFLAGS => '%CFLAGS',
CXXCOM => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
LINK => '%CXX',
LINKCOM => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
LINKMODULECOM => '%LD -r -o %> %<',
LIBDIRPREFIX => '-L',
AR => 'ar',
ARFLAG => 'r',
ARCOM => "%AR %ARFLAGS %> %<\n%RANLIB %>",
RANLIB => 'ranlib',
AS => 'sebagai',
ASFLAG => '',
ASCOM => '%AS %ASFLAGS %< -o %>',
LD => 'l',
LDFLAGS => '',
PREFLIB => 'lib',
SUFLIB => '.a',
SUFLIBS => '.so:.a',
SUFOBJ => '.o',
ENV => { 'JALAN' => '/tempat sampah:/ usr / bin' },

Pada sistem Win32 (Windows NT), variabel konstruksi berikut diganti di:
default:

CC => 'cl',
CFLAGS => '/nologo',
CCCOM => '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
CXXCOM => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
INCDIRPREFIX => '/I',
LINK => 'tautan',
LINKCOM => '%LINK %LDFLAGS /keluar:%> %< %_LDIRS %LIBS',
LINKMODULECOM => '%LD /r /o %> %<',
LIBDIRPREFIX => '/LIBPATH:',
AR => 'lib',
ARFLAGS => '/nologo ',
ARCOM => "%AR %ARFLAGS /keluar:%> %<",
RANLIB => '',
LD => 'tautan',
LDFLAGS => '/nologo ',
PREFLIB => '',
SUFEXE => '.exe',
SUFLIB => '.lib',
SUFLIBS => '.dll:.lib',
SUFOBJ => '.obj',

Variabel-variabel ini digunakan oleh berbagai metode yang terkait dengan lingkungan, dalam
tertentu metode apa pun yang pada akhirnya memanggil perintah eksternal akan menggantikan ini
variabel ke dalam perintah akhir, yang sesuai. Misalnya, metode `Objek' mengambil
sejumlah file sumber dan mengatur untuk memperoleh, jika perlu, objek yang sesuai
file. Sebagai contoh:

Objek $env 'foo.c', 'bar.c';

Ini akan mengatur untuk menghasilkan, jika perlu, foo.o dan bar.o. Perintah yang dipanggil hanyalah
`%CCCOM', yang diperluas melalui substitusi, ke perintah eksternal yang sesuai yang diperlukan
untuk membangun setiap objek. Kami akan mengeksplorasi aturan substitusi lebih lanjut di bawah `Perintah'
metode, di bawah ini.

Variabel konstruksi juga digunakan untuk tujuan lain. Misalnya, `CPPPATH' adalah
digunakan untuk menentukan jalur direktori include yang dipisahkan titik dua. Ini dimaksudkan untuk menjadi
diteruskan ke preprosesor C dan juga digunakan oleh mesin pemindaian file-C untuk
menentukan dependensi yang terlibat dalam Kompilasi C. Variabel yang diawali dengan
garis bawah, dibuat dengan berbagai metode, dan biasanya harus dianggap ``internal''
variabel. Misalnya, ketika sebuah metode dipanggil yang memanggil pembuatan objek
dari sumber C, variabel `_IFLAGS' dibuat: ini sesuai dengan sakelar `-I'
diperlukan oleh kompiler C untuk mewakili direktori yang ditentukan oleh `CPPPATH'.

Perhatikan bahwa, untuk lingkungan tertentu, nilai variabel ditetapkan satu kali, dan kemudian
jangan pernah mengatur ulang (untuk mengubah variabel, Anda harus membuat lingkungan baru. Metode disediakan
untuk menyalin lingkungan yang ada untuk tujuan ini). Beberapa variabel internal, seperti
`_IFLAGS' dibuat sesuai permintaan, tetapi setelah disetel, mereka tetap tetap selama masa pakai
lingkungan.

Variabel `CFLAGS', `LDFLAGS', dan `ARFLAGS' semuanya menyediakan tempat untuk meneruskan opsi ke
compiler, loader, dan pengarsip, masing-masing. Kurang jelas, `INCDIRPREFIX'
variabel menentukan string opsi yang akan ditambahkan ke awal setiap include
direktori sehingga kompiler tahu di mana menemukannya .h file. Demikian pula,
Variabel `LIBDIRPREFIX' menentukan string opsi yang akan ditambahkan ke awal
setiap direktori yang harus dicari oleh penaut untuk perpustakaan.

Variabel lain, `ENV', digunakan untuk menentukan lingkungan sistem selama eksekusi
dari perintah eksternal. Secara default, satu-satunya variabel lingkungan yang disetel adalah `PATH',
yang merupakan jalur eksekusi untuk perintah UNIX. Untuk reproduktifitas maksimal, Anda harus
benar-benar mengatur untuk mengatur jalur eksekusi Anda sendiri, di tingkat atas Anda Membangun berkas (atau
mungkin dengan mengimpor paket konstruksi yang sesuai dengan perintah Perl `use'). NS
variabel default dimaksudkan untuk membuat Anda keluar dari tanah.

Interpolasi konstruksi variabel

Variabel lingkungan konstruksi dapat diinterpolasi dalam nama file sumber dan target
dengan mengawali nama variabel konstruksi dengan `%'.

$env = kontra baru(
DESTDIR => 'program',
SRCDIR => 'src',
);
Program $env '%DESTDIR/hello', '%SRCDIR/hello.c';

Perluasan variabel konstruksi bersifat rekursif--yaitu, file nama(s) akan kembali
diperluas sampai tidak ada lagi substitusi yang dapat dilakukan. Jika variabel konstruksi tidak
didefinisikan di lingkungan, maka string nol akan diganti.

Default konstruksi metode


Daftar metode konstruksi default meliputi berikut ini:

Grafik `baru' pembina

Metode 'baru' adalah konstruktor objek Perl. Artinya, itu tidak dipanggil melalui referensi
ke lingkungan konstruksi yang ada referensi, tapi, agak statis, menggunakan nama
dari Perl paket di mana konstruktor didefinisikan. Metode ini dipanggil seperti ini:

$env = kontra baru( );

Lingkungan yang Anda dapatkan kembali diberkati ke dalam paket `kontra', yang berarti akan
telah mengaitkannya dengan metode default yang dijelaskan di bawah ini. Konstruksi individu
variabel dapat ditimpa dengan memberikan pasangan nama/nilai dalam daftar penimpaan. Perhatikan bahwa
untuk mengganti variabel lingkungan perintah apa pun (yaitu apa pun di bawah `ENV'), Anda harus
menimpa mereka semua. Anda dapat mengatasi kesulitan ini dengan menggunakan metode `salin' di
lingkungan konstruksi yang ada.

Grafik `kloning' metode

Metode `kloning' membuat tiruan dari lingkungan konstruksi yang ada, dan dapat
disebut seperti pada contoh berikut:

$env2 = $env1->klon( );

Anda dapat memberikan penggantian dengan cara biasa untuk membuat lingkungan yang berbeda dari
asli. Jika Anda hanya menginginkan nama baru untuk lingkungan yang sama (yang mungkin berguna ketika
mengekspor lingkungan ke komponen yang ada), Anda bisa menggunakan tugas sederhana.

Grafik `salin' metode

Metode `copy' mengekstrak variabel konstruksi yang ditentukan secara eksternal dari sebuah
lingkungan dan mengembalikannya sebagai daftar pasangan nama/nilai. Override juga bisa
asalkan, dalam hal ini, nilai yang diganti akan dikembalikan, sebagaimana mestinya. NS
daftar yang dikembalikan dapat ditetapkan ke hash, seperti yang ditunjukkan pada prototipe, di bawah, tetapi juga dapat
dimanipulasi dengan cara lain:

%env = $env1->salin( );

Nilai `ENV', yang merupakan hash, juga disalin ke hash baru, jadi ini mungkin
berubah tanpa takut mempengaruhi lingkungan aslinya. Jadi, misalnya, jika Anda benar-benar
ingin mengganti hanya variabel `PATH' di lingkungan default, Anda bisa melakukan
sebagai berikut:

%kontra = kontra baru()->copy();
$kontra{ENV}{PATH} = " ";
$kontra = kerugian baru(%kontra);

Ini akan meninggalkan hal lain yang mungkin ada di lingkungan eksekusi default
tak terganggu.

Grafik 'Instal' metode

Metode `Instal' mengatur file yang ditentukan untuk dipasang di tempat yang ditentukan
direktori. Instalasi dioptimalkan: file tidak disalin jika dapat ditautkan. Jika
ini bukan perilaku yang diinginkan, Anda harus menggunakan metode lain untuk menginstal
mengajukan. Disebut sebagai berikut:

Instal $env , ;

Perhatikan bahwa, sementara file yang akan diinstal dapat diberi nama secara sewenang-wenang, hanya yang terakhir
komponen dari setiap nama digunakan untuk nama target yang diinstal. Jadi, misalnya, jika Anda
mengatur untuk menginstal foo/bar in dasar, ini akan membuat bar file di dasar direktori (bukan
foo/bar).

Grafik 'Instal Sebagai' metode

Metode `InstallAs' mengatur sumber yang ditentukan fillet(s) untuk dipasang sebagai
target yang ditentukan fillet(S). Beberapa file harus ditentukan sebagai daftar file. NS
instalasi dioptimalkan: file tidak disalin jika dapat ditautkan. Jika ini bukan
perilaku yang diinginkan, Anda perlu menggunakan metode lain untuk menginstal file. Dia
disebut sebagai berikut:

`InstallAs' bekerja dalam dua cara:

Instal file tunggal:

Instal Sebagai $env TgtFile, SrcFile;

Beberapa file menginstal:

InstalAs $env ['tgt1', 'tgt2'], ['src1', 'src2'];

Atau, bahkan sebagai:

@srcs = qw(src1 src2 src3);
@tgts = qw(tgt1 tgt2 tgt3);
Instal Sebagai $env [@tgts], [@srcs];

Target dan daftar sumber harus sama panjangnya.

Grafik `Berharga' metode

Metode `Berharga' meminta kontra untuk tidak menghapus file atau daftar file yang ditentukan sebelumnya
membangun mereka lagi. Itu dipanggil sebagai:

Berharga ;

Ini sangat berguna untuk memungkinkan pembaruan tambahan ke perpustakaan atau debug
file informasi yang diperbarui daripada dibangun kembali setiap kali. Kontra akan tetap
hapus file ketika flag `-r' ditentukan.

Grafik `Perintah' metode

Metode `Command' adalah metode catchall yang dapat digunakan untuk mengatur eksternal apa pun
perintah yang akan dipanggil untuk memperbarui target. Untuk perintah ini, file target dan daftar
masukan disediakan. Selain itu, baris perintah konstruksi, atau baris, disediakan sebagai
string (string ini mungkin memiliki beberapa perintah yang disematkan di dalamnya, dipisahkan oleh yang baru
garis). 'Perintah' disebut sebagai berikut:

Perintah $env , , ;

Target dibuat tergantung pada daftar file input yang ditentukan, dan input harus
berhasil dibangun atau Kontra tidak akan berusaha membangun target.

Dalam perintah konstruksi, variabel apa pun dari lingkungan konstruksi mungkin
diperkenalkan dengan mengawali nama variabel konstruksi dengan `%'. Ini adalah rekursif:
perintah diperluas sampai tidak ada lagi penggantian yang dapat dilakukan. Jika sebuah konstruksi
variabel tidak didefinisikan di lingkungan, maka string nol akan diganti. A
dua kali lipat `%%' akan digantikan oleh satu `%' dalam perintah konstruksi.

Ada beberapa variabel semu yang juga akan diperluas:

%> Nama file target (dalam perintah multi-target, ini selalu menjadi target pertama
tersebut).

%0 Sama seperti `%>'.

%1, %2, ..., %9
Ini merujuk ke file input pertama hingga kesembilan.

%< Set input lengkap. Jika salah satu dari ini telah digunakan di tempat lain di
baris perintah saat ini (melalui `%1', `%2', dll.), maka itu akan dihapus dari
daftar disediakan oleh `%<'. Pertimbangkan perintah berikut yang ditemukan di a wajib militer fillet
dalam uji direktori:

Perintah $env 'tgt', qw(foo bar baz), qq(
echo %< -i %1 > %>
echo %< -i %2 >> %>
echo %< -i %3 >> %>
);

If tgt perlu diperbarui, maka ini akan menghasilkan eksekusi
mengikuti perintah, dengan asumsi bahwa tidak ada pemetaan ulang yang dibuat untuk uji
direktori:

tes gema/tes batang/baz -i tes/foo > tes/tgt
echo test/foo test/baz -i test/bar >> test/tgt
echo test/foo test/bar -i test/baz >> test/tgt

Salah satu dari variabel semu di atas dapat segera diikuti oleh salah satu dari berikut ini:
akhiran untuk memilih bagian dari nama jalur yang diperluas:

:a path absolut ke nama file
:b direktori ditambah nama file yang dihilangkan sufiksnya
:d direktori
:f nama file
:s akhiran nama file
:F nama file dilucuti dari sufiks apa pun

Melanjutkan contoh di atas, `%<:f' akan diperluas menjadi `foo bar baz', dan `%':d> akan
memperluas ke `test'.

Dimungkinkan untuk menulis ulang bagian dari perintah secara terprogram dengan melampirkan bagiannya
antara `%[' dan `%]'. Ini akan memanggil variabel konstruksi bernama sebagai kata pertama
terlampir dalam tanda kurung sebagai referensi kode Perl; hasil panggilan ini akan digunakan
untuk mengganti isi tanda kurung di baris perintah. Misalnya, diberikan
file input yang ada bernama tgt.in:

@kata kunci = qw(foo bar baz);
$env = new kontra(X_COMMA => sub { join(",", @_) });
Perintah $env 'tgt', 'tgt.in', qq(
echo '# Kata Kunci: %[X_COMMA @kata kunci %]' > %>
kucing %< >> %>
);

Ini akan mengeksekusi:

echo '# Kata kunci: foo,bar,baz' > tgt
kucing tgt.in >> tgt

Setelah substitusi terjadi, string ruang putih diubah menjadi kosong tunggal, dan
spasi putih di depan dan di belakang dihilangkan. Oleh karena itu tidak mungkin untuk memperkenalkan
panjang variabel spasi putih dalam string yang diteruskan ke perintah, tanpa menggunakan beberapa
semacam kutipan shell.

Jika string perintah multi-baris disediakan, perintah dijalankan secara berurutan. Jika ada
dari perintah gagal, maka tidak ada yang dieksekusi, dan target tidak ditandai sebagai
diperbarui, yaitu tanda tangan baru tidak disimpan untuk target.

Biasanya, jika semua perintah berhasil, dan mengembalikan status nol (atau platform-
indikasi keberhasilan yang spesifik diperlukan), maka tanda tangan baru disimpan untuk
target. Jika perintah salah melaporkan keberhasilan bahkan setelah kegagalan, maka Kontra akan
asumsikan bahwa file target yang dibuat oleh perintah itu akurat dan mutakhir.

Kata pertama dari setiap string perintah, setelah ekspansi, dianggap sebagai executable
perintah mencari pada variabel lingkungan `PATH' (yang, pada gilirannya, ditentukan oleh
variabel konstruksi `ENV'). Jika perintah ini ditemukan di jalan, maka target akan
bergantung padanya: karena itu perintah akan dibuat secara otomatis, jika perlu. Dia
mungkin untuk menulis perintah multi-bagian ke beberapa shell, dipisahkan oleh titik koma. Hanya
kata perintah pertama akan bergantung, jadi jika Anda menulis string perintah Anda
dengan cara ini, Anda harus secara eksplisit mengatur ketergantungan (dengan metode `Tergantung'), atau
pastikan bahwa perintah yang Anda gunakan adalah perintah sistem yang diharapkan
tersedia. Jika tidak tersedia, tentu saja Anda akan mendapatkan kesalahan.

Jika ada perintah (bahkan satu dalam perintah multi-baris) dimulai dengan `[perl]', sisanya
dari baris perintah itu akan dievaluasi oleh Perl yang sedang berjalan alih-alih bercabang oleh
kerang. Jika terjadi kesalahan dalam mengurai Perl atau jika ekspresi Perl mengembalikan 0 atau
undef, perintah akan dianggap gagal. Sebagai contoh, berikut ini adalah sederhana
perintah yang membuat file `foo' langsung dari Perl:

$env = kontra baru();
Perintah $env 'foo',
qq([perl] buka(FOO,'>foo');cetak FOO "hi\\n"; tutup(FOO); 1);

Perhatikan bahwa ketika perintah dijalankan, Anda berada dalam paket yang sama seperti ketika Membangun
or wajib militer file telah dibaca, sehingga Anda dapat memanggil fungsi Perl yang telah Anda definisikan dalam hal yang sama
Membangun or wajib militer file di mana `Command' muncul:

$env = kontra baru();
sub buat_file {
$file saya = shift;
buka(FILE, ">$file");
cetak FILE "hai\n";
tutup (FILE);
1 kembali;
}
Perintah $env 'foo', "[perl] &create_file('%>')";

String Perl akan digunakan untuk menghasilkan tanda tangan untuk file turunan, jadi jika Anda
ubah string, file akan dibangun kembali. Isi dari setiap subrutin yang Anda panggil,
namun, bukan bagian dari tanda tangan, jadi jika Anda memodifikasi subrutin yang dipanggil seperti
`create_file' di atas, target akan tidak dibangun kembali. Pengguna peringatan.

Kontra biasanya mencetak perintah sebelum menjalankannya. Perilaku ini ditekan jika
karakter pertama dari perintah adalah `@'. Perhatikan bahwa Anda mungkin perlu memisahkan `@' dari
nama perintah atau keluar darinya untuk mencegah `@cmd' terlihat seperti array untuk kutipan Perl
operator yang melakukan interpolasi:

# Baris perintah pertama salah,
# karena "@cp" terlihat seperti array
# ke fungsi Perl qq//.
# Gunakan formulir kedua sebagai gantinya.
Perintah $env 'foo', 'foo.in', qq(
@cp %< file temp
@ cp file temp %>
);

Jika ada karakter meta shell di mana saja di baris perintah yang diperluas, seperti `<',
`>', tanda kutip, atau titik koma, maka perintah tersebut akan benar-benar dijalankan dengan memanggil a
kerang. Ini berarti bahwa perintah seperti:

cd foo

saja biasanya akan gagal, karena tidak ada perintah `cd' di jalurnya. Tapi perintah
tali:

cd $<:d; tar cf $>:f $<:f

ketika diperluas masih akan berisi titik koma karakter meta shell, dan shell akan menjadi
dipanggil untuk menginterpretasikan perintah. Karena `cd' ditafsirkan oleh sub-kulit ini, perintah
akan dieksekusi seperti yang diharapkan.

Untuk menentukan perintah dengan beberapa target, Anda dapat menentukan referensi ke daftar
target. Di Perl, referensi daftar dapat dibuat dengan melampirkan daftar dalam tanda kurung siku.
Oleh karena itu perintah berikut:

Perintah $env ['foo.h', 'foo.c'], 'foo.template', q(
generasi %1
);

dapat digunakan dalam kasus di mana perintah `gen' membuat dua file, keduanya foo.h dan foo.c.

Grafik 'Objek' metode

Metode `Objek' mengatur untuk membuat file objek yang sesuai dengan yang ditentukan
file sumber. Itu dipanggil seperti yang ditunjukkan di bawah ini:

@files = Objek $env ;

Di bawah Unix, file sumber berakhiran .s dan .c saat ini didukung, dan akan dikompilasi
menjadi nama file yang sama berakhiran .o. Secara default, semua file dibuat dengan memanggil
perintah eksternal yang dihasilkan dari perluasan variabel konstruksi `CCCOM', dengan
`%<' dan `%>' masing-masing diatur ke file sumber dan objek (lihat metode `Command'
untuk rincian ekspansi). Variabel `CPPPATH' juga digunakan saat memindai file sumber
untuk dependensi. Ini adalah daftar nama path yang dipisahkan titik dua, dan juga digunakan untuk membuat
variabel konstruksi `_IFLAGS,' yang akan berisi daftar yang sesuai dari -`I'
pilihan untuk kompilasi. Setiap nama path relatif di `CPPPATH' ditafsirkan relatif
ke direktori tempat lingkungan konstruksi terkait dibuat (mutlak
dan nama relatif atas juga dapat digunakan). Variabel ini digunakan oleh `CCCOM'. Perilaku
dari perintah ini dapat dimodifikasi dengan mengubah salah satu variabel yang diinterpolasi
menjadi `CCCOM', seperti `CC', `CFLAGS', dan, secara tidak langsung, `CPPPATH'. Itu juga mungkin untuk
ganti nilai `CCCOM' itu sendiri. Untuk kenyamanan, file ini mengembalikan daftar
nama file objek.

Grafik `Program' metode

Metode `Program' mengatur untuk menghubungkan program yang ditentukan dengan objek yang ditentukan
file. Itu dipanggil dengan cara berikut:

Program $env , ;

Nama program akan memiliki nilai variabel konstruksi `SUFEXE' yang ditambahkan (oleh
default, `.exe' pada sistem Win32, tidak ada pada sistem Unix) jika akhiran belum
menyajikan.

File sumber dapat ditentukan sebagai pengganti file objek--metode `Objek' adalah
dipanggil untuk mengatur konversi semua file menjadi file objek, dan karenanya semua
pengamatan tentang metode `Objek', di atas, berlaku juga untuk metode ini.

Penautan program yang sebenarnya akan ditangani oleh perintah eksternal yang menghasilkan
dari memperluas variabel konstruksi `LINKCOM', dengan `%<' disetel ke file objek ke
ditautkan (dalam urutan yang disajikan), dan `%>' disetel ke target (lihat metode `Perintah'
untuk rincian ekspansi). Pengguna dapat mengatur variabel tambahan dalam konstruksi
lingkungan, termasuk `LINK', untuk menentukan program mana yang digunakan untuk menghubungkan, `LIBPATH', a
daftar jalur pencarian perpustakaan yang dipisahkan titik dua, untuk digunakan dengan spesifikasi perpustakaan dari
bentuk -libi, dan `LIBS', menentukan daftar pustaka yang akan ditautkan (dalam salah satu) -libi
bentuk atau hanya sebagai nama path. Nama path relatif di `LIBPATH' dan `LIBS' diinterpretasikan
relatif terhadap direktori tempat lingkungan konstruksi terkait dibuat
(nama absolut dan relatif atas juga dapat digunakan). Kontra secara otomatis mengatur
ketergantungan pada perpustakaan apa pun yang disebutkan dalam `LIBS': perpustakaan itu akan dibangun sebelumnya
perintah ditautkan.

Grafik `Perpustakaan' metode

Metode `Library' mengatur untuk membuat perpustakaan yang ditentukan dari objek yang ditentukan
file. Ini dipanggil sebagai berikut:

Perpustakaan $env , ;

Nama perpustakaan akan memiliki nilai variabel konstruksi `SUFLIB' yang ditambahkan (oleh
default, `.lib' pada sistem Win32, `.a' pada sistem Unix) jika akhiran belum
menyajikan.

File sumber dapat ditentukan sebagai pengganti file objek--metode `Objek' adalah
dipanggil untuk mengatur konversi semua file menjadi file objek, dan karenanya semua
pengamatan tentang metode `Objek', di atas, berlaku juga untuk metode ini.

Pembuatan perpustakaan yang sebenarnya akan ditangani oleh perintah eksternal yang menghasilkan
dari memperluas variabel konstruksi `ARCOM', dengan `%<' disetel ke anggota perpustakaan (dalam
urutan yang disajikan), dan `%>' ke perpustakaan yang akan dibuat (lihat metode `Perintah' untuk
rincian ekspansi). Pengguna dapat mengatur variabel dalam lingkungan konstruksi yang akan
mempengaruhi operasi perintah. Ini termasuk `AR', program arsip yang akan digunakan,
`ARFLAGS', yang dapat digunakan untuk memodifikasi flag yang diberikan ke program yang ditentukan oleh `AR',
dan `RANLIB', nama program pembuatan indeks arsip, jika diperlukan (jika
kebutuhan tidak memerlukan fungsi yang terakhir, maka `ARCOM' harus didefinisikan ulang untuk tidak
referensi `RANLIB').

Metode `Library' memungkinkan library yang sama ditentukan dalam beberapa metode
doa. Semua objek yang berkontribusi dari semua doa (yang mungkin berasal dari
direktori yang berbeda) digabungkan dan dihasilkan oleh satu perintah arsip. Catatan,
namun, jika Anda memangkas build sehingga hanya sebagian dari library yang ditentukan, maka hanya
bagian perpustakaan itu akan dihasilkan (sisanya akan hilang!).

Grafik `Modul' metode

Metode `Modul' adalah kombinasi dari metode `Program' dan `Perintah'. Daripada
menghasilkan program yang dapat dieksekusi secara langsung, perintah ini memungkinkan Anda untuk menentukan sendiri
perintah untuk benar-benar menghasilkan modul. Metode ini dipanggil sebagai berikut:

Modul $env , , ;

Perintah ini berguna dalam kasus di mana Anda ingin membuat, misalnya, secara dinamis
modul yang dimuat, atau pustaka kode yang ditautkan secara statis.

Grafik 'Tergantung' metode

Metode `Tergantung' memungkinkan Anda menentukan dependensi tambahan untuk target. Dia
dipanggil sebagai berikut:

Tergantung $env , ;

Ini mungkin kadang-kadang berguna, terutama dalam kasus di mana tidak ada pemindai (atau tidak ada pemindai).
dapat ditulis) untuk jenis file tertentu. Biasanya, dependensi dihitung
secara otomatis dari kombinasi dependensi eksplisit yang diatur oleh metode
doa atau dengan memindai file sumber.

Satu set dependensi identik untuk beberapa target dapat ditentukan menggunakan referensi ke
daftar target. Di Perl, referensi daftar dapat dibuat dengan melampirkan daftar di kotak
kurung. Oleh karena itu perintah berikut:

Tergantung $env ['foo', 'bar'], 'input_file_1', 'input_file_2';

menentukan bahwa kedua foo dan bar file tergantung pada file input yang terdaftar.

Grafik 'abaikan' metode

Metode `Ignore' memungkinkan Anda untuk mengabaikan dependensi eksplisit yang disimpulkan oleh Cons
memiliki. Ini dipanggil sebagai berikut:

Mengabaikan ;

Ini dapat digunakan untuk menghindari kompilasi ulang karena perubahan dalam file header sistem atau
utilitas yang diketahui tidak mempengaruhi target yang dihasilkan.

Jika, misalnya, sebuah program dibangun di direktori yang dipasang NFS pada banyak sistem yang
memiliki salinan yang berbeda dari stdio.h, perbedaan akan mempengaruhi tanda tangan semua
target turunan yang dibuat dari file sumber yang `#include '. Ini akan menyebabkan semua
target yang akan dibangun kembali saat mengubah sistem. Jika ini bukan perilaku yang diinginkan,
maka baris berikut akan menghapus dependensi pada stdio.h File:

Abaikan '^/usr/include/stdio\.h$';

Perhatikan bahwa argumen ke metode `Abaikan' adalah ekspresi reguler, sangat istimewa
karakter harus diloloskan dan Anda mungkin ingin menambatkan awal atau akhir dari
ekspresi dengan karakter `^' atau `$'.

Grafik 'garam' metode

Metode `Salt' menambahkan nilai konstan ke perhitungan tanda tangan untuk setiap turunan
mengajukan. Ini dipanggil sebagai berikut:

garam $string;

Mengubah nilai Salt akan memaksa pembangunan kembali lengkap dari setiap file turunan. Ini bisa jadi
digunakan untuk memaksa membangun kembali dalam keadaan tertentu yang diinginkan. Sebagai contoh,

Garam `uname -s`;

Akan memaksa pembangunan kembali lengkap dari setiap file turunan setiap kali sistem operasi aktif
di mana pembangunan dilakukan (seperti yang dilaporkan oleh `uname -s') berubah.

Grafik 'Gunakan Cache' metode

Metode `UseCache' menginstruksikan Kontra untuk memelihara cache file turunan, untuk dibagikan
di antara pohon bangunan terpisah dari proyek yang sama.

GunakanCache("tembolok/ ") warn("direktori cache tidak ditemukan");

Grafik `Jalur Sumber' metode

Mathod `SourcePath' mengembalikan nama jalur sumber sebenarnya dari sebuah file, seperti yang berlawanan dengan
nama jalur dalam direktori build. Ini dipanggil sebagai berikut:

$path = SourcePath ;

Grafik `KontraJalan' metode

Metode `ConsPath' mengembalikan nilai true jika jalur yang disediakan adalah file turunan, dan mengembalikan
undef (salah) sebaliknya. Ini dipanggil sebagai berikut:

$hasil = ConsPath ;

Grafik `Jalur Terpisah' metode

Metode `SplitPath' mencari beberapa nama jalur dalam string yang dipisahkan secara default
pemisah jalur untuk sistem operasi (':' pada sistem UNIX, ';' pada Windows NT), dan
mengembalikan nama yang sepenuhnya memenuhi syarat. Ini dipanggil sebagai berikut:

@jalur = SplitPath ;

Metode `SplitPath' akan mengonversi nama yang diawali '#' ke build tingkat atas yang sesuai
name (tanpa '#') dan akan mengonversi nama relatif menjadi nama tingkat atas.

Grafik `Jalan Dir' metode

Metode `DirPath' mengembalikan jalur pembangunan nama(s) dari direktori atau daftar direktori.
Ini dipanggil sebagai berikut:

$cwd = DirPath ;

Penggunaan paling umum untuk metode `DirPath' adalah:

$cwd = DirPath '.';

untuk mengambil jalur ke direktori anak perusahaan saat ini wajib militer file.

Grafik `Jalur File' metode

Metode `FilePath' mengembalikan jalur pembangunan nama(s) dari file atau daftar file. Dia
dipanggil sebagai berikut:

$file = FilePath ;

Grafik `Bantuan' metode

Metode `Help' menentukan teks bantuan yang akan ditampilkan ketika pengguna memanggil `cons
-H'. Ini dapat digunakan untuk menyediakan dokumentasi target spesifik, nilai, build
opsi, dll. untuk pohon build. Ini dipanggil sebagai berikut:

Membantu ;

Metode `Bantuan' hanya dapat dipanggil sekali, dan biasanya harus ditentukan di bagian atas
tingkat Membangun file.

Memperluas Kekurangan


Utama konstruksi variabel

Ada beberapa cara untuk memperluas Kontra, yang tingkat kesulitannya bervariasi. Yang paling sederhana
metode adalah untuk menentukan lingkungan konstruksi Anda sendiri, berdasarkan lingkungan default,
tetapi dimodifikasi untuk mencerminkan kebutuhan khusus Anda. Ini sering kali cukup untuk berbasis-C
aplikasi. Anda dapat menggunakan konstruktor `baru', dan metode `kloning' dan `salin' untuk
menciptakan lingkungan hibrida. Perubahan ini dapat sepenuhnya transparan pada dasarnya
wajib militer file.

Menambahkan yang baru metode

Untuk perubahan yang sedikit lebih menuntut, Anda mungkin ingin menambahkan metode baru ke `kontra'
kemasan. Berikut adalah contoh ekstensi yang sangat sederhana, `InstallScript', yang menginstal a
tcl skrip di lokasi yang diminta, tetapi mengedit skrip terlebih dahulu untuk mencerminkan platform-
jalur dependen yang perlu diinstal dalam skrip:

# kontra::InstallScript - Buat versi shell yang bergantung pada platform
# script dengan mengganti string ``#!your-path-here'' dengan platform tertentu
# jalur $BIN_DIR.

sub kontra::InstallScript {
saya ($env, $dst, $src) = @_;
Perintah $env $dst, $src, qq(
sed s+jalan-Anda-sini+$BIN_DIR+ %< > %>
chmod oug+x %>
);
}

Perhatikan bahwa metode ini didefinisikan secara langsung dalam paket `kontra' (dengan mengawali nama
dengan `kontra::'). Perubahan yang dibuat dengan cara ini akan terlihat secara global di semua lingkungan,
dan dapat disebut seperti pada contoh berikut:

InstallScript $env "$BIN/foo", "foo.tcl";

Untuk perbaikan kecil secara umum, variabel `BINDIR' dapat diteruskan sebagai
argumen atau diambil dari lingkungan konstruksi--sebagai `%BINDIR'.

Utama metode

Alih-alih menambahkan metode ke ruang nama `kontra', Anda dapat mendefinisikan paket baru
yang mewarisi metode yang ada dari paket `kontra' dan menimpa atau menambahkan yang lain. Ini
dapat dilakukan dengan menggunakan mekanisme pewarisan Perl.

Contoh berikut mendefinisikan paket baru `cons::switch' yang menggantikan standar
Metode 'Perpustakaan'. Metode yang diganti membangun modul perpustakaan yang ditautkan, bukan perpustakaan
arsip. Konstruktor baru disediakan. Lingkungan yang dibuat dengan konstruktor ini akan
memiliki metode perpustakaan baru; yang lain tidak.

paket kontra::beralih;
MULAI {@ISA = 'kontra'}

sub baru {
menggeser;
memberkati kontra baru(@_);
}

sub Perpustakaan {
saya($env) = pergeseran;
saya($lib) = shift;
my(@objs) = Objek $env @_;
Perintah $env $lib, @objs, q(
%LD -r %LDFLAGS %< -o %>
);
}

Fungsionalitas ini dapat dipanggil seperti dalam contoh berikut:

$env = kontra baru::switch(@overrides);
...
Pustaka $env 'lib.o', 'foo.c', 'bar.c';

Memohon Kekurangan


Perintah `cons' biasanya dipanggil dari akar pohon build. A Membangun fillet
harus ada di direktori itu. Jika argumen `-f' digunakan, maka alternatif Membangun
file dapat digunakan (dan, mungkin, root alternatif, karena `kontra' akan cd ke Membangun
direktori yang berisi file).

Jika `kontra' dipanggil dari anak akar pohon pembangunan dengan argumen `-t', itu
akan menaiki hierarki direktori mencari a Membangun mengajukan. (Nama alternatif mungkin
masih ditentukan dengan `-f'.) Target yang diberikan pada baris perintah akan dimodifikasi
menjadi relatif terhadap yang ditemukan Membangun mengajukan. Misalnya, dari direktori yang berisi
tingkat atas Membangun file, doa berikut:

% cd libfoo/subdir
% kontra -t target

persis sama dengan:

% kontra libfoo/subdir/target

Jika ada target `Default' yang ditentukan dalam hierarki direktori Membangun or
wajib militer file, hanya target default pada atau di bawah direktori dari mana `cons -t'
dipanggil akan dibangun.

Perintah dipanggil sebagai berikut:

kontra --

dimana argumen dapat berupa salah satu dari berikut ini, dalam urutan apa pun:

target Membangun target yang ditentukan. Jika target adalah direktori, lalu membangun secara rekursif
segala sesuatu dalam direktori itu.

+pola Batasi wajib militer file yang dianggap hanya yang cocok belt hold, Yang
ekspresi reguler Perl. Beberapa argumen `+' diterima.

nama=
set nama untuk menilai val di hash `ARG' diteruskan ke tingkat atas Membangun file.

`-cc' Tampilkan perintah yang akan dieksekusi, saat mengambil dari cache. Tidak
indikasi bahwa file telah diambil diberikan; ini berguna untuk
menghasilkan log build yang dapat dibandingkan dengan log build nyata.

`-cd' Nonaktifkan semua cache. Jangan mengambil dari cache atau menyiram ke cache.

`-cr' Membangun dependensi dalam urutan acak. Ini berguna saat membangun banyak
pohon serupa dengan caching diaktifkan.

`-cs' Menyinkronkan target build yang ada yang ditemukan up-to-date dengan cache.
Ini berguna jika caching telah dinonaktifkan dengan -cc atau baru saja diaktifkan
dengan UseCache.

`-d' Aktifkan debugging ketergantungan.

`-f'
Gunakan file yang ditentukan alih-alih Membangun (tapi pertama-tama ubah menjadi mengandung
direktori dari fillet).

`-h' Tampilkan pesan bantuan lokal ke build saat ini jika salah satunya sudah ditentukan, dan keluar.

`-k' Terus berjalan sejauh mungkin setelah kesalahan.

`-o'
Baca file timpa fillet.

`-p' Tampilkan produk konstruksi di pohon tertentu. Tidak ada build yang dicoba.

`-pa' Tampilkan produk konstruksi dan tindakan terkait. Tidak ada build yang dicoba.

`-pw' Menampilkan produk dan di mana mereka didefinisikan. Tidak ada build yang dicoba.

`-q' Jangan bertele-tele tentang Memasang dan Menghapus target.

`-r' Hapus produk konstruksi yang terkait dengan . Tidak ada build yang dicoba.

`-R'
Cari file di sisa. Beberapa -R sisa direktori dicari di
pesanan yang ditentukan.

`-t' Melintasi hierarki direktori mencari a Membangun file, jika tidak ada
di direktori saat ini. Target akan dimodifikasi menjadi relatif terhadap
Membangun file.

`-v' Tampilkan versi `kontra' dan lanjutkan pemrosesan.

`-V' Tampilkan versi `kontra' dan keluar.

`-wf'
Tulis semua nama file yang dipertimbangkan menjadi fillet.

`-x' Tampilkan pesan bantuan yang mirip dengan yang ini, dan keluar.

Dan konstruksi-args dapat berupa argumen apa pun yang ingin Anda proses di Membangun file.
Perhatikan bahwa harus ada -- memisahkan argumen kontra dan argumen yang Anda
ingin diproses di Membangun file.

Pemrosesan konstruksi-args dapat dilakukan dengan paket standar apa pun seperti getopt atau yang
varian, atau paket yang ditentukan pengguna. kontra akan lulus di konstruksi-args as @ARGV dan
tidak akan mencoba menafsirkan apa pun setelah --.

% kontra -R /usr/local/repository -d os=solaris +driver -- -c test -f DEBUG

akan meneruskan yang berikut ke kontra

-R /usr/local/repositori -d os=solaris +driver

dan berikut ini, ke tingkat atas Membangun file sebagai @ARGV

-c tes -f DEBUG

Perhatikan bahwa `kontra -r .' setara dengan `make clean' rekursif penuh, tetapi tidak memerlukan
dukungan dalam Membangun file atau apapun wajib militer file. Ini paling berguna jika Anda
kompilasi file ke dalam direktori sumber (jika Anda memisahkan membangun dan ekspor direktori,
maka Anda bisa menghapus direktori).

Pilihan `-p', `-pa', dan `-pw' sangat berguna untuk digunakan sebagai bantuan dalam membaca
skrip atau men-debug mereka. Jika Anda ingin tahu skrip apa yang diinstal ekspor/sertakan/foo.h,
misalnya, cukup ketik:

% kontra -pw export/include/foo.h

Menggunakan dan penulisan ketergantungan scanner


QuickScan memungkinkan pemindai target-independen sederhana untuk diatur untuk file sumber. Hanya
satu pemindai QuickScan dapat dikaitkan dengan file sumber dan lingkungan apa pun.

QuickScan dipanggil sebagai berikut:

QuickScan CONSENV CODEREF, NAMA FILE [, PATH]

Subrutin yang dirujuk oleh CODEREF diharapkan mengembalikan daftar nama file yang disertakan
langsung oleh FILE. Nama file ini, pada gilirannya, akan dipindai. Argumen PATH opsional
menyediakan jalur pencarian untuk menemukan FILENAME dan/atau file yang dikembalikan oleh pengguna yang disediakan
subrutin. PATH dapat berupa referensi ke array nama direktori pencarian, atau a
string nama yang dipisahkan oleh karakter pemisah sistem (':' pada sistem UNIX, ';' pada
WindowsNT).

Subrutin dipanggil sekali untuk setiap baris dalam file, dengan $_ disetel ke baris saat ini.
Jika subrutin perlu melihat baris tambahan, atau, dalam hal ini, seluruh file,
maka ia dapat membacanya sendiri, dari filehandle SCAN. Itu juga dapat mengakhiri loop, jika
ia mengetahui bahwa tidak ada informasi penyertaan lebih lanjut yang tersedia, dengan menutup pegangan file.

Apakah jalur pencarian disediakan atau tidak, QuickScan pertama-tama mencoba mencari file
relatif terhadap direktori saat ini (untuk file tingkat atas yang dipasok langsung ke QuickScan),
atau dari direktori yang berisi file yang mereferensikan file tersebut. Ini tidak terlalu
umum, tetapi tampaknya cukup baik--terutama jika Anda memiliki kemewahan menulis sendiri
utilitas dan dapat mengontrol penggunaan jalur pencarian dengan cara standar. Akhirnya,
jalur pencarian, saat ini, dipisahkan titik dua. Ini mungkin tidak membuat kubu NT senang.

Berikut adalah contoh nyata, diambil dari Membangun berkas di sini:

sub kontra::SMFgen {
saya($env, @tabel) = @_;
foreach $t (@tabel) {
$env->QuickScan(sub { /\b\S*?\.smf\b/g }, "$t.smf",
$env->{SMF_INCLUDE_PATH});
$env->Perintah(
["$t.smdb.cc","$t.smdb.h","$t.snmp.cc","$t.ami.cc", "$t.http.cc"],
"$t.smf",
q(
smfgen %( %SMF_INCLUDE_OPT %) %
)
);
}
}

[CATATAN bahwa formulir `$env->QuickScan ...' dan `$env->Command ...' tidak boleh
diperlukan, tetapi, untuk beberapa alasan, diperlukan untuk permintaan khusus ini. Ini muncul
menjadi bug di Perl atau kesalahpahaman di pihak saya; gaya doa ini tidak
tampaknya selalu diperlukan.]

Ini menemukan semua nama formulir .smf dalam file. Itu akan mengembalikan nama bahkan jika
mereka ditemukan di dalam komentar, tapi tidak apa-apa (mekanismenya memaafkan file tambahan;
mereka hanya diabaikan dengan asumsi bahwa file yang hilang akan diperhatikan ketika
program, dalam contoh ini, smfgen, sebenarnya dipanggil).

Pemindai hanya dipanggil untuk file sumber yang diberikan jika diperlukan oleh beberapa target di
pohon. Itu hanya pernah dipanggil sekali untuk file sumber yang diberikan.

Berikut adalah cara lain untuk membuat pemindai yang sama. Yang ini menggunakan referensi kode eksplisit,
dan juga (tidak perlu, dalam hal ini) membaca seluruh file itu sendiri:

sub pemindaian saya {
saya(@termasuk);
lakukan {
push(@termasuk, /\b\S*?\.smf\b/g);
} ketika ;
@termasuk
}

Perhatikan bahwa urutan loop dibalik, dengan tes loop di akhir. Ini adalah
karena baris pertama sudah dibacakan untuk Anda. Pemindai ini dapat dilampirkan ke sumber
mengajukan oleh:

QuickScan $env \myscan, "$_.smf";

SUPPORT DAN SARAN


Kontra dikelola oleh komunitas pengguna. Untuk berlangganan, kirim email ke kontra-diskusi-
[email dilindungi] dengan tubuh berlangganan.

Silakan laporkan saran apa pun melalui [email dilindungi] milis.

Gunakan kontra online menggunakan layanan onworks.net


Server & Workstation Gratis

Unduh aplikasi Windows & Linux

  • 1
    turkdevops
    turkdevops
    TurkDevOps a ?k kaynak yaz?l?m
    geli?tirici topluluklar? DevTurks-Tim
    Taraf?ndan desteklenmektedir..
    Fitur: https://github.com/turkdevops https://turkdevops.g...
    Unduh turkdevops.dll
  • 2
    asammdf
    asammdf
    *asammdf* adalah pengurai Python yang cepat dan
    editor untuk ASAM (Asosiasi untuk
    Standarisasi Otomasi dan
    Sistem Pengukuran) MDF / MF4
    (Format Data Pengukuran...
    Unduh asammdf.dll
  • 3
    LAME (Lame Bukan Encoder MP3)
    LAME (Lame Bukan Encoder MP3)
    LAME adalah alat pendidikan yang akan digunakan
    untuk belajar tentang pengkodean MP3. Itu
    tujuan dari proyek LAME adalah untuk meningkatkan
    akustik psiko, kualitas dan kecepatan
    dari MP...
    Unduh LAME (Lame Aint an MP3 Encoder)
  • 4
    wxPython
    wxPython
    Satu set modul ekstensi Python yang
    bungkus kelas GUI lintas platform dari
    wxWidgets.. Pemirsa: Pengembang. Pengguna
    antarmuka: Sistem X Window (X11), Win32 ...
    Unduh wxPython.dll
  • 5
    manajer file paket
    manajer file paket
    Ini adalah pengelola file paket Total War
    proyek, mulai dari versi 1.7. SEBUAH
    pengenalan singkat ke Warscape
    modifikasi: ...
    Unduh packfilemanager.dll
  • 6
    IPerf2
    IPerf2
    Alat lalu lintas jaringan untuk mengukur
    Kinerja TCP dan UDP dengan metrik
    sekitar throughput dan latency. NS
    tujuan termasuk mempertahankan aktif
    kod iperf...
    Unduh IPerf2.dll
  • Lebih banyak lagi »

Perintah Linux

Ad