Beetaversioon: sisu on enamasti terviklik ja avalikuks katsetamiseks valmis, kuid vajab veel tehnilist, keelelist ja kasutatavuse kontrolli.

Peatüki vaade

Linux/Unix/macOS käsurea kiirõpik

Praegu loed peatükki Kompileerimine ja käivitamine: shell, Python, C, C++, Go, Rust, Java, mis kuulub osasse Osa V: Arendus ja töövood.

Kompileerimine ja käivitamine: shell, Python, C, C++, Go, Rust, Java

Loogika

See peatükk ei ole mõeldud nende keelte õppimiseks, vaid ühe väga praktilise vahe mõistmiseks:

  • mõni fail käivitatakse tõlgendiga otse
  • mõni fail kompileeritakse kõigepealt teise vormi
  • mõni tulemus on natiivne binaar
  • mõni tulemus vajab eraldi käivituskeskkonda või virtuaalmasinat

See teema seob kokku:

  • shebang-rida ja käivitatavad skriptid
  • PATH-i ja käskude leidmise
  • Dockeri ja koostamistööriistad
  • LaTeX-i kompileerimise idee

Kiirülevaade

Eesmärk on mõista, miks eri keelte programmide käivitamine erineb: mõnda tõlgendatakse käivitamise ajal, mõni koostatakse enne eraldi artefaktiks.

Kuju või tööriistMilleksMida tavaliselt näed
tõlgendiga skriptkäivita lähtekood otseprogrammi väljund kohe
kompilaatortee lähtekoodist uus artefaktbinaar või koostamiskataloog
go build, cargojuhi koostamissamme tööriistagakoostamislogi ja väljundfailid
Javakompileeri ja käivita eri sammudena.class failid ja programmi väljund
süntaksi- või kompileerimisvigakäivitus peatub enne tulemustveateade enne programmi tööd

Tüüpilised algaja vead

  • arvatakse, et kõik lähtefailid on otse käivitatavad
  • aetakse segi koostamis- ja käivituskäsk
  • unustatakse vaadata, millised failid pärast koostamist tekkisid

Üks kiire võrdlustabel

KeelLähtefailTüüpiline käivitusMis tekib
Shellhello.shsh hello.sh või ./hello.shtavaliselt eraldi koostamisväljundit ei teki
Pythonhello.pypython3 hello.pylähtefail, mõnikord __pycache__
Chello.c./hello-c pärast kompileerimistnatiivne binaarfail
C++hello.cpp./hello-cpp pärast kompileerimistnatiivne binaarfail
Gohello.gogo run hello.go või ./hello-gonatiivne binaarfail
Rustsrc/main.rscargo run või binaarfail kataloogis target/natiivne binaarfail ja kataloog target/
JavaHello.javajava Hello.class fail, käivitus JVM-is

Shell: skript ja shebang

Shelli näide on kõige lihtsam, sest see on lihtsalt tekstifail, mida loeb shell.


cat > hello.sh <<'EOF'
#!/bin/sh
echo "Tere, maailm!"
echo "Tere, maailm!"
echo "Tere, maailm!"
EOF
chmod +x hello.sh
./hello.sh

Siin:

  • fail on tavaline tekstifail
  • chmod +x lubab selle käivitada
  • shebang #!/bin/sh ütleb, milline shell faili tõlgendab

Teine võimalus on:


sh hello.sh

Siis valid shelli käsurealt ise.

Python: tõlgendatud käivitus

Pythoni näide näeb välja samuti lihtne, aga erinevalt shellist käivitad sa tavaliselt faili Pythoni tõlgendiga.


cat > hello.py <<'EOF'
for _ in range(3):
    print("Tere, maailm!")
EOF
python3 hello.py

Siin:

  • lähtefail jääb tekstifailiks
  • python3 loeb selle sisse ja käivitab
  • tavaliselt ei teki kohe samas mõttes eraldi käivitatavat binaari

C: kompileeri binaariks

C on klassikaline näide keelest, kus lähtekood tuleb kõigepealt kompileerida.


cat > hello.c <<'EOF'
#include <stdio.h>

