Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: Compiler- und IDE-Forum ::  Frage zu Makefile für MINGW/GCC linker     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
McMorf
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.01.2011
Beiträge: 39
Beitrag McMorf Mitglied 13:24:52 20.01.2012   Titel:   Frage zu Makefile für MINGW/GCC linker            Zitieren

Hi !

Ich versuche mich gerade an Makefiles....
Mein Problem: Ich habe mir eine dll gebastelt, will die dazu passende lib(*.a)
über nen makefile mit meinem Projekt linken.

Scheinbar mache ich da etwas mit der Pfadangabe Falsch (vlt ist es auch was anderes)

Also mit nem shellscript funktioniert das:

Code:
g++ main.cpp dll.h -o main.exe -lm ../../../tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a
Code:
g++ main.cpp dll.h -o main.exe -lm ../../../tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a
Code:
g++ main.cpp dll.h -o main.exe -lm ../../../tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a


In meinem Makefile:

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
CC = gcc                                                                                    #c compiler
CPP = g++                                                                                   #c++ compiler
LD = $(CPP)                                                                                #linker
CFLAGS = -Wall -g                                                                         #compiler flags

LDDIR = -lm  ../../../tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a
LDFLAGS = $(LDDIR)                                                                      #linker flags
RM = rm -f                                                                                  #clean (löschen)

OBJS = main.o
SRCS = main.cpp
PROG = main.exe


all: $(OBJS)
    $(LD) $(LDFLAGS) $(OBJS) -o $(PROG)

# *.o aus *.c erstellen
%.o: %.c
    $(CPP) $(CFLAGS) -c $<

#abhängigkeiten bilden
depend:
    $(CPP) $(CFLAGS) -MM $(SRCS) > depend

run: all
    $(PROG)

include depend

clean:
    $(RM) $(PROG)
    $(RM) *.o
    $(RM) depend
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
CC = gcc #c compiler
CPP = g++ #c++ compiler
LD = $(CPP) #linker
CFLAGS = -Wall -g #compiler flags

LDDIR = -lm ../../../tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a
LDFLAGS = $(LDDIR) #linker flags
RM = rm -f #clean (löschen)

OBJS = main.o
SRCS = main.cpp
PROG = main.exe


all: $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) -o $(PROG)

# *.o aus *.c erstellen
%.o: %.c
$(CPP) $(CFLAGS) -c $<

#abhängigkeiten bilden
depend:
$(CPP) $(CFLAGS) -MM $(SRCS) > depend

run: all
$(PROG)

include depend

clean:
$(RM) $(PROG)
$(RM) *.o
$(RM) depend
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
CC = gcc                                                                                    #c compiler
CPP = g++                                                                                   #c++ compiler
LD = $(CPP)                                                                                #linker
CFLAGS = -Wall -g                                                                         #compiler flags

LDDIR = -lm  ../../../tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a
LDFLAGS = $(LDDIR)                                                                      #linker flags
RM = rm -f                                                                                  #clean (löschen)

OBJS = main.o
SRCS = main.cpp
PROG = main.exe


all: $(OBJS)
    $(LD) $(LDFLAGS) $(OBJS) -o $(PROG)

# *.o aus *.c erstellen
%.o: %.c
    $(CPP) $(CFLAGS) -c $<

#abhängigkeiten bilden
depend:
    $(CPP) $(CFLAGS) -MM $(SRCS) > depend

run: all
    $(PROG)

include depend

clean:
    $(RM) $(PROG)
    $(RM) *.o
    $(RM) depend


funktioniert das leider nicht, was mache ich hier falsch ?
Ich habe auch schon versucht den Pfad direkt anzugeben(leider kein Erfolg)

Die Ausgabe in der Konsole(cygwin) lässt mich darauf schließen das die lib nicht richtig verlinkt wurde...
Code:
$ make
g++                                                                                                                                                                                   -lm  ../../../tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a                                                         main.o  -o main.exe
main.o:main.cpp:(.text+0x174): undefined reference to `_imp___ZN8DllClassC1Ev'
main.o:main.cpp:(.text+0x1c2): undefined reference to `_imp___ZN8DllClass5HelloEv'
collect2: ld returned 1 exit status
make: *** [all] Error 1
Code:
$ make
g++ -lm ../../../tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a main.o -o main.exe
main.o:main.cpp:(.text+0x174): undefined reference to `_imp___ZN8DllClassC1Ev'
main.o:main.cpp:(.text+0x1c2): undefined reference to `_imp___ZN8DllClass5HelloEv'
collect2: ld returned 1 exit status
make: *** [all] Error 1
Code:
$ make
g++                                                                                                                                                                                   -lm  ../../../tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a                                                         main.o  -o main.exe
main.o:main.cpp:(.text+0x174): undefined reference to `_imp___ZN8DllClassC1Ev'
main.o:main.cpp:(.text+0x1c2): undefined reference to `_imp___ZN8DllClass5HelloEv'
collect2: ld returned 1 exit status
make: *** [all] Error 1


