Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Pretkompajlerske direktive? :)

[es] :: C/C++ programiranje :: Pretkompajlerske direktive? :)

[ Pregleda: 1787 | Odgovora: 6 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Goran Arandjelovic
Beograd

Član broj: 29116
Poruke: 387
*.smin.sezampro.yu.



+9 Profil

icon Pretkompajlerske direktive? :)29.10.2005. u 19:03 - pre 225 meseci
Da li je moguce uraditi sledece:

Npr. ako imamo ovakvu funckiju (da ne bih sada navodio kompletno telo f-je koju pisem):

Code:

void funkcija()
{
  player *p[0]; //player je neka klasa
  p[0] = new igrac1(argumenti); //igrac1 je klasa koja nasledjuje klasu player
}


U direktorijumu gde se nalazi glavni program (koji sadrzi ovu funckiju) nalazi se fajl igrac1.h (koji sadrzi deklaraciju i definiciju klase igrac1).
E sada, da li je moguce po dodavanju npr. novog fajla igrac2.h u direktorijum, da program automatski pri kompajliranju doda sledeci kod u datoj funkciji:

Code:

  player *p[1];
  p[1] = new igrac2(argumenti); //igrac2 je klasa koja takodje nasledjuje klasu player


Da li se tako nesto moze postici pretkompajlerskim direktivama i kako? (naravno, podrazumeva se da postoji funkcija koja vraca sadrzaj direktorijuma i string sa nazivom novog header fajla u njemu)

Pozdrav i unapred hvala.
 
Odgovor na temu

Časlav Ilić
Braunšvajg, Nemačka

Član broj: 4945
Poruke: 565
*.informatik.uni-erlangen.de.



+27 Profil

icon Re: Pretkompajlerske direktive? :)30.10.2005. u 11:23 - pre 225 meseci
Malo mi je neobično to što želiš da uradiš, moguće je da postoji bolje rešenje, više u duhu C++-a, iako komplikovanije (nekakve fabrike mi se vrzmaju po glavi...) S druge strane, zaista biva s vremena na vreme da je potrebno „spolja“ izvršiti neku izmenu na izvornoj datoteci, kao to što ti sada nameravaš. Tako da ću nešto o tome da kažem.

Obično se te spoljašnje izmene u kodu ne sprovode preko preprocesorskih naredbi, ne samo jer je to možda nemoguće, već i zato što često dovode do rusvaja kada se pokušaju upotrebiti van uobičajenih namena. Umesto toga, taj deo posla se uglavnom prebacuje na sistem za gradnju.

Na Linuksu, najčešći sistem za gradnju je make, uz nadgradnju u vidu kombinacije Automejk/Autokonf koje se oslanjaju na njega (to je ono što stvara sveprisutno ./configure && make && make install za izvorne pakete). Međutim, iako u širokoj upotrebi i dobro podržan, ovaj lanac alata malo pokazuje godine, tako da počinju sve češće da se koriste neki noviji sistemi. Jedan od izgleda omiljenijih (npr. KDE uskoro prelazi na njega), jeste Skons (Scons); to je u stvari sistem naredbi za gradnju na bazi pitona, tako da se u njegovim spravljačkim datotekama mogu koristiti sve pitonske baterije.

Za primer koji si naveo, imaš ovakve izvore u jednom direktorijumu:

Code:
// player.h
#ifndef PLAYER_H
#define PLAYER_H

class player {};

#endif

Code:
// igrach1.h
#ifndef IGRACH1_H
#define IGRACH1_H

#include "player.h"

class igrach1 : public player {};

#endif

Code:
// igrach2.h
#ifndef IGRACH2_H
#define IGRACH2_H

#include "player.h"

class igrach2 : public player {};

#endif


Onda recimo napišeš glavni program ovako:

Code:
// proba.cc
#include <iostream>

using namespace std;

#include "igrachi-spec.h"

int main ()
{
    #include "igrachi-spec.cc"
    return 0;
}


gde će ova uključenija da navedu odgovarajuća zaglavlja i kod za alociranje onih igrača, a napraviće ih Skons. U istom direktorijumu napraviš spravljačku datoteku po imenu SConstruct (mora baš tako da se zove, sa sve velikim i malim slovima), u kojoj se nalazi ovo:

