C++ - problem z linkowaniem(?)

0

Witam, to mój pierwszy post na tym forum.

Zakupiłem ebooka Magnum Opus C++ i uczę się z niego programowania w CPP. Jestem na stronie 219. W wielkim skrócie, robię teraz - zgodnie z przykładem w książce - program w kilku plikach z dwoma plikami w CPP (afryka.cpp i europa.cpp) i jednym plikiem nagłówkowym naglowek.h.

Mój kod:

naglowek.h:

extern int ile_pigmejow;
extern int ile_europejczykow;

void funkcja_etiopska();
void funkcja_kenijska();
void funkcja_francuska();
void funkcja_niemiecka();

afryka.cpp:

# include <iostream>

using namespace std;

#include "naglowek.h"

int ile_pigmejow = 9;

//**********************************************************************

int main()
{
	cout << "Poczatek programu" << endl;
	funkcja_francuska();
	funkcja_niemiecka();
	cout << "Koniec programu" << endl;
}

//**********************************************************************

void funkcja_etiopska()
{
	cout << "Jestem w Abbis Abbebie (Afryka) " << endl;
	cout << "Na świecie mam przyjaciol: " << ile_pigmejow << " Pigmejow i "
		 << ile_europejczykow << " Europejczykow" << endl;
}

//**********************************************************************

void funkcja_kenijska()
{
	cout << "Jestem w Nairobi (Afryka) " << endl;
	cout << "Na świecie mam przyjaciol: " << ile_pigmejow << " Pigmejow i "
		 << ile_europejczykow << " Europejczykow" << endl;
}

europa.cpp:

#include <iostream>

using namespace std;

#include "naglowek.h"

int ile_europejczykow = 8;

//**********************************************************************

void funkcja_francuska()
{
	cout << "Jestem w Paryzu (Europa) " << endl;
	cout << "Na świecie mam przyjaciol: " << ile_pigmejow << " Pigmejow i "
		 << ile_europejczykow << " Europejczykow" << endl;
		 
	funkcja_etiopska();
}

//**********************************************************************

void funkcja_niemiecka()
{
	cout << "Jestem w Berlinie (Europa) " << endl;
	cout << "Na świecie mam przyjaciol: " << ile_pigmejow << " Pigmejow i "
		 << ile_europejczykow << " Europejczykow" << endl;
		 
	funkcja_kenijska();
}

Nagłówek kompiluje mi się dobrze, ale obydwa podpliki w CPP już nie. Kiedy próbuję na ten przykład skompilować Afrykę otrzymuję następujący komunikat:

