View previous topic :: View next topic |
Author |
Message |
musv Advocate
Joined: 01 Dec 2002 Posts: 3337 Location: de
|
Posted: Fri Jan 11, 2013 10:18 am Post subject: [solved] Brauch mal cmake-Einstiegshilfe: Linking-Problem |
|
|
Guten Morgen.
Ich versuch mir seit kurzem mal cmake zu Gemüte zu führen, scheiter aber schon bei einem einfachen Linking-Problem. Dazu hab ich ein Hello-World-Projekt gebastelt und versuch das Teil jetzt zum Laufen zu kriegen.
Verzeichnisstruktur:
Code: | ./CMakeLists.txt
./includes
./src
./src/main.cpp
./src/CMakeLists.txt
./src/klasse.cpp
./src/klasse.h
./build
./bin |
Source-Code:
main.cpp: | #include <iostream>
#include "klasse.h"
int main()
{
std::cout << "Main" << std::endl;
Klasse * k = new Klasse();
delete k;
return 0;
} |
klasse.h: | #ifndef KLASSE_H
#define KLASSE_H
class Klasse
{
public:
Klasse();
virtual ~Klasse();
};
#endif |
klasse.cpp: | #include "klasse.h"
#include <iostream>
Klasse::Klasse()
{
std::cout << "Klasse Konstruktor" << std::endl;
}
Klasse::~Klasse()
{
std::cout << "Klasse Destruktor" << std::endl;
} |
CMake-Configs:
CMakeLists.txt: | cmake_minimum_required(VERSION 2.8)
project(hello)
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
add_subdirectory(src) |
- Zu erstellendes Binary soll hello heißen und im bin-Verzeichnis abgelagert werden.
- Die zu compilierenden Dateien befinden sich in src. Die Headerdateien will ich später noch nach includes auslagern.
src/CMakeLists.txt: | add_executable(hello main.cpp) |
- main.cpp ist der Einstiegspunkt, mit dem das Binary hello gebaut werden soll.
Build-Prozess:
Und damit kommen wir zu meinem Problem.
Code: | cd build
cmake ..
-> Ausgabe:
-- The C compiler identification is GNU 4.7.2
-- The CXX compiler identification is GNU 4.7.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/blubb/Programmierung/cmake_hello/build
make
-> Ausgabe:
Scanning dependencies of target hello
[100%] Building CXX object src/CMakeFiles/hello.dir/main.cpp.o
Linking CXX executable ../../bin/hello
CMakeFiles/hello.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x38): undefined reference to `Klasse::Klasse()'
collect2: Fehler: ld gab 1 als Ende-Status zurück
make[2]: *** [../bin/hello] Fehler 1
make[1]: *** [src/CMakeFiles/hello.dir/all] Fehler 2
make: *** [all] Fehler 2 |
Warum? Was fehlt mir?
Last edited by musv on Fri Jan 11, 2013 12:26 pm; edited 1 time in total |
|
Back to top |
|
|
firefly Watchman
Joined: 31 Oct 2002 Posts: 5173
|
Posted: Fri Jan 11, 2013 11:27 am Post subject: |
|
|
du musst bei add_executable alle sourcen angeben... _________________ Ein Ring, sie zu knechten, sie alle zu finden,
Ins Dunkel zu treiben und ewig zu binden
Im Lande Mordor, wo die Schatten drohn. |
|
Back to top |
|
|
musv Advocate
Joined: 01 Dec 2002 Posts: 3337 Location: de
|
Posted: Fri Jan 11, 2013 12:26 pm Post subject: |
|
|
Hast Recht. Es klappt.
Eigentlich war ich davon ausgegangen, dass cmake das irgendwie aus dem Quellcode und den darin angegebenen Abhängigkeiten selbst auf die Reihe bekommen. Aber nun gut, es funktioniert.
Danke |
|
Back to top |
|
|
franzf Advocate
Joined: 29 Mar 2005 Posts: 4565
|
Posted: Fri Jan 11, 2013 4:30 pm Post subject: |
|
|
musv wrote: | Eigentlich war ich davon ausgegangen, dass cmake das irgendwie aus dem Quellcode und den darin angegebenen Abhängigkeiten selbst auf die Reihe bekommen. Aber nun gut, es funktioniert. |
Kann GCC allein durch Übergabe einer main.cpp alle Abhähngigkeiten _selbständig_ ermitteln? Nö
Das Problem sollte recht komplex sein, cmake müsste dafür einen eigenen Parser für ALLE unterstützten Sprachen mitbringen. Größere Projekte würden dadurch allein fürs Makefile erzeugen ziemlich lange brauchen. |
|
Back to top |
|
|
AmonAmarth l33t
Joined: 03 Mar 2005 Posts: 727
|
Posted: Sun Jan 13, 2013 12:20 pm Post subject: |
|
|
Kleiner Tipp um nicht immer alle Dateien einzeln in die CMakeLists eintragen zu müssen:
Code: | file(GLOB Sources ${PROJECT_SOURCE_DIR}/src/*.cpp)
add_executable(Hello ${Sources} |
|
|
Back to top |
|
|
franzf Advocate
Joined: 29 Mar 2005 Posts: 4565
|
Posted: Sun Jan 13, 2013 12:30 pm Post subject: |
|
|
Globben würd ich nicht, weil man damit auch auf die Schnauze fallen kann. Z.B. wenn man eine Klasse umschreibt/splittet/... und die Implementierung in neue .cpp-Dateien packt -> multiple definition, wenn man nicht aufpasst. Und wenn man sich (dank GLOB) nicht mehr ums CMakeLists.txt kümmert, erinnert man sich am Ende gar nicht mehr daran... |
|
Back to top |
|
|
AmonAmarth l33t
Joined: 03 Mar 2005 Posts: 727
|
Posted: Sun Jan 13, 2013 12:40 pm Post subject: |
|
|
franzf wrote: | Globben würd ich nicht, weil man damit auch auf die Schnauze fallen kann. Z.B. wenn man eine Klasse umschreibt/splittet/... und die Implementierung in neue .cpp-Dateien packt -> multiple definition, wenn man nicht aufpasst. Und wenn man sich (dank GLOB) nicht mehr ums CMakeLists.txt kümmert, erinnert man sich am Ende gar nicht mehr daran... |
Dann wird der compiler meckern, entweder wegen missing implementation oder double definition. Dann muss man einfach nur einmal cmake neu ausführen und fertig.
EDIT: oder meinst du, wenn man die implementierung von A.cpp nach B.cpp kopiert und nicht verschoben hat? Genau sowas sollte man meiner meinung nach noch weniger machen... |
|
Back to top |
|
|
|