Ich würde mich über jedliche Hilfe sehr freuen und binn sehr gespannt was ich hier falsch mache !

Mfg McMorf

_________________
(\__/) This is Bunny. Copy Bunny into your signature to help him
(0.o ) on his way to world domination.
( >< ) <-- Hatt es mir einfach Angetahn..
rüdiger
Moderator

Benutzerprofil
Anmeldungsdatum: 11.07.2001
Beiträge: 22820
Beitrag rüdiger Moderator 14:15:14 20.01.2012   Titel:              Zitieren

1. CXX ist die Variable für den C++-Compiler. CPP ist der Präprozessor! CXXFLAGS sind die Flags für den C++-Compiler. CFLAGS sind die Flags für den C Compiler.
2. In Zeile 19 die Regel brauchst du vermutlich nicht. Du hast ja eh keine C-Dateien. Außerdem hat Make implizite Regeln für cpp und c Dateien. (Daher auch 1. beachten!)
3. Sollten all, run, clean als PHONY markiert werden, da sie ja keinen Dateien entsprechen.
4. all sollte vielleicht eine Abhängigkeit auf depend haben.
5. Du hast leider in deiner Konsolenausgabe ausgelassen, wie der g++ genau ausgerufen wird.

Siehe auch: http://www.c-plusplus.de/forum/88418
abc.w
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.04.2008
Beiträge: 1364
Beitrag abc.w Mitglied 15:04:00 21.01.2012   Titel:              Zitieren

Ich hatte mal ein "dll"-Beispiel aus dem Buch "Windows Programmierung" von Charles Petzold mit mingw gebaut und folgendes Makefile geschrieben:
Code:
all:
    mingw32-gcc -c -DBUILD_DLL EdrLib.c
    mingw32-gcc -shared -o EdrLib.dll -Wl,--out-implib,libEdrLib.a EdrLib.o -mwindows
    mingw32-gcc EdrTest.c -o EdrTest.exe -pedantic -Wall -mwindows -ggdb -L./ -lEdrLib
Code:
all:
mingw32-gcc -c -DBUILD_DLL EdrLib.c
mingw32-gcc -shared -o EdrLib.dll -Wl,--out-implib,libEdrLib.a EdrLib.o -mwindows
mingw32-gcc EdrTest.c -o EdrTest.exe -pedantic -Wall -mwindows -ggdb -L./ -lEdrLib
Code:
all:
    mingw32-gcc -c -DBUILD_DLL EdrLib.c
    mingw32-gcc -shared -o EdrLib.dll -Wl,--out-implib,libEdrLib.a EdrLib.o -mwindows
    mingw32-gcc EdrTest.c -o EdrTest.exe -pedantic -Wall -mwindows -ggdb -L./ -lEdrLib

Vielleicht hilft es weiter.

(PS: man kann das Makefile natürlich beliebig kompliziert machen)

_________________
E = int * char^2
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 10:40:42 24.01.2012   Titel:   Erst mal Danke für die Antworten !            Zitieren

Erst mal Danke für die Antworten !

wo genau jetzt mein fehler liegt wurde leider nicht vollständig geklährt...
ich werde mich wohl noch ein bischen weiter damit auseinander setzen müssen...

Trotzdem danke, da hab ich erst mal ein paar infos wo ich vlt. drauf aufbauen kan...

Mfg McMorf
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 15:00:12 24.01.2012   Titel:   schade            Zitieren

hmmm... irgendwie hilft mir keine dieser antworten wirklich weiter...
dann muss ich mir wohl shell scripte dafür bauen...

trotzdem danke für den versuch !
f.-th.
Unregistrierter




Beitrag f.-th. Unregistrierter 16:03:44 24.01.2012   Titel:              Zitieren

Bei deinem Shellscript:
Code:
g++ main.cpp dll.h -o main.exe -lm ...
Code:
g++ main.cpp dll.h-o main.exe -lm ...
Code:
g++ main.cpp dll.h -o main.exe -lm ...


Die dll.h kommt mir ungewöhnlich vor :confused:

Erwarte da, wenn es C++ werden soll, nur Dateinamen mit der Endung '.cpp' oder ähnliche, aber keine '.h'.

Wenn deine dll.h nicht zu lang ist, zeig die mal.

MfG f.-th.
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 16:27:08 24.01.2012   Titel:   Hier mal die SourceCodes            Zitieren

dll.h
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef _DLL_H_
#define
_DLL_H_