Code:
# SConstruct - napisao Pera Haker
# -*- coding: utf8 -*-
import os
import re

# Sve stavke iz tekućeg direktorijuma.
files = os.listdir('.')

# Regiz za imena unosa koje želimo da izdvojimo.
sito = re.compile('igrach[0-9]+\.h')

# Filtriraj listu stavki u direktorijumu.
igrachi = filter(sito.search, files)

# Pravimo posebnu datoteku koja uključuje zaglavlja svih igrača.
fincl = open('igrachi-spec.h', 'w')
for igrach in igrachi:
    fincl.write('#include "%s"\n' % igrach);
fincl.close()

# Pravimo posebnu datoteku koja sadrži kod za stvaranje svih igrača.
fcode = open('igrachi-spec.cc', 'w')
fcode.write('int npls = %d;\n' % len(igrachi))
fcode.write('player *p[npls];\n')
ind = 0;
for igrach in igrachi:
    fcode.write('p[%d] = new %s(/*argumenti*/);\n' % (ind, igrach[:-2]))
    ind += 1
fcode.close()

# Skonsova naredba za spravljanje programa.
# (deo CPPPATH... kaže Skonsu da postoji zavisnost od nekih zaglavlja)
Program('proba.cc', CPPPATH = '.')


Zatim u tom direktorijumu izvršiš naredbu scons, koja će automatski da pokupi datoteku SConstruct i sagradi program na osnovu nje:

Code:
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -I. -c -o proba.o proba.cc
g++ -o proba proba.o
scons: done building targets.


Ako opet izvršiš isto, ne dirajući izvore, dobićeš ovo:

Code:
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
scons: done building targets.


To je Skons uvideo da nije bilo nikakvih izmena u izvorima, pa je odlučio da ne gradi program ponovo. Čim izmeniš neki izvor, Skons će primetiti i ponovo sagraditi program.
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4902
*.nat-pool.po.sbb.co.yu.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: Pretkompajlerske direktive? :)30.10.2005. u 12:47 - pre 225 meseci
Slicne izmene u izvornom kodu (a sve naravno - pre kompajliranja), u jednoj
firmi u kojoj sam radio, vrsilo se awk-om. awk je neki komandni procesor tekstualnih
datoteka - pogledaj na net-u.

Dakle, samo kompajliranje se vrsilo iz komandne linije pozivanjem odredjene BAT
datoteke, koja je opet bila sastavljena iz raznih skriptova medju kojima je bio i
awk skript koji je pre samog pozivanja kompajlera/linkera vrsio razne korekcije
na source kodu.

 
Odgovor na temu

Goran Arandjelovic
Beograd

Član broj: 29116
Poruke: 387
*.37.eunet.yu.



+9 Profil

icon Re: Pretkompajlerske direktive? :)30.10.2005. u 14:45 - pre 225 meseci
Jasno. Hvala na odgovorima, pretpostavio sam da ne može sa pretkompajlerskim direktivama. Ali, ako je situacija već takva, napisaću posebnu aplikaciju, ali opet u C++-u, koja će činiti gore navedeno.

Još jedno pitanje kad je već pomenut scons ili awk... Da li se ide na neki skript jezik zbog lakoće pisanja ovakve aplikacije, zbog poštovanja (ili uvođenja) nekog standarda ili je neki drugi razlog u pitanju? Zašto se takve stvari ne pišu u C++-u? (Zašto je npr. KDE prešao na Scons sistem?)
 
Odgovor na temu

Časlav Ilić
Braunšvajg, Nemačka

Član broj: 4945
Poruke: 565
*.lstm.uni-erlangen.de.



+27 Profil

icon Re: Pretkompajlerske direktive? :)30.10.2005. u 15:34 - pre 225 meseci
Citat:
Goran Arandjelovic: Još jedno pitanje kad je već pomenut scons ili awk... Da li se ide na neki skript jezik zbog lakoće pisanja ovakve aplikacije, zbog poštovanja (ili uvođenja) nekog standarda ili je neki drugi razlog u pitanju? Zašto se takve stvari ne pišu u C++-u? (Zašto je npr. KDE prešao na Scons sistem?)