g++ -Wall -std=c++0x -o "afryka" "afryka.cpp" (w katalogu G:\Personal Data\My Folders\Programowanie\CPP\MagnusOpus\6)
C:\Users\SZYMON1\AppData\Local\Temp\ccnbCGZ6.o:afryka.cpp:(.text+0x3c): undefined reference to funkcja_francuska()' C:\Users\SZYMON~1\AppData\Local\Temp\ccnbCGZ6.o:afryka.cpp:(.text+0x41): undefined reference to funkcja_niemiecka()'
C:\Users\SZYMON
1\AppData\Local\Temp\ccnbCGZ6.o:afryka.cpp:(.text+0xa6): undefined reference to ile_europejczykow' C:\Users\SZYMON~1\AppData\Local\Temp\ccnbCGZ6.o:afryka.cpp:(.text+0x146): undefined reference to ile_europejczykow'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../../mingw32/bin/ld.exe: C:\Users\SZYMON~1\AppData\Local\Temp\ccnbCGZ6.o: bad reloc address 0x0 in section `.ctors'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
Kompilacja nie powiodła się

Korzystam z Geany i gcc na Windowsie 10.

Czy ktoś może mi powiedzieć co zrobiłem źle? Pierwszy raz programuję w więcej niż jednym pliku i jestem kompletnie zielony jeśli o to chodzi. Znaczy, tak jak na to patrzę to widzę, że pliki nie widzą mi swoich funkcji (?), ale przecież wszystko zrobiłem zgodnie z przykładem, więc czemu tak jest?

Program działa jeśli wszystkie funkcje - i deklaracje i definicje - oraz zmienne umieszczę w pliku nagłówkowym, w takim wypadku zostaje mi tylko jeden plik - afryka.cpp - który działa. Chyba jednak autorowi chodziło o nieco inne rozwiązanie? Zrobiłem coś nie tak?

0

Spróbuj g++ afryka.cpp europa.cpp

0
[Kaworu napisał(a)]

Nagłówek kompiluje mi się dobrze, ale obydwa podpliki w CPP już nie.

Pliki nagłówkowe nie są kompilowane.

0

Oh, dziękuję, podziałało, teraz tylko muszę zrobić coś, żeby mi się okno tak szybko nie zamykało. Mogę spytać czemu Geany nie był w stanie tego zrobić automatycznie?

0

Nie wiem jak działa Geany, nie wiem jak zrobiłeś ten projekt. Może w makefile nie było obu plików. Trudno powiedzieć.

0

Chyba jednak dalej mam problem. Dodałem prostą funkcjonalność, by program czekał na wpisanie jakiejś litery, ale niestety, w żaden sposób to nie działa. Mam też tylko jeden plik po skomplikowaniu (nazywa się a.exe, a nie afryka.exe i nie ma pliku europa.exe). I jak mówię, ten plik się otwiera, zamyka po sekundzie, żadnego śladu po cin >> c nie ma...

Próbowałem też program skompilować pod Code::Blocks, ale dalej mam informacje o "undefined references" co sugeruje, że to bardziej problem z programem niż z danym IDE.

Przepraszam też za niewiedzę o nagłówkach, pracuję z nimi pierwszy raz w życiu.

0

No nazywa się a.exe bo to domyślna nazwa jak nie podasz własnej. nie będziesz miał 2 plików .exe skoro masz 1 funkcję main w projekcie. Po co by ci było kilka plików exe?

0

Hm, czyli nie będzie pliku dla europa.cpp? Dobrze, dziękuję za wyjaśnienie.

I jednak wszystko mi działa, zapomniałem zapisać tych zmian, gapa ze mnie :)

Jakieś porady jak w przyszłości kompilować takie pliki bez wchodzenia w wiersz poleceń? Np: przy pomocy Code::Blocks? Jeśli będę miał więcej plików to wpisanie ich wszystkich w linii komend mogłoby być męczące.

1
  1. Stworz plik i nazwij go "Makefile"
  2. Wklej do niego to i ewentualnie zmodyfikuj
COMPILER = g++
ERRORS = -Wall -Wextra -pedantic
CFLAGS = --std=c++14 -I$(IDIR) -g

IDIR = ./include/
SRCDIR = ./src/

SOURCES = $(SRCDIR)*.cpp

all: clean install run

install: $(SOURCES)
	$(COMPILER) main.cpp $(SOURCES) $(ERRORS) $(CFLAGS) -o prog
run:
	./prog
clean:
	rm -f prog
  1. Headery trzymasz w /include/ a .c w /src/
  2. Kompilujesz poleceniem make

  1. To instrukcja do Linuxa ale jestem przekonany ze na windowsie tez sie da tylko pewnie trzeba make zainstalowac. I wtedy tez clean i run trzeba napisac zeby w shellu windowsa dzialalo

Edit: ewentualnie zainstaluj IDE ktore sobie to ogarnie za Ciebie (tylko musisz nowy projekt w takim zalozyc bo samo wczytanie plikow nie wystarczy)
Np. CLion (zeby miec za darmo musisz byc studentem)
Visual Studio Community
Pewnie jakies NetBeans lub Eclipse tez ogarnia C++
W ostatecznosci jakis Code::Blocks (oh, nie lubie tego ale dziala)

1 użytkowników online, w tym zalogowanych: 0, gości: 1