#if
BUILDING_DLL
# define
DLLIMPORT __declspec (dllexport)
#else
/* Not BUILDING_DLL */
# define
DLLIMPORT __declspec (dllimport)
#endif
/* Not BUILDING_DLL */


class DLLIMPORT DllClass
{
  public:
    DllClass();
    virtual ~DllClass(void);

    void Hello(void);

  private:

};


#endif
/* _DLL_H_ */
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef _DLL_H_
#define
_DLL_H_

#if
BUILDING_DLL
# define
DLLIMPORT __declspec (dllexport)
#else
/* Not BUILDING_DLL */
# define
DLLIMPORT __declspec (dllimport)
#endif
/* Not BUILDING_DLL */


class DLLIMPORT DllClass
{
public:
DllClass();
virtual ~DllClass(void);

void Hello(void);

private:

};


#endif
/* _DLL_H_ */
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef _DLL_H_
#define
_DLL_H_

#if
BUILDING_DLL
# define
DLLIMPORT __declspec (dllexport)
#else
/* Not BUILDING_DLL */
# define
DLLIMPORT __declspec (dllimport)
#endif
/* Not BUILDING_DLL */


class DLLIMPORT DllClass
{
  public:
    DllClass();
    virtual ~DllClass(void);

    void Hello(void);

  private:

};


#endif
/* _DLL_H_ */

dll.cpp
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* Replace "dll.h" with the name of your header */
#include
"dll.h"
#include
<windows.h>

DLLIMPORT DllClass::DllClass()
{

}


DLLIMPORT DllClass::~DllClass ()
{

}

DLLIMPORT void DllClass::Hello(void)
{
    MessageBox(NULL, "Hallo Welt", "MsgBox", MB_OK | MB_ICONINFORMATION);
}


BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* Replace "dll.h" with the name of your header */
#include
"dll.h"
#include
<windows.h>

DLLIMPORT DllClass::DllClass()
{

}


DLLIMPORT DllClass::~DllClass ()
{

}

DLLIMPORT void DllClass::Hello(void)
{
MessageBox(NULL, "Hallo Welt", "MsgBox", MB_OK | MB_ICONINFORMATION);
}


BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
break;

case DLL_PROCESS_DETACH:
break;

case DLL_THREAD_ATTACH:
break;

case DLL_THREAD_DETACH:
break;
}

/* Returns TRUE on success, FALSE on failure */
return TRUE;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* Replace "dll.h" with the name of your header */
#include
"dll.h"
#include
<windows.h>

DLLIMPORT DllClass::DllClass()
{

}


DLLIMPORT DllClass::~DllClass ()
{

}

DLLIMPORT void DllClass::Hello(void)
{
    MessageBox(NULL, "Hallo Welt", "MsgBox", MB_OK | MB_ICONINFORMATION);
}


BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}

main.cpp:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cstdlib>
#include
<iostream>
#include
<windows.h>
#include
"dll.h"

using namespace std;

