Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Dzielenie kodu na kilka plików źródłowych - błąd w zbudowaniu

Ostatnio zmodyfikowano 2009-12-20 16:07
Autor Wiadomość
Rantrave
Temat założony przez niniejszego użytkownika
Dzielenie kodu na kilka plików źródłowych - błąd w zbudowaniu
» 2009-12-19 22:23:02
Witam,

Według artykułu na stronie XXII, zrobiłem plik nagłowkowy :
definicje.hpp
C/C++
#ifndef definicje_hpp

#define definicje_hpp

using namespace std;
int wpisy( string komenda );
int ip( string komenda );
int ip6( string komenda );
int ipx( string komenda );
int ip4( string komenda );
void filtr( string komenda, string IP );

#endif

main.cpp
C/C++
#include <iostream>
#include <fstream>
#include <string>
#include "definicje.hpp"

obliczenia.cpp
C/C++
#include <iostream>
#include <fstream>
#include <string>
#include "definicje.hpp"
using namespace std;

dodatkowe.cpp
C/C++
#include <iostream>
#include <fstream>
#include <string>
#include "definicje.hpp"
using namespace std;

oraz makefile

main: main.o obliczenia.o dodatkowe.o
gcc main.o obliczenia.o dodatkowe.o -o main

all: main

main.o: main.cpp
gcc -c main.cpp -o main.o

obliczenia.o: obliczenia.cpp
gcc -c obliczenia.cpp -o obliczenia.o

dodatkowe.o: dodatkowe.cpp
gcc -c dodatkowe.cpp -o dodatkowe.o

clean:
rm -f *.o


Przy tworzeniu przez make dodatkowe.o ni ema problemu, jednakze gdy daje make main, wywarzuca o to taki komunikat :