Naravno, mogao bi uvek sam da pišeš neki servisni kod za gradnju projekta, ali mnoge radnje koje će ti trebati ponavljaju se od projekta do projekta. Stoga, postoje sistemi za gradnju (spravljači) koji već imaju te česte radnje implementirane, te ne moraš da „zagrevaš vodu“. U svakom slučaju, nemoj misliti da će ijedan veći projekat raditi nešto na svoju ruku, bez spravljača (koji može biti i implicitan, tj. u okviru nekakvog grafičkog razvojnog okruženja).

E sad, kako spravljači interaguju sa korisnikom, to naravno zavisi od jednog do drugog. Većina uniks spravljača radi iz komandne linije, pa je logično da imaju nekakav skriptni interfejs. Tako sveprisutni GNU Mejk ima sopstvenu sintaksu i semantiku, na žalost zapetljanu i zastarelu (za čupanje kose čim pokušaš nešto intenzivnije). Od novijih, tu je KuMejk (QMake) koji, koliko sam čuo, ima već znatno poboljšane mogućnosti, ali opet potpuno u svojoj režiji. Zatim, Skons, koji se mnogima dopada baš zato što se oslanja na moderan i popularan skriptni jezik, piton (baš je bila rasprava između KuMejka i Skonsa za naredni KDE-ov sistem gradnje, i čini mi se da je baš zbog pitona Skons prevagnuo).

Citat:
Goran Arandjelovic: Ali, ako je situacija već takva, napisaću posebnu aplikaciju, ali opet u C++-u, koja će činiti gore navedeno.

U skladu sa ovim što napisah gore, bolje nemoj, išao sam i ja tim putem :) Mada, ko zna, možda i to ima svoju obrazovnu stranu... Nemoj ni C++-a da se držiš ko pijan plota; da ne dužim, uglavnom ko upozna još neke jezike, pita se posle kako je mogao bez njih u svom arsenalu :)
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4902
*.nat-pool.po.sbb.co.yu.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: Pretkompajlerske direktive? :)30.10.2005. u 15:47 - pre 225 meseci
Hm... awk je poznat jos od UNIX-a i tamo je bio izuzetno popularan. Dobra strana
awk-a je sto (moze da) radi nad skript fajlovima koji mu se poture kao argument.

To dalje znaci da jedan awk skript moze da menja drugi (ili vise njih) a onda neki
treci sve to zajedno obradi. U praksi, nesto kao kaskadno menjanje.

U sali se kaze da je naziv awk nastao od uzdaha kada su programeri trebali da ga
koriste, sto bi po tom engleskom humoru trebalo da znaci da ga je TEŠKO nauciti
i koristiti.

U svakom slucaju, cisto informativno, vredi otici na par sajtova i videti malo njegovu
sintaksu...



P.S. mada, u praksi, i ja bih napravio poseban program za takvo nesto... ko sad
da se zeza sa ucenjem ;)


 
Odgovor na temu

NastyBoy
Bojan Nastic
UK

Član broj: 12041
Poruke: 895
*.plus.com.



+4 Profil

icon Re: Pretkompajlerske direktive? :)30.10.2005. u 21:08 - pre 225 meseci
Citat:
E sada, da li je moguce po dodavanju npr. novog fajla igrac2.h u direktorijum, da program automatski pri kompajliranju doda sledeci kod u datoj funkciji
...

Da li se tako nesto moze postici pretkompajlerskim direktivama i kako?


K'o shto rekoshe, nije moguce prostim precompile direktivama, ali jeste moguce da ti to kompajler odradi sam, bez potrebe za ikakvim skriptovima i eksternim menjanjem koda, vec chim dodash novu klasu da se automatski instancira.

Recimo, pomocu statichkih 'class-descriptora' i ClassFactory paterna mozhesh postici da ti se svi tipovi klasa instanciraju i 'registruju' u Factory-u automatski.
Takav pristup se chesto koristi za izradu custom RTTI funkcionalnosti i raznih varijanti ClassFactory-a. Ako te zanima kako, mogu kasnije postaviti kod koji obavlja ovakvo "automatsko" registrovanje i instanciranje.
 
Odgovor na temu

[es] :: C/C++ programiranje :: Pretkompajlerske direktive? :)

[ Pregleda: 1787 | Odgovora: 6 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.