Selamat siang, Habr!
Hari ini saya ingin berbagi pengalaman pengembangan saya untuk komputer mini di linux (RPI, BBB dan lainnya) dalam bahasa pemrograman D. Di bawah luka, instruksi lengkap tentang cara melakukan ini tanpa rasa sakit. Ya, atau hampir ... =)

Mengapa d?
Ketika di tempat kerja tugasnya adalah menulis sistem pemantauan untuk ARM, bahkan sebagai penggemar berat D, saya ragu apakah itu harus diambil sebagai alat utama. Secara umum, saya bukan orang yang aneh, dan saya telah berada di D untuk waktu yang lama, jadi saya pikir itu patut dicoba dan ... tidak semuanya begitu sederhana. Di satu sisi, tidak ada masalah khusus (kecuali satu yang tidak sepenuhnya jelas yang tersisa dengan kedatangan versi baru dari kompiler), di sisi lain, orang yang sedang mengembangkan ARM dapat terus-menerus berpikir bahwa toolkit tidak siap dari kata sama sekali. Terserah Anda.
Toolkit
Saya dapat menyarankan Visual Studio Code
dengan plugin D Programming Language
dari kawan. WebFreak (Jan Jurzitza). Di pengaturan, Anda dapat mengatur pengaturan Beta Stream
untuk selalu memiliki versi terbaru dari serve-d
. Plugin itu sendiri menginstal perangkat lunak yang diperlukan.
Struktur umum proyek
Secara umum, ternyata cukup membingungkan (dibandingkan dengan proyek yang biasa pada D), tetapi, menurut saya, itu cukup fleksibel dan nyaman.
. ├── arm-lib/ | ├── libcrypto.a | ├── libssl.a | └── libz.a ├── docker-ctx/ | ├── Dockerfile | └── entry.sh ├── source | └── app.d ├── .gitignore ├── build-docker ├── ddb ├── dub.sdl ├── ldc └── makefile
arm-lib
- perpustakaan yang diperlukan agar aplikasi kita dapat berfungsi (dikompilasi di bawah lengan)
docker-ctx
- konteks untuk merakit gambar buruh pelabuhan
entry.sh
- akan melakukan beberapa tindakan tentang setiap peluncuran wadah nanti, tentang yang nanti
dub.sdl
- file proyek dalam D, memungkinkan Anda untuk memasukkan perpustakaan pihak ketiga dan banyak lagi
build-docker
- skrip pembuatan wadah (dasarnya 1 baris, tapi tetap saja)
ddb
- buruh pelabuhan D pembangun - skrip peluncuran wadah (juga satu baris, tetapi sebenarnya lebih nyaman)
ldc
- skrip yang memungkinkan Anda memanggil ldc dengan semua parameter yang diperlukan
makefile
- berisi resep buatan untuk arm dan x86 dan tindakan tambahan
source/app.d
- sumber proyek
Beberapa kata tentang arm-lib
.
Ada file yang diperlukan agar vibe berfungsi. Menambahkan file biner ke repositori adalah bentuk yang buruk. Tetapi di sini, untuk menyederhanakan hidup Anda, lebih mudah untuk melakukan hal itu. Anda dapat menambahkannya di dalam wadah, tetapi kemudian untuk sepenuhnya membentuk resep perakitan wadah, Anda harus menyimpan folder arm-lib
di dockert-ctx
. Rasa dan warnanya ...
Algoritma perakitan umum
./ddb make
ddb
memulai wadah, menjalankan skrip entry.sh
entry.sh
mengkonfigurasi dub
sedikit sehingga menggunakan folder perpustakaan di dalam wadah, yang akan berlokasi di direktori saat ini, yang akan memungkinkan Anda untuk tidak memompa keluar dan mengumpulkan perpustakaan yang digunakan dalam proyek ketika Anda me-restart perakitanentry.sh
akhirnya melewati kontrol ke perintah input ( make
di kasus kami)make
pada gilirannya membaca makefile
- semua flag untuk kompilasi silang dan direktori build disimpan di
makefile
, saluran panggilan dub
dibentuk - ketika dipanggil ke
dub
skrip ldc
dari direktori saat ini diteruskan sebagai variabel kompilator dan lingkungan ditetapkan - pustaka runtime ditetapkan sebagai dependensi make-up di
makefile
, yang, jika hilang, dikumpulkan oleh ldc-build-runtime
- variabel diteruskan ke skrip
dub.sdl
dan ke parameter dub.sdl
Isi dari file utama
Dockerfile
Karena kami akan menulis di bawah RPI3, kami memilih gambar dari sistem dasar debian:stretch-slim
, di mana gcc-arm-linux-gnueabihf
menggunakan versi glibc
sama dengan distribusi raspbian resmi (ada masalah dengan fedora, di mana pengelola kompiler silang menggunakan versi glibc
terlalu baru untuk glibc
)
FROM debian:stretch-slim RUN apt-get update && apt-get install -y \ make cmake bash p7zip-full tar wget gpg xz-utils \ gcc-arm-linux-gnueabihf ca-certificates \ && apt-get autoremove -y && apt-get clean ARG ldcver=1.11.0 RUN wget -O /root/ldc.tar.xz https://github.com/ldc-developers/ldc/releases/download/v$ldcver/ldc2-$ldcver-linux-x86_64.tar.xz \ && tar xf /root/ldc.tar.xz -C /root/ && rm /root/ldc.tar.xz ENV PATH "/root/ldc2-$ldcver-linux-x86_64/bin:$PATH" ADD entry.sh /entry.sh RUN chmod +x /entry.sh WORKDIR /workdir ENTRYPOINT [ "/entry.sh" ]
ldc
kompiler ldc
dari github
, di mana ia dikompilasi berdasarkan llvm
saat ini.
entry.sh
#!/bin/bash if [ ! -d ".dpack" ]; then mkdir .dpack fi ln -s $(pwd)/.dpack /root/.dub exec $@
Semuanya sederhana di sini: jika tidak ada folder .dpack
, lalu buat, gunakan .dpack
untuk membuat tautan simbolis ke /root/.dub
.
Ini akan memungkinkan Anda untuk menyimpan paket yang diunduh oleh dub
di folder proyek.
build-docker, ddb, ldc
Ini adalah tiga file baris tunggal sederhana. Dua di antaranya adalah opsional, tetapi nyaman, tetapi ditulis untuk linux (bash). Untuk windows, Anda harus membuat file serupa pada skrip lokal atau menjalankannya dengan tangan.
build-docker
memulai build container (dipanggil sekali, hanya untuk linux):
#!/bin/bash docker build -t dcross docker-ctx
ddb
meluncurkan wadah untuk perakitan dan melewati parameter (hanya linux):
#!/bin/bash docker run -v `pwd`:/workdir -t --rm dcross $@
Harap dicatat bahwa nama wadah digunakan dcross
(nama itu sendiri tidak masalah, tetapi harus cocok di kedua file) dan perintah pwd
digunakan untuk Dockerfile
direktori saat ini di /workdir
(direktori tersebut ditentukan sebagai WORKDIR
di Dockerfile
) (dalam kemenangan, tampaknya, Anda perlu menggunakan %CD%
).
ldc
mulai ldc
, anehnya, saat menggunakan variabel lingkungan (hanya linux, tapi itu dimulai dalam wadah, sehingga tidak perlu diubah untuk membangun di bawah menang):
#!/bin/bash $LDC $LDC_FLAGS $@
dub.sdl
Sebagai contoh, ini akan sangat sederhana:
name "chw" description "Cross Hello World" license "MIT" targetType "executable" targetPath "$TP" dependency "vibe-d" version="~>0.8.4" dependency "vibe-d:tls" version="~>0.8.4" subConfiguration "vibe-d:tls" "openssl-1.1"
targetPath
diambil dari variabel lingkungan karena dub
tidak dapat menentukan bidang resep perakitan dengan platform (misalnya, lflags "-L.libs" platform="arm"
akan menambahkan bendera ke linker hanya ketika membangun di bawah lengan).
makefile
Dan inilah yang paling menarik. Bahkan, make
tidak digunakan untuk membangun seperti itu, ia memanggil dub
untuk ini, dan dub
sendiri memantau apa yang perlu dirakit ulang dan apa yang tidak. Tetapi dengan bantuan makefile
semua variabel lingkungan yang diperlukan terbentuk, perintah tambahan dieksekusi dalam kasus yang lebih kompleks (membangun perpustakaan di C, mengemas file pembaruan, dll.).
Isi makefile
lebih besar dari yang lain:
# arm arch = arm # target path -- , TP = build-$(arch) LDC_DFLAGS = -mtriple=armv7l-linux-gnueabihf -disable-inlining -mcpu=cortex-a8 # EMPTY := SPACE :=$(EMPTY) $(EMPTY) LDC_BRT_DFLAGS = $(subst $(SPACE),;,$(LDC_DFLAGS)) ifeq ($(force), y) # # , .. dub FORCE = --force else FORCE = endif ifeq ($(release), y) BUILD_TYPE = --build=release else BUILD_TYPE = endif DUB_FLAGS = build --parallel --compiler=./ldc $(FORCE) $(BUILD_TYPE) $(info DUB_FLAGS: $(DUB_FLAGS)) # LDC = ldc2 LDC_BRT = ldc-build-runtime # ldc, runtime ARM LDC_RT_DIR = .ldc-rt # gcc GCC = arm-linux-gnueabihf-gcc ifeq ($(arch), x86) LDC_FLAGS = else ifeq ($(arch), arm) LDC_FLAGS = $(LDC_DFLAGS) -LL./$(LDC_RT_DIR)/lib -LL./arm-lib -gcc=$(GCC) else $(error unknown arch) endif DUB = TP=$(TP) LDC=$(LDC) LDC_FLAGS="$(LDC_FLAGS)" dub $(DUB_FLAGS) # .PHONY: all clean rtlibs stat # all: rtlibs $(DUB) DRT_LIBS=$(addprefix $(LDC_RT_DIR)/lib/, libdruntime-ldc.a libdruntime-ldc-debug.a libphobos2-ldc.a libphobos2-ldc-debug.a) $(DRT_LIBS): CC=$(GCC) $(LDC_BRT) -j8 --dFlags="$(LDC_BRT_DFLAGS)" --buildDir=$(LDC_RT_DIR) \ --targetSystem="Linux;UNIX" BUILD_SHARED_LIBS=OFF # D runtime ARM rtlibs: $(DRT_LIBS) # stat: find source -name '*.d' | xargs wc -l clean: rm -rf $(TP) rm -rf .dub $(LDC_BRT) --buildDir=$(LDC_RT_DIR) --resetOnly
makefile
semacam itu memungkinkan Anda membangun sebuah proyek di bawah lengan dan x86 dengan hampir satu perintah:
./ddb make ./ddb make arch=x86 # x86 make arch=x86 # host ldc
File untuk arm masuk ke build-arm
, untuk x86 di build-x86
.
app.d
Nah, untuk hidangan pembuka, untuk gambaran lengkap, kode app.d
:
import vibe.core.core : runApplication; import vibe.http.server; void handleRequest(scope HTTPServerRequest req, scope HTTPServerResponse res) { if (req.path == "/") res.writeBody("Hello, World!", "text/plain"); } void main() { auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = ["::1", "0.0.0.0"]; auto l = listenHTTP(settings, &handleRequest); scope (exit) l.stopListening(); runApplication(); }
Semua orang sekarang membutuhkan web =)
Kesimpulan
Secara umum, semuanya tidak begitu rumit seperti yang terlihat pada pandangan pertama, hanya saja pendekatan universal belum siap. Secara pribadi, saya menghabiskan banyak waktu mencoba melakukan tanpa make
. Dengan dia, segalanya menjadi lebih sederhana dan lebih bervariasi.
Tetapi Anda perlu memahami bahwa D tidak Go, di D itu kebiasaan untuk menggunakan perpustakaan eksternal dan Anda perlu berhati-hati dengan versi mereka.
Cara termudah untuk mendapatkan perpustakaan untuk lengan adalah menyalinnya dari perangkat yang berfungsi.
Referensi
Berikut ini adalah kode sumbernya. Dalam repositori ini, komunitas berbahasa Rusia secara bertahap mengumpulkan informasi, contoh, tautan.
Ada informasi tambahan di sini, seperti bagaimana membangun untuk YoctoLinux.
Umpan berita dalam VK