int main(int argc, char *argv[])
{
    DllClass *dll = new DllClass();
    dll->Hello();
    delete dll;

    system("PAUSE");
    return 0;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cstdlib>
#include
<iostream>
#include
<windows.h>
#include
"dll.h"

using namespace std;

int main(int argc, char *argv[])
{
DllClass *dll = new DllClass();
dll->Hello();
delete dll;

system("PAUSE");
return 0;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cstdlib>
#include
<iostream>
#include
<windows.h>
#include
"dll.h"

using namespace std;

int main(int argc, char *argv[])
{
    DllClass *dll = new DllClass();
    dll->Hello();
    delete dll;

    system("PAUSE");
    return 0;
}


und das shellScript was ich mir jetzt gebaut habe:
Code:
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
#Under WINDOWS(CYGWIN) dont forget 2 run dos2unix [scriptname]
COMPILER=g++
SOURCES=main.cpp
HEADERS=dll.h
OUTPUT=main.exe
LIBS=/tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a

echo "$COMPILER $SOURCES $HEADERS -o $OUTPUT -lm $LIBS"
$COMPILER $SOURCES $HEADERS -o $OUTPUT -lm $LIBS
Code:
1
2
3
4
5
6
7
8
9
#Under WINDOWS(CYGWIN) dont forget 2 run dos2unix [scriptname]
COMPILER=g++
SOURCES=main.cpp
HEADERS=dll.h
OUTPUT=main.exe
LIBS=/tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a

echo "$COMPILER $SOURCES $HEADERS -o $OUTPUT -lm $LIBS"
$COMPILER $SOURCES $HEADERS -o $OUTPUT -lm $LIBS
Code:
1
2
3
4
5
6
7
8
9
#Under WINDOWS(CYGWIN) dont forget 2 run dos2unix [scriptname]
COMPILER=g++
SOURCES=main.cpp
HEADERS=dll.h
OUTPUT=main.exe
LIBS=/tmpWorkspace/makefiles/dllStatischLinkenObjekte/libdllBsp1.a

echo "$COMPILER $SOURCES $HEADERS -o $OUTPUT -lm $LIBS"
$COMPILER $SOURCES $HEADERS -o $OUTPUT -lm $LIBS


und mir geht es eigendlich garnicht um die dll sondern generell um libs also sowohl unter windoof wie auch unter linux....

Ich frage mich auch welchen vorteil eine makefile gegenüber einem shellscript hat ?!?

naja wie gesagt finde den fehler in meinem makefile nicht, denke aber das das irgendwas mit der ordnerangabe zu tun haben muss... notfalls würde mir aber wirklich auch ein shellscript reichen, hauptsache es funktioniert... und ich bleibe platformunabhängig (was sich natürlich mit ner dll beist) es geht mir ja nur um das algemeine verständniss

Mfg McMorf
f.-th.
Unregistrierter




Beitrag f.-th. Unregistrierter 21:41:58 24.01.2012   Titel:              Zitieren

Die Lösung hab ich jetzt nicht, aber:
Weder im Makefile noch sonst wo hat da 'dll.h' etwas zu suchen :warning:
Da musst du etwas mit deiner 'dll.cpp' schreiben :warning:
Im Quelltext deiner 'dll.cpp' ist der Header 'dll.h' ja schon eingebunden.
Ebenso in 'main.cpp'. Das reicht!

Da du spezielle Windows-Funktionen im Quelltext nutzt musst du dies dem Linker bekannt geben :warning:
Also muss da irgend so was im Makefile stehen, wie abc.w schon schrieb: -mwindows
Eventuell gibt es da noch einen weiteren Weg.

Ursprünglich wurden DLL's für Windows mit einer C-konformen Schnittstelle konzipiert. Abweichungen davon sind heute möglich, bringen dem Programmierer oft viel Spass ;)

Da dein Quelltext sehr Windows-lastig ist wirst du den ohne deutliche Modifizierungen kaum unter Linux zum Laufen bekommen.

Wenn du das vorhast, solltest du dich in eine Bibliothek einarbeiten die beide Betriebssysteme unterstützt.

f.-th.
f.-th.
Unregistrierter




Beitrag f.-th. Unregistrierter 22:04:32 24.01.2012   Titel:              Zitieren

Hier noch etwas zu deiner DLL:
http://msdn.microsoft.com/de-de/library/3y1sfaz2.aspx

Auf deutsch 'DLLIMPORT' gibt es nur bei Microsoft.
Und ob du da die Gross- und Kleinschreibung beliebig nutzen kannst :confused:
Das gibt unter C und C++ meist Ärger.

MfG f.-th.
f.-th.
Unregistrierter




Beitrag f.-th. Unregistrierter 22:12:55 24.01.2012   Titel:              Zitieren

Zu dllimport und gcc gibt es schon einen Beitrag:
http://www.c-plusplus.de/forum/245780
und hier auch noch:
http://gcc.gnu.org/wiki/Visibility

MfG f.-th.
f.-th.
Unregistrierter




Beitrag f.-th. Unregistrierter 22:31:10 24.01.2012   Titel:              Zitieren

f.-th. schrieb:

Auf deutsch 'DLLIMPORT' gibt es nur bei Microsoft.
Und ob du da die Gross- und Kleinschreibung beliebig nutzen kannst :confused:
Das gibt unter C und C++ meist Ärger.


Das ist Blödsinn. Siehe Links. :mad:

Aber trotzdem in deiner Microsoft-dll.h nachsehen:
export <=> import :confused:

MfG f.-th.
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 09:54:26 25.01.2012   Titel:   verwirrt            Zitieren

-mwindows führt bei einem konsolen prg nur dazu das keine konsole gebildet wird...
DLLIMPORT ist eine Konstante da ist Groß/Klein schreibung geschmackssache...
noch dazu habe ich diese dll ganz schnell mit dev-cpp erstellt und das war erst mal vorgabe, was man auch an den komentaren sehen kann...

gut... in meinem shell script brauch ich die dll.h wirklich nicht angeben ich dachte immer das macht man so :o) naja jut 1 schritt weiter...

das problem ist aber nicht in meiner dll zu suchen, sondern irgendwo in meiner makefile :confused:

Natürlich will ich keine dll auf linux verwenden die dll hab ich nur zum testen benutzt mir geht es eher generell ums verlinken was ist z.B wenn ich unter M$ die libole32.a linken will oder sonst irgend eine lib ?!?
abc.w
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.04.2008
Beiträge: 1364
Beitrag abc.w Mitglied 22:39:46 25.01.2012   Titel:   Re: verwirrt            Zitieren

McMorf! schrieb:
das problem ist aber nicht in meiner dll zu suchen, sondern irgendwo in meiner makefile :confused:

Ich verstehe das Problem nicht. Schau Dir mein Makefile an, es wird von oben nach unten, von links nach rechts abgearbeitet. Es werden eine dll, eine .a und schließlich eine exe erstellt. Beim Erstellen der exe bekommt der Compiler die Parameter "-L./ -lEdrLib" und sie sagen dem Compiler, in welchem Verzeichnis die EdrLib zu suchen ist (wie man sieht, im aktuellen Verzeichnis ./). Keine Hexerei also. Du müsstest irgendwo im Makefile "-L/tmpWorkspace/makefiles/dllStatischLinkenObjekte/" an gcc übergeben, damit gcc weiss, in welchem Verzeichnis die Bibliothek zu suchen ist (absolute Pfade sind aber Scheiße...). Das war's.

Schau noch mal mein Makefile und Dein Makefile an. Meins ist einfach, deins ist kompliziert. Muss es so kompliziert sein :confused:

_________________
E = int * char^2
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 18:50:18 26.01.2012   Titel:   Also irgendwie habe ich in meinem Makefile den fehler immer noch nicht...            Zitieren

Also abc.w anich währe deine lösung für mich bei größeren Projekten einfach zu viel schreibarbeit auserdem finde ich wird es dann unübersichtlich...
vlt einfach nur geschmackssache.....

Aber ne generelle Frage habe ich trotzdem...
Also jetzt mal kurz vom makefile weck...:

Habe jetzt erst mal nen ShellScript (welches ich recht übersichtlich finde) gebastelt...
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#(CYGWIN) run dos2unix [scriptname]
COMPILER="g++"
SOURCES="main.cpp"
HEADERS=""
CFLAGS="-mwindows -Wall"
OUTPUT="main.exe"
LDIR=""
LIBS=""
OWNLDIR="/tmpWorkspace/makefiles/dllStatischLinkenObjekte/"
OWNLIBS="libdllBsp1.a"

#Absolute Pfandangabe zusammen setzen:
LIBS=" $LIBS"
LDIR=" $LDIR"
LIBS="${LIBS// /$LDIR}"
OWNLIBS=" $OWNLIBS"
OWNLDIR=" $OWNLDIR"
OWNLIBS="${OWNLIBS// /$OWNLDIR}"

#Ausgabe an Kompiler:
echo "$COMPILER $SOURCES -o $OUTPUT -lm $LIBS $OWNLIBS $CFLAGS"
$COMPILER $SOURCES -o $OUTPUT -lm $LIBS $OWNLIBS $CFLAGS
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#(CYGWIN) run dos2unix [scriptname]
COMPILER="g++"
SOURCES="main.cpp"
HEADERS=""
CFLAGS="-mwindows -Wall"
OUTPUT="main.exe"
LDIR=""
LIBS=""
OWNLDIR="/tmpWorkspace/makefiles/dllStatischLinkenObjekte/"
OWNLIBS="libdllBsp1.a"

#Absolute Pfandangabe zusammen setzen:
LIBS=" $LIBS"
LDIR=" $LDIR"
LIBS="${LIBS// /$LDIR}"
OWNLIBS=" $OWNLIBS"
OWNLDIR=" $OWNLDIR"
OWNLIBS="${OWNLIBS// /$OWNLDIR}"

#Ausgabe an Kompiler:
echo "$COMPILER $SOURCES -o $OUTPUT -lm $LIBS $OWNLIBS $CFLAGS"
$COMPILER $SOURCES -o $OUTPUT -lm $LIBS $OWNLIBS $CFLAGS
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#(CYGWIN) run dos2unix [scriptname]
COMPILER="g++"
SOURCES="main.cpp"
HEADERS=""
CFLAGS="-mwindows -Wall"
OUTPUT="main.exe"
LDIR=""
LIBS=""
OWNLDIR="/tmpWorkspace/makefiles/dllStatischLinkenObjekte/"
OWNLIBS="libdllBsp1.a"

#Absolute Pfandangabe zusammen setzen:
LIBS=" $LIBS"
LDIR=" $LDIR"
LIBS="${LIBS// /$LDIR}"
OWNLIBS=" $OWNLIBS"
OWNLDIR=" $OWNLDIR"
OWNLIBS="${OWNLIBS// /$OWNLDIR}"

#Ausgabe an Kompiler:
echo "$COMPILER $SOURCES -o $OUTPUT -lm $LIBS $OWNLIBS $CFLAGS"
$COMPILER $SOURCES -o $OUTPUT -lm $LIBS $OWNLIBS $CFLAGS


Was währe der Nachteil eines solchen Scripts gegenüber einem Makefile ???

Mfg McMorf
abc.w
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.04.2008
Beiträge: 1364
Beitrag abc.w Mitglied 21:57:08 26.01.2012   Titel:   Re: Also irgendwie habe ich in meinem Makefile den fehler immer noch nicht...            Zitieren

McMorf! schrieb:
Also abc.w anich währe deine lösung für mich bei größeren Projekten einfach zu viel schreibarbeit auserdem finde ich wird es dann unübersichtlich...

Ja, natürlich, bei größeren Projekten muss man die Struktur des Makefiles überdenken. Mein Makefile baut ja die Dateien jedes Mal neu, ob sie sich geändert haben oder nicht, kostet Zeit und Zeit ist Geld.

McMorf! schrieb:
Was währe der Nachteil eines solchen Scripts gegenüber einem Makefile ???

Mit dem Skript versuchst Du die Funktionalität des Tools make nachzubauen, also ein Tool, was schon da ist und von Profis speziell für diese Zwecke entwickelt wurde und sich in der Praxis bewährt hatte. make bringt ja noch Automatismen mit: Prüfst Du im Skript den Rückgabewert des Compilers? Nein (oder ich sehe es nicht, weil müde, will schlafen oder sonstiges). make würde bei einem aufgetretenen Fehler die Abarbeitung des Makefiles sofort abbrechen. Nutzt Dein Skript mehrere Kerne aus? Nein, ein Skript wird von oben nach unten abgearbeitet. Mit make könnte man die Aufgabe auf mehrere CPU-Kerne verteilen, d.h. man könnte ein Projekt deutlich schneller bauen, mit dem Skript nicht.

_________________
E = int * char^2
f.-th.
Unregistrierter




Beitrag f.-th. Unregistrierter 00:12:08 27.01.2012   Titel:              Zitieren

Hier noch mal wie das auf Kommandozeile laut MinGW aufgerufen wird:
http://www.mingw.org/wiki/sampleDLL
Passende Umgebung (Path) setze ich mal voraus.

CYGWIN - nicht jeder hantiert in der Form mit dem MinGW.
Also läuft dein Script nicht überall. Hab die Möglichkeit bezüglich der Scripte unter den neuen Windows, Stichwort "Powershell", noch nicht in der Hinsicht getestet.

MfG f.-th.
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 09:16:57 27.01.2012   Titel:   Super Herzlichen Dank für die Antworten !            Zitieren

Super Herzlichen Dank für die Antworten !

Mit den letzten beiden Antworten (abc.w f.-th.) konnte ich richtig viel anfangen, das ist schon mal ne perfekte erklährung warum makefiles sinniger sind...

http://www.mingw.org/wiki/sampleDLL

Wird mir hoffentlich weiter helfen, sieht auf jeden fall so aus als könnte ich damit weiter kommen...

Den ansatz shell script werde ich dann mal vernachlässigen und mich weiter mit Makefiles beschäftigen... irgendwie muss ich das ja mal zum laufen bekommen ^^

Ihr habt mir auf jeden fall deutlich weiter geholfen !

Mfg McMorf
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 10:57:20 27.01.2012   Titel:   So, hab das jetzt mal total minimalistisch gemacht...            Zitieren

So, hab das jetzt mal total minimalistisch gemacht...
und ja, es funktioniert !

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CC = gcc                                                                                    
CPP = g++                                                                                  
LD = $(CPP)                                                                                
CFLAGS = -Wall -g                                                                        

LDDIR = -L./ -ldllBsp1
LDFLAGS = $(LDDIR)                                                                      
RM = rm -f                                                                                  

OBJS = main.o
SRCS = main.cpp
PROG = main.exe


all: $(OBJS)
    $(LD) $(SRCS) -o $(PROG) $(LDFLAGS)
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CC = gcc
CPP = g++
LD = $(CPP)
CFLAGS = -Wall -g

LDDIR = -L./ -ldllBsp1
LDFLAGS = $(LDDIR)
RM = rm -f

OBJS = main.o
SRCS = main.cpp
PROG = main.exe


all: $(OBJS)
$(LD) $(SRCS) -o $(PROG) $(LDFLAGS)
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CC = gcc                                                                                    
CPP = g++                                                                                  
LD = $(CPP)                                                                                
CFLAGS = -Wall -g                                                                        

LDDIR = -L./ -ldllBsp1
LDFLAGS = $(LDDIR)                                                                      
RM = rm -f                                                                                  

OBJS = main.o
SRCS = main.cpp
PROG = main.exe


all: $(OBJS)
    $(LD) $(SRCS) -o $(PROG) $(LDFLAGS)


jetzt hab ich ne frage die mich beschäftigt....
was hat das mit den *.o dateien genau auf sich ?
also bei meinem shell script z.b habe ich diese ja nicht gebildet....

und wofür brächte man das ?:
Code:
depend:
    $(CPP) $(CFLAGS) -MM $(SRCS) > depend
Code:
depend:
$(CPP) $(CFLAGS) -MM $(SRCS) > depend
Code:
depend:
    $(CPP) $(CFLAGS) -MM $(SRCS) > depend

das sind ja alles sachen die z.B von DEV-CPP auch mit gebildet würden, ich verstehe nur nicht wozu....

Aber trotzdem erst mal Danke für die tolle hilfe hier, so komme ich doch immer n stückchen weiter !!! Will halt so langsam mal verstehen ^^
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 11:06:07 27.01.2012   Titel:   also *.o hab ich schon mal verstanden...            Zitieren

also *.o hab ich schon mal verstanden...

hier speichert der compiler zwischen und deswegen muss nicht bei jeder Änderung das gesamte projekt neu kompiliert werden (denke nicht das meine progs so groß werden das ich das zwingend benötige)

bleibt nur noch die frage wozu depend ?

Mfg McMorf
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 12:22:55 27.01.2012   Titel:   Zum Thema mehrere Kerne            Zitieren

Zum Thema mehrere Kerne...

Also klar... nen shellScript bekomme ich ohne CYGWIN(o.ä.) nicht unter Windows zum Laufen... das verstehe ich....
Zitat:

Prüfst Du im Skript den Rückgabewert des Compilers?

bei einem Shellscript bricht MinGW bei error ab...
bei nem Makefile auch...
wozu den Rückgabewert überprüfen ? ich sehe es doch dann in der Shell ?!?

Was mir jetzt nicht ganz klar ist....:
Zitat:

Nutzt Dein Skript mehrere Kerne aus? Nein, ein Skript wird von oben nach unten abgearbeitet. Mit make könnte man die Aufgabe auf mehrere CPU-Kerne verteilen, d.h. man könnte ein Projekt deutlich schneller bauen, mit dem Skript nicht.


also mal auf mein beispiel bezogen:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
COMPILER=    G++                                                                              
SOURCE=     main.cpp
OUTPUT=     main.exe
CFLAGS=     -Wall -g -mwindows                                                                        
LDIR=         -L./
LIBS=        -lm libdllBsp1.a       
                                                                 
RM =         rm -f                                                                                  
OBJS=         main.o

LIBS1 = $(LDIR) $(LIBS)


all:
    $(COMPILER) -c $(SOURCE) -o $(OBJS)
    $(COMPILER) $(SOURCE) -o $(OUTPUT) $(LIBS1) $(CFLAGS)

clean:
    $(RM) $(PROG)
    $(RM) *.o
    $(RM) depend
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
COMPILER= G++
SOURCE= main.cpp
OUTPUT= main.exe
CFLAGS= -Wall -g -mwindows
LDIR= -L./
LIBS= -lm libdllBsp1.a

RM = rm -f
OBJS= main.o

LIBS1 = $(LDIR) $(LIBS)


all:
$(COMPILER) -c $(SOURCE) -o $(OBJS)
$(COMPILER) $(SOURCE) -o $(OUTPUT) $(LIBS1) $(CFLAGS)

clean:
$(RM) $(PROG)
$(RM) *.o
$(RM) depend
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
COMPILER=    G++                                                                              
SOURCE=     main.cpp
OUTPUT=     main.exe
CFLAGS=     -Wall -g -mwindows                                                                        
LDIR=         -L./
LIBS=        -lm libdllBsp1.a       
                                                                 
RM =         rm -f                                                                                  
OBJS=         main.o

LIBS1 = $(LDIR) $(LIBS)


all:
    $(COMPILER) -c $(SOURCE) -o $(OBJS)
    $(COMPILER) $(SOURCE) -o $(OUTPUT) $(LIBS1) $(CFLAGS)

clean:
    $(RM) $(PROG)
    $(RM) *.o
    $(RM) depend


wie würde ich das jetzt auf mehrere kerne aufteilen ?
und warum sollte das mit einem shellscript nicht gehen ? wird nicht letzten endes die aufgabe eh an MinGw übergeben ?

Fragen über fragen... sehe schon das thema wird mich noch länger beschäftigen ;)