g++ -Wall -o "main" "main.cpp" (w katalogu /home/andrzej/projekty/Plikitekstowe)
Kompilacja nie powiodła się
/tmp/ccipyvAl.o: In function `main':
main.cpp:(.text+0x33f): undefined reference to `wpisy(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
main.cpp:(.text+0x3f2): undefined reference to `ip(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
main.cpp:(.text+0x471): undefined reference to `ip6(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
main.cpp:(.text+0x4f0): undefined reference to `ipx(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
main.cpp:(.text+0x68b): undefined reference to `wpisy(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
main.cpp:(.text+0x73e): undefined reference to `ip4(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
main.cpp:(.text+0x7f1): undefined reference to `ip6(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
main.cpp:(.text+0xa97): undefined reference to `filtr(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
collect2: ld returned 1 exit status

Yhhh gdzie błąd? Chciałbym, aby można było etapowo kompilować wszystko przez makefile'a, bez większego problemu

Może zamiast hpp dać #include "obliczenia.cpp"?
Pozdrawiam
P-12297
malan
» 2009-12-19 22:49:57
Hmmm... może tak:
C/C++
extern int wpisy( string komenda );
extern int ip( string komenda );
extern int ip6( string komenda );
extern int ipx( string komenda );
extern int ip4( string komenda );
extern void filtr( string komenda, string IP );
P-12301
Elaine
» 2009-12-19 22:55:25
extern nic nie da, przy funkcjach extern stoi jakby domyślnie (jak tego nie chcemy, to jest static).
P-12302
Rantrave
Temat założony przez niniejszego użytkownika
» 2009-12-19 22:56:11
Dalej ten sam błąd, tak jakby nie widział tych definicji w headerze,
Jak dałem w mainie bezpośrednio zaincludowane pliki źródłowe .cpp to w miarę działało z pozycji kompilatora (kompilacja+zbudowanie programu)

Jednakże w momencie gdy daje z konsoli make main wyrzuca ten błąd co podałem, samo extern co robi? Podejrzewam, że błąd może być w makefilu oraz w headerze, bo przy includowaniu plików źródłowych kompilator zadziałał swoje jednakże już z pozycji konsoli nie, natomiast jak wyrzucam zaincludowane pliki źródłowe to nawet w kompilatorze jest ten sam błąd.
P-12303
malan
» 2009-12-19 23:02:52
Co ja pisze ;/- za długo już siedzę...

extern - sprawia iż np. zmienne poprzedzone nim będę widoczne na zewnątrz pliku (to tak w skrócie).

/edit:
Ogólnie rzecz biorąc to ja bym to zrobił tak:
C/C++
#ifndef definicje_hpp
#define definicje_hpp

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int wpisy( string komenda );
int ip( string komenda );
int ip6( string komenda );
int ipx( string komenda );
int ip4( string komenda );
void filtr( string komenda, string IP );

#endif

C/C++
// plik.definicje.cpp (tutaj bym napisał ciała funkcji)
#include "definicje.hpp"
int wpisy( string komenda )
{
    //...
};
// itd...

C/C++
// main.cpp
#include "definicje.hpp"
...itd.

P-12304
Rantrave
Temat założony przez niniejszego użytkownika
» 2009-12-19 23:17:51
W obliczenia.cpp i dodatkowe.cpp mam ciała funkcji,

dałem biblioteki w hpp, dalej nie widzi odniesień do definicji funkcji gdy chce je wywołać w int main(czytaj ten sam bład) >_<

W mainie mam int main{}
W obliczenia.cpp mam includowany "definicje.hpp" oraz funkcje np
int wpisy(String komenda) {instrukcje};
Nie wiem czemu nie dziala to wszystko, natomiast jak daje includowanie plikow zrodlowych w mainie i same definicje w mainie (czyli wszystkie linijki z definicje.hpp),
Dziala z poziomu kompilatora, nie dziala z poziomu konsoli
Chcialbym, aby wszystkie definicje były w headerze i kompilacja działała z konsoli jak i również w kompilatorze, którego używam.
P-12305
DejaVu
» 2009-12-20 03:11:29
Nie czytałem niczego poza pierszym postem, ale opcje masz takie:
1a) tworzysz lib'a, czyli plik *.a z plików, które mają tworzyć osobną bibliotekę.
2a) drugi projekt to Twój program w którym masz tylko np. main.cpp. Aby Twój projekt się skompilował musisz zlinkować statycznie bibliotekę *.a wygenerowaną w kroku pierwszym.

Drugą opcją, która jest prostsza to po prostu podczas procesu kompilacji wymienić wszystkie pliki *.cpp, które mają zostać skompilowane. Jeśli skompilujesz tylko main.cpp, kompilator nie będzie miał definicji funkcji, które znajdują się w plikach *.hpp i stąd się biorą błędy 'undefined refernce ...'.

/edit:
Tak patrzę sobie na Twój makefile i myślę, że masz go źle napisanego. W jednej linijce powinny się znajdować wszystkie pliki *.cpp. Ale ja się nie znam na makefile'ach - po to mam środowisko Visual C++ lub Code::Blocks lub Dev-C++, żebym nie musiał wiedzieć jak je się tworzy ;)
P-12312
Rantrave
Temat założony przez niniejszego użytkownika
» 2009-12-20 15:56:18
Udało mi się poprawić błąd, a więc tak:

Do, każdego pliku źródłowego z ciałami funkcji stworzyłem osobny *.hpp z definicjami funkcji. Biblioteki umieściłem w biblioteki.hpp, które dołączam do każdego pliku źródłowego,

Potem poprawiłem makefile, a więc tak program uzależniłem (albo on jest uzależniony albo wtf...) od main.o , dodatkowe.o obliczenia.o, które potem rozpisałem jak się tworzą, teraz jak daje polece make main wyrzuca tlyko czasem dyrektywa main.cpp okreżna -> dyrektywa porzucona, ale tworzy PROGRAM więc sukces

Oto zmieniony makefile:

main: main.o obliczenia.o dodatkowe.o
g++ -o main main.o obliczenia.o dodatkowe.o

main.cpp: main.cpp biblioteki.hpp
g++ -c main.cpp

obliczenia.o: obliczenia.cpp biblioteki.hpp obliczenia.hpp
g++ -c obliczenia.cpp

dodatkowe.o: dodatkowe.cpp biblioteki.hpp dodatkowe.hpp
g++ -c dodatkowe.cpp

clean:
rm -f *.o
  
all: main

@Piotr Szawdyński
Taka specyfika zadania, że ma być kompilowany z makefile'em, więc go tworzę, też używam dev-c++/geany, (Code Blocks będe musiał artykuł przeczytać);

Co do twojej wizji pisania oddzielnego liba *.a, jakiś artykuł na stronie o tym jest? bo nie zrozumiałem twojej wizji rozwiązania problemu

Pozdrawiam
P-12323
« 1 » 2
  Strona 1 z 2 Następna strona