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.aspx

    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.

    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/Visibility

    MfG 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 <=> import 😕

    MfG 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 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 😕



  • 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. 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.



  • 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 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:

    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


Anmelden zum Antworten