Mfg McMorf
f.-th.
Unregistrierter




Beitrag f.-th. Unregistrierter 16:57:53 27.01.2012   Titel:              Zitieren

Eine 'test.cpp' wird compiliert zur 'test.o'.
Wenn die 'test.o' gelinkt wird es eine 'test.exe'

Das ist ein Einfachst-Beispiel beim MinGW.

Wenn es ein wenig umfangreicher wird kannst du auch mehrere '.o' Dateien zu einem Projekt zusammen linken. Das Ergebnis muss auch nicht 'test.exe' heissen. Da kannst du auch andere Namen mit der gleichen Endung '.exe' wählen.

Wenn eine der '.cpp' in einem grösseren Projekt nicht geändert wurde, brauchen nur die geänderten vor einem gemeinsamen Linken neu kompiliert werden.

Soweit eine Kurzfassung. Da kann man noch ausführlicher was dazu schreiben.

MfG f.-th.
abc.w
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.04.2008
Beiträge: 1364
Beitrag abc.w Mitglied 20:01:07 27.01.2012   Titel:   Re: Zum Thema mehrere Kerne            Zitieren

McMorf! schrieb:
Zbei einem Shellscript bricht MinGW bei error ab...
bei nem Makefile auch...
wozu den Rückgabewert überprüfen ? ich sehe es doch dann in der Shell ?!?