int main(void) {
    for (int i = 0; i < 3; i++) {
        puts("Tere, maailm!");
    }
    return 0;
}
EOF
cc hello.c -o hello-c
./hello-c

Siin:

  • hello.c on lähtefail
  • cc ... -o hello-c teeb sellest binaari
  • ./hello-c käivitab juba kompileeritud programmi

See on oluline vahe võrreldes shelli või Pythoniga: enne käivitamist tuleb ehitada eraldi käivitatav fail.

C++: sarnane C-ga, aga teise kompilaatoriga


cat > hello.cpp <<'EOF'
#include <iostream>

int main() {
    for (int i = 0; i < 3; i++) {
        std::cout << "Tere, maailm!" << std::endl;
    }
    return 0;
}
EOF
c++ hello.cpp -o hello-cpp
./hello-cpp

Loogika on sama nagu C puhul:

  • lähtekood
  • kompileerimine
  • binaar

Go: lihtne tee ühe binaarini

Go sobib käsureaõppeks hästi, sest koostamise loogika on lihtne.


cat > hello.go <<'EOF'
package main

import "fmt"

func main() {
    for i := 0; i < 3; i++ {
        fmt.Println("Tere, maailm!")
    }
}
EOF
go run hello.go
go build -o hello-go hello.go
./hello-go

Siin on kaks eri tööviisi:

  • go run kompileerib ja käivitab ühe käsuga
  • go build teeb natiivse binaari

Go näitab hästi erinevust käivitamise ja eraldi binaari koostamise vahel.

Rust: koostamistööriist on osa tavalisest töövoost

Rustis kasutatakse väga sageli tööriista cargo.


mkdir -p hello-rust
cd hello-rust
cargo init --bin .
cat > src/main.rs <<'EOF'
fn main() {
    for _ in 0..3 {
        println!("Tere, maailm!");
    }
}
EOF
cargo run
cargo build --release
./target/release/hello-rust

Siin:

  • cargo init --bin . teeb projekti karkassi
  • cargo run ehitab ja käivitab
  • cargo build --release teeb optimeerituma binaari

Rusti näide näitab, et mõnes keeles ei koosne koostamine ainult ühest kompilaatorikäsust, vaid tervest töövoost.

Java: kompileerimine ja eraldi käivituskeskkond

Java on hea kontrast C-le ja Go-le, sest kompileerimine toimub küll enne, aga tulemus ei ole tavaliselt otse natiivne binaar.


cat > Hello.java <<'EOF'
public class Hello {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            System.out.println("Tere, maailm!");
        }
    }
}
EOF
javac Hello.java
java Hello

Siin:

  • javac teeb failist Hello.class
  • java Hello käivitab selle JVM-is

See on oluline vahe:

  • C, C++, Go ja Rust annavad sulle tavaliselt natiivse binaari
  • Java annab klassifaili, mida käitab Java käivituskeskkond

Minitest

  1. Tee shelliskript, mis prindib sama rea kolm korda.
  2. Tee sama Pythonis.
  3. Kompileeri väike C programm ja käivita see.
  4. Võrdle go run ja go build käitumist.
  5. Vaata, mis fail tekib pärast javac Hello.java.
  6. Selgita ühe lausega, miks Java erineb C-st käivitamise mõttes.

Peatüki täisspikker

Edasijõudnu

Eesmärk

Erista lähtekoodi, koostatud väljundit ja selle käivitajat. Vali üks paigaldatud tööriistaga keel.

Käsud ja näited

  • sh hello.shtõlgenda POSIX-shelliskript
  • python3 hello.pykäivita Pythoni lähtefail
  • cc hello.c -o hello-ckompileeri C lähtefail käivitatavaks failiks
  • ./hello-ckäivita äsja koostatud C programm
  • c++ hello.cpp -o hello-cppkompileeri C++
  • go build -o hello-go hello.gokoosta Go binaarfail
  • cargo runRust: koosta ja käivita Cargo projekt
  • javac Hello.javaJava: loo baitkoodifail Hello.class
  • java Hellokäivita klass JVM-is, ilma .class-laiendita