Frage zu Makefile für MINGW/GCC linker
-
Die Lösung hab ich jetzt nicht, aber:
Weder im Makefile noch sonst wo hat da 'dll.h' etwas zu suchen
Da musst du etwas mit deiner 'dll.cpp' schreiben
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
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.
-
Hier noch etwas zu deiner DLL:
http://msdn.microsoft.com/de-de/library/3y1sfaz2.aspxAuf deutsch 'DLLIMPORT' gibt es nur bei Microsoft.
Und ob du da die Gross- und Kleinschreibung beliebig nutzen kannst
Das gibt unter C und C++ meist Ärger.MfG f.-th.
-
Zu dllimport und gcc gibt es schon einen Beitrag:
http://www.c-plusplus.net/forum/245780
und hier auch noch:
http://gcc.gnu.org/wiki/VisibilityMfG f.-th.
-
f.-th. schrieb:
Auf deutsch 'DLLIMPORT' gibt es nur bei Microsoft.
Und ob du da die Gross- und Kleinschreibung beliebig nutzen kannst
Das gibt unter C und C++ meist Ärger.Das ist Blödsinn. Siehe Links.
Aber trotzdem in deiner Microsoft-dll.h nachsehen:
export <=> importMfG f.-th.
-
-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 naja jut 1 schritt weiter...
das problem ist aber nicht in meiner dll zu suchen, sondern irgendwo in meiner makefile
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 ?!?
-
McMorf! schrieb:
das problem ist aber nicht in meiner dll zu suchen, sondern irgendwo in meiner makefile
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 eineexe
erstellt. Beim Erstellen derexe
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
-
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...
#(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
-
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. Mitmake
könnte man die Aufgabe auf mehrere CPU-Kerne verteilen, d.h. man könnte ein Projekt deutlich schneller bauen, mit dem Skript nicht.
-
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.
-
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
-
So, hab das jetzt mal total minimalistisch gemacht...
und ja, es funktioniert !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 ?:
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 ^^
-
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
-
Zum Thema mehrere Kerne...
Also klar... nen shellScript bekomme ich ohne CYGWIN(o.ä.) nicht unter Windows zum Laufen... das verstehe ich....
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....:
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:
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
-
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.
-
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:
gcc -c blabla.c -o blabla.o || error
und
error
ist eine Funktion dieexit
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:
make -j4
Bei einem QuadCore so
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.
-
Herzlichen Dank für die ganzen Antworten !
Ihr habt mir wirklich sehr weiter geholfen !
Mfg McMorf
-
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: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:
WXCONFIG = ´wx-config --cxxflags --libs´
irgendwie habe ich keinen ansatz dafür gefunden...
würde mich sehr über eure Hilfe freuen !Mfg McMorf
-
VAR =$(shell wx-config --cxxflags --libs)
Mfg McMorf