Wenn im Skript Hunderte Dateien gebaut werden, übersiehst Du die Fehlermeldung von MinGW. MinGW bricht bei einem Fehler ab, aber Dein Skript nicht. Dein Skript wird weiter abgearbeitet, egal was passiert. Wenn, dann müsste man bei jedem Aufruf des Compilers, Linkers usw. so was machen:
Code:
gcc -c blabla.c -o blabla.o || error
Code:
gcc -c blabla.c -o blabla.o || error
Code:
gcc -c blabla.c -o blabla.o || error

und error ist eine Funktion die exit aufruft o.ä. Aber das ist ungut, weil man beim Schreiben des Skripts daran denken muss, überall || error dranzuhängen. (Mit meinem Lieblings-Editor gVim wäre es vielleicht kein Problem).
McMorf! schrieb:
wie würde ich das jetzt auf mehrere kerne aufteilen ?

Bei Deinem Makefile wird es wahrscheinlich nicht funktionieren, weil Du im Prinzip nur einen Compiler-Aufruf hast. Es geht mit dem Parameter -j{X}, wobei es eine (ungeschriebene?) Regel gibt, X solle Anzahl der Kerne mal zwei sein. Ich habe einen DualCore, also würde ich so aufrufen:
Code:
make -j4
Code:
make -j4
Code:
make -j4

