Kokemukseni / tietoni Linuxeista ovat varsin vähäiset. Aion kumminkin tehdä monikielisiä, cross-platform käyttöliittymiä QT:llä, nyt kun kohtapuolin QT on saatavissa myös LPGL lisenssillä. OpenGL saattaa olla mukana tai sitten ei. Käyttiksien teko vielä aloittamatta, mielessä ollut myös WxWidgets. Ohjelmien tarkoitus toimia windowsissa, macissakin ja tietysti linuxissa. Mutta onko ongelmia saada sama binaari toimimaan eri linux versioissa?
Jos asia vaati enemmälti paneutumista, linkit olis tervetulleita.
Olen käyttänyt Ubuntua puolisen vuotta, sen kanssa alan jo pärjäilemään. Ohjelmointi kokemusta sinällään on aika lailla, mutta linuxin kanssa vielä vähän pihalla
Jos asia vaati enemmälti paneutumista, linkit olis tervetulleita.
Olen käyttänyt Ubuntua puolisen vuotta, sen kanssa alan jo pärjäilemään. Ohjelmointi kokemusta sinällään on aika lailla, mutta linuxin kanssa vielä vähän pihalla
Vastaukset 10
Vanhimmat
Linux -pohjaisissa saa tehtyä käyttisriippumattomia binääreitä tekemällä niistä LSB-speksin mukaisia:
http://en.wikipedia.org/wiki/Linux_Standard_Base
http://www.linuxfoundation.org/en/LSB
"Mutta onko ongelmia saada sama binaari toimimaan eri linux versioissa?"
Linuxin versiot on vähän kummallinen käsite. Useimmat käyttöjärjestelmävalmistajat ottaa sen Linux-ytimen ja räätälöivät tarpeisiinsa ja sitä myös päivitetään käyttöjärjestelmän elinkaaren aikana. Kannattaa ymmärtää, että Suse, Android, Ubuntu, Debian, Red Hat Enterprise, CentOS, Mandriva, Maemo jne. ovat käyttöjärjestelmiä joita yhdistää Linux-ydin. Monissa on myös paljon samoja komponentteja ja LSB-speksi on rajapinta joka yhdistää LSB-yhteensopivia käyttöjärjestelmiä vakioimalla osan komponenteista.
Tietenkään kaikkia Linuxia käyttävät käyttöjärjestelmät ei ole LSB-yhteensopivia, kuten esimerkiksi Android tai DSL. Näille pitää kääntää omat binäärit jos haluaa tukea. Mac OS X sitten on unix-yhteensopivana melko helppo käyttis kun oletus kääntäjäkin on GCC mitä Linux-pohjaisissa käytetään. Microsoftin käyttöjärjestelmät sitten on kummajaisia käyttöjärjestelmien joukossa.
Itse kuitenkin suosittelen lähtökohdaksi käyttämään avoimia alustariippumattomia kirjastoja (ja versioita jotka on standardin kanssa yhteensopivia) jotka on LSB-standardissa ka muihin käyttöjärjestelmiin sitten kikkailee puuttuvat kirjastot softan mukaan tai kikkailee toimimaan eri versiolla. Fiksu veto on myös vakioida kääntäjä samaksi. GCC 3.4.x on saatavilla ja toimii jokseenkin identtisesti joka paikassa. Windowseissa voi käyttää sitten MinGW:tä.
"Itse kuitenkin suosittelen lähtökohdaksi käyttämään avoimia alustariippumattomia kirjastoja (ja versioita jotka on standardin kanssa yhteensopivia)"
Onkohan aiemmin mainitut Qt ja WxWidgets tässä mielessä sopivia? Vai oisko joku muu parempi?
"Onkohan aiemmin mainitut Qt ja WxWidgets tässä mielessä sopivia? Vai oisko joku muu parempi?"
wxWidgets kyllä tavallaan on turhaa bloattia mitä pitäisi raahata turhaan mukana. Ja se on muuten todella turvonnut kirjasto, mutta sillä sitten saisi natiivi-ikkunoinnin joka paikkaan.
GTK , Qt on ne mitä suosisin kun näiden API on vakaa. GTK on kiva kun sitä voi koodata millä tahansa kielellä ja siinä taitaa skinien teko olla vähän edellä Qt:tä. Qt taas olisi kevyempi ja käyttää natiivikoodia mutta on rajoittunut C :n.
Mutta, käyttöliittymä nyt muutenkin erotetaan muusta koodista ja jos täydellisyyttä haluaa niin kääntäjävalitsimilla sitten voisi tehdä eri kälikoodin. Itse olen tuumannut jos jotenkin saisi makroiltua kälikoodin eri rajapinnoille tms. vastaavaa.
jotain niin linkkaa staattisesti. Jos taas jaat sorsat, niin anna innokkaiden hoitaa paketointi sun puolesta =)... ehkä omalle distrolle, tai jotain.
sen verran että mitä kaikkia perusjakeluita (sellaisia joihin muut perustuu) on olemassa?
Itselleni tulee mieleen ns. perusjakeluista:
1. Debian, deb-paketit, johon perustuu Ubuntu/Xubuntu/Kubuntu/Edubuntu/Ubuntustudio/Medibuntu ym. Ubuntun sisaret ja Ubuntuun puolestaan perustuu Linux Mint, yhtäkaikki ovat kuitenkin debian pohjaisia, muita debianiin perustuvia ja niin ikään deb-paketteja käyttäviä mm. Xandros
2. Fedora, alunperin Red Hat, rpm-paketit ja johon perustuu mm. Mandriva, Vixta (Vista-klooniksi väännetty Fedora-pohjainen jakelu), CentOS
3. Slackware, paketeista ei ole mitään hajuakaan?, mutta Slackwareen perustuu ainakin Vector Linux muitakin lienee mutta en tiedä muista..
Onko muita? Jos joku ystävällinen ja kärsivällinen sielu voisi täydentää listaani ja kertoa myös mitä muita on perustuva noihin jakeluihin, listani on varmasti puuteellinen.
Siinähän ne melkein tulikin sillä erolla että listasta puuttuu SuSE joka sekin (RedHat/Fedoran lailla) perustuu Slackwareen.
http://upload.wikimedia.org/wikipedia/commons/8/8c/Gldt.svg
Fedora/RH ole kumminkin eri jakeluita alunperinkin olleet?? Siis eri jakeluita kuin Slackware..
Fedoran tiedän olevan jatkoa muinaiselle Red Hatin ilmaisversiolle. Mutta Slackwaren olen kyllä ymmärtänyt olevan ihan eri jakelu, siis oman haaransa kuin Slackware ja siihen pohjautuvat.
Eipä tarvitse arvailla. Linux-historia on kirjoitettu: http://fi.wikipedia.org/wiki/Linux
Erityisesti tuo kuva eri jakelujen kehityshistoriasta vastaa kysymykseesi.
ml# ldd /bin/ls
linux-gate.so.1 => (0xb7f92000)
librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb7f70000)
libselinux.so.1 => /lib/libselinux.so.1 (0xb7f57000)
libacl.so.1 => /lib/libacl.so.1 (0xb7f4f000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7df4000)
libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7ddb000)
/lib/ld-linux.so.2 (0xb7f93000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7dd7000)
libattr.so.1 => /lib/libattr.so.1 (0xb7dd2000)
ml# ls -l /lib/i686/cmov/librt*
-rw-r--r-- 1 root root 30624 4.1. 20:12 /lib/i686/cmov/librt-2.7.so
lrwxrwxrwx 1 root root 12 17.1. 17:52 /lib/i686/cmov/librt.so.1 -> librt-2.7.so
kekeke... fubar.so.1234
Freepascal+Lazarus on paras saatavilla oleva ohjelmointiväline linuxille.
Tosin, varsinkin integroitu debuggeri ei valitettavasti ole delphistä tuttua tasoa.
Oletuswidgetsettinä tuossa on GTK1, mutta siihen voi asentaa myös tuen GTK2:lle sekä QT:lle.
QT -tuessa ilmeisesti on käytetty apuna pientä C++:lla koodattua apukirjastoa juurikin siksi, ettei QT toimi suoraan muiden kuin C++:n kanssa.
Samaa ratkaisua käytti aikanaan Borland Kylix 3, tosin sinä QT oli ainoa tuettu widgetsysteemi.
Lazaruksessa on paljon myös muita pikkubugeja jotka tosin eivät estä ohjelmien toimintaa, mutta kiusallisia ovat silti. Esimerkki tällaisesta:
kun napin Caption -ominaisuudeksi asettaa:
Button1.Caption := '&Muokkaa';
niin Alt-M pitäisi aiheuttaa tuon napin painallus.
En nyt muista kumminpäin tuossa on bugi, mutta joko niin, että Alt-M EI liipaise tujon napin painallusta jos napilla ei ole focusta, tai sitten niin, että pelkkä M (ilman Alt:ia) liipaisee napin silloinkin kun jossain TEdit tai TMemo -kentässä on focus.
Tällaisten bugien takia itse jätän tuon Alt-kirjain -option käyttämättä Lazaruksella koodatesssani, eli en käytä '&' -merkkiä nappien Captioneissa.
Lisäksi, pieneen vaatimattomaan tarpeeseen Lazaruksessa on integroitu debughgeri, mutta heti, kun debuggaus menee vaativaksi, joudut turvautumaan ulkoiseen debuggeriin, joista ikävä kyllä 99% on gdb -pohjaisia, gdb:tä sellaisenaan voin suositella vain masokisteille.
Jos joudut gdb -phjaista debuggeria käyttämään niin:
set dis int
olkoon 1. käskysi, tosin sitä ennen break main ja run
tuolla set dis int pääset eroon lähinnä sontaa muistuttavasta at&t assemblersyntaksista, ja intel tilalle.
sääli, etteivät useammat tajua objectpascalin hyötyjä, kieli on vähintään yhtä tehokas ja pätevä kuin C++, mutta paljon helpompi.
Erityisesti string on objectpascalissa mainio keksintö, mutta huomaa:
var
St1 : String;
begin
St1 := 'käyttö';
// TÄHÄN lisättynä St1:n merkki merkiltä läpikäynti antaisi esimerkkikoodin jälkeen esitetyt tulokset
ShowMessage( IntToStr( length(St1) ) );
end;
em. koodinpätkä (laita sovellettuna vaikka formin button1click -tapahtumakäsittelijään) tuo esille nykylinuxien jännän piirteen: nappia painettaessa messagebox näyttää numeron 8.
Ai miksikä sanan 'käyttö' pituus on 8 eikä 6 ?
(Delphi+Windows tulostaisivat tuossa luvun 6).
Syy on se, että nykylinuxit käyttävät oletusmerkkivalikoimana unicodea ja sen koodaustapana UTF-8:aa.
Siis jokainen US-ASCII:hin kuuluva merkki otta tilaa yhden tavun, mutta ä ja ö ovat UTF-8:ssa 2.tavuisia epämerkkejä.
Siksipä:
St1[1] = 'k'
St1[2] = ? // ½ ä -kirjaimesta
St1[3] = ? // ½ ä -kirjaimesta
St1[4] = 'y'
St1[5] = 't'
St1[6] = 't'
St1[7] = ? // ½ ö -kirjaimesta
St1[8] = ? // ½ ö -kirjaimesta
Huomaa siis myös, että objectpascalin stringien indeksointi alkaa 1:stä.
Jos sensijaan lisäät esimerkkikoodiin:
var
P : PChar; // objectpascalin PChar on sama asia, jonka C -koodaajat tuntevat nimellä "char *"
begin
// tässä asetetaan St1:n arvo
St1 := 'käyttö';
P := PChar(St1); // tyyppimuunnos eli ns. "cast"
// TÄSSÄ P:llä (tai tarkkaanottaen P:n osoittamalla muistialueella !) on seuraavat arvot:
end;
P[0] = 'k'
P[1] = ? // ½ ä -kirjaimesta
P[2] = ? // ½ ä -kirjaimesta
P[3] = 'y'
P[4] = 't'
P[5] = 't'
P[6] = ? // ½ ö -kirjaimesta
P[7] = ? // ½ ö -kirjaimesta
P[8] = #0 // eli siis ascii NUL -merkki, josta mahd. C:llä koodatut systeemikirjastot tietävät string:in loppumisen
Siis St1[1] ja P[0] edustavat samaa merkkiä.
huomaa: objectpascalin length() EI ole sama asia kuin C:n strlen(), vaikka tässä tapauksessa ne palauttavatkin saman arvon.
Nimittäin seuraavakin on laillinen merkkijono arvo objectpascalissa:
St1 := 'abc'#0'def';
Tuollaiselle length() palauttaa 7, mutta strlen(PChar(St1)) palauttaa 3.
Tuossa siis St1[4] = #0, eli ascii NUL, joten strlen (joka löytyy sekä C:stä että objectpascalista) tulkitsee, että sitä edeltävä (tässä 'c') on merkkijonon 3. ja viimeinen merkki.
Mutta NUL on objectpascalissa kelvollinen arvo merkkijonon yhdelle merkille.
Aiemmassa esimerkissä tuo ½ ä -kirjaimesta tarkoittaa siis sitä, että ottamalla olemmat epämerkit huomioon ja tulkitsemalla niiden numeroarvot UTF8 -standardin mukaisesti, 2 peräkkäistä epämerkkiä yhdessä esittää ä -kirjainta.
Freepascalissa ei taida olla valmiina rutiinia, jotka tuosta palauttaisivat ä -kirjaimen, mutta ei ole vaikeaa itse koodata tämäntapaista rutiinia:
type
TUtf8Char = TAnsiChar;
TUnicodeChar = Longword; // 32 bittiä, joista 21 vähiten merkitsevää esittävät Unicode -koodia, ja loput ovat aina nollia.
function GetUnicodeChar(var Merkki:TUtf8Char):TUnicodeChar;
// pieni "trikki":
var
RawBytes : Array[0..3] of BYTE absolute Merkki;
begin
// ne, jotka eivät "absolute":n käyttöä hyväksy, joutuvat käyttämään sensijaan osoitintyyppiä P:PChar; P := PChar(Merkki);
// tämän koodaaminen ei ole kovin vaikeaa
// RawBytes[0] = UTF8 -sekvenssin 1. tavu
// RawBytes[1] = UTF8 -sekvenssin 2. tavu
// RawBytes[2] = UTF8 -sekvenssin 3. tavu
// RawBytes[3] = UTF8 -sekvenssin 4. tavu
// toki jos RawBytes[0]