Bei einem QuadCore so
Code:
make -j8
Code:
make -j8
Code:
make -j8

McMorf! schrieb:
und warum sollte das mit einem shellscript nicht gehen ? wird nicht letzten endes die aufgabe eh an MinGw übergeben ?

Das geht bestimmt, nur musst Du als Autor des Skripts die Sisyphos-Arbeit erledigen, manuell Threads erzeugen, die bestimmte Teile deines Projektes bauen usw.

_________________
E = int * char^2
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 11:03:23 28.01.2012   Titel:   Dann erst mal danke !!!            Zitieren

Herzlichen Dank für die ganzen Antworten !

Ihr habt mir wirklich sehr weiter geholfen !

Mfg McMorf
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 12:35:17 06.02.2012   Titel:   noch eine Frage            Zitieren

Hi !
Ich habe noch eine Frage bezüglich makefiles...

Ich würde gerne wissen wie man die ausgabe eines Programms in eine Variable schreiben kann...

Sprich ich habe eine z.B hallo.exe die in der console nur hallo ausgibt...
diese würde ich gerne im makefile als variable angeben also so habe ich es versucht, funktioniert leider nicht:

Code:
VarHallo =´hallo.exe´
oder
VarHallo = @echo´hallo.exe´
Code:
VarHallo =´hallo.exe´
oder
VarHallo = @echo´hallo.exe´
Code:
VarHallo =´hallo.exe´
oder
VarHallo = @echo´hallo.exe´


also mir geht es darum die ausgabe von wx-config in eine variable umzuleiten sprich sowas wie:

Code:
WXCONFIG = ´wx-config --cxxflags --libs´
Code:
WXCONFIG = ´wx-config --cxxflags --libs´
Code:
WXCONFIG = ´wx-config --cxxflags --libs´


irgendwie habe ich keinen ansatz dafür gefunden...
würde mich sehr über eure Hilfe freuen !

Mfg McMorf
McMorf!
Unregistrierter




Beitrag McMorf! Unregistrierter 12:40:33 06.02.2012   Titel:   habs...            Zitieren

VAR =$(shell wx-config --cxxflags --libs)

Mfg McMorf
C/C++ Forum :: Compiler- und IDE-Forum ::  Frage zu Makefile für MINGW/GCC linker   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.