Makefile c++ header probleme mit inline

ZuseZ3

Lt. Commander
Registriert
Jan. 2014
Beiträge
1.659
Hallo zusammen,
ich habe von einem Mathematiker ein Programm erhalten, dessen Struktur ich erstmal nicht ändern kann und welches zusammengefasst folgenden Aufbau besitzt:
Eine prog.cpp, welche #include a.h und #include b.h beinhaltet.
Es existieren keine a.cpp oder b.cpp, die Implementierungen sind in den headerdateien.
In a.h wird zusaetzlich mit inlinening gearbeitet. Was fuer folgen hat das auf mein makefile?
Das makefile soll bei der Aenderung von einer der drei Dateien alle drei neubauen (performance ist kein Kriterium). So sieht mein aktuelles Makefile aus:

CXX:=icpc
LDFLAGS=-g -mfpmath=387 -finline-functions
LDLIBS=-lgmp
prog: prog.o
$(CXX) $(LDFLAGS) -o prog $(LDLIBS)
prog.o: prog.cpp b.h a.o
$(CXX) $(LDFLAGS) -c prog.cpp a.o $(LDLIBS)
a.o: a.h
$(CXX) $(LDFLAGS) -c a.h

Normalerweise wäre der letzte Teil bei einem header wohl nicht notwendig, da mittels finline aber bereits die Implementierungen untergebracht ist hier jedoch schon? Zurzeit bekomme ich durch die a.h dutzende Fehler in dieser Richtung:

solvemodz.h(34): error: identifier "exit" is undefined
exit(1);
^

solvemodz.h(48): error: identifier "NULL" is undefined
return NULL;
^
Woran koennte das liegen?

Das es vom Ansatz her schöner geht ist mir klar, aber das kann ich mir nachher selbst beibringen.
 
Zuletzt bearbeitet:
Hier stand Blödsinn:
Es kann gut sein, dass ich mich Irre, aber eigentlich müsste folgendes reichen:
Code:
CXX:=icpc
LDFLAGS=-g -mfpmath=387 -finline-functions
LDLIBS=-lgmp
prog: prog.cpp
$(CXX) $(LDFLAGS) -o prog $(LDLIBS)

Header werden beim Compilieren vorübergehend in die Datei "kopiert", die sie einbindet. Daher sollten alle Funktionsimplementierungen automatisch mitkompiliert werden, wenn sie ebenfalls im Header stehen.

Es gibt hier mehrere Probleme: Wenn du Header kompilierst, erhältst du keine Objektdateien, sondern vorkompilierte Header. Diese lassen sich im Anschluss nicht Linken. Da deine Header Definitionen und Implementierungen enthalten, kannst du die Dateien auch nicht ohne Weiteres in .cpp umbenennen. Deshalb musst du den Code Umstrukturieren, damit das Funktioniert.

Entweder du trennst das ganze sauber in .cpp und .h (und setzt entspechende #pragma once und #include "") oder du benennst die .h dateien in .cpp um, entfernst die Funktionsdeklarationen und deklarierst in den Dateien, die diese jeweils nutzen würden die Funktionen als "extern". Dann musst du aber auch a.cpp und b.cpp als shared library bauen und nachher statisch einbinden, um Linkerfehlern entgegenzuwirken.

Für Variante 2 habe ich dir ein Beispiel (für Mingw64, gegebenenfalls Dateiendungen im Makefile ändern) angehängt, aber ohne dass du deinen Code zur Verfügung stellst, gestaltet sich weitere Hilfe aber als schwierig.

Makefile_Beispiel
 
Zuletzt bearbeitet:
Da fehlt das Headerfile mit den Deklarationen für NULL und exit(). Wobei es eventuell nur an der Reihenfolge der #includes in prog.cpp liegt. NULL und exit() sind in stdlib.h bzw. cstdlib deklariert. Somit sollte dieses Headerfile auch vor dem "Benutzer" solvemodz.h includiert werden.
 
@kiffmet, es scheint als hättest du da Ahnung von. Das auftrennen in cpp und h würde ich gerne lassen, da das inlinen extra wegen der Performance durchgeführt wurde. Den ganzen Code möchte ich zur Sicherheit nicht rausgeben, da das ganze später publiziert wird und ich mich da nicht zu sehr auskenne. Hast du noch eine andere Idee wenn man bedenkt, dass alles in einem Schritt (s.u.) funktioniert?
Dein Makefile Beispiel funktioniert btw. leider nicht, die Datei scheint leer zu sein (0 MB?) bzw. lässt sich nicht öffnen unter Linux.

@mkossmann, ich denke du konzentrierst dich zu sehr auf die Symptome, die Ursache ist recht sicher eine andere.

icpc prog.cpp -oprog -O3 -mfpmath=387 -finline-functions funktioniert problemlos.

Zur Sicherheit habe ich gerade auch noch mal folgendes probiert, das ging natürlich auch (halt ohne Zwischenschritte) Sehe ich es richtig, dass ich es bei der aktuellen Vermischung von definition und implementierung nicht granularer hinbekomme?

CXX:=icpc
LDFLAGS=-g -O3 -mfpmath=387 -finline-functions
LDLIBS=-lgmp
prog: prog.cpp a.h b.h
$(CXX) $(LDFLAGS) prog.cpp $(LDLIBS)
 
Zuletzt bearbeitet:
Ich nehme mal an in prog.cpp steht
...
#include <cstdlib>
...
#include "a.h"


In a.h gibt es aber kein weiteres #include <cstdlib>

Dann ist zu dem Zeitpunkt, wo du a.h standalone compilieren willst , der Inhalt von cstdlib und damit die Deklarationen von NULL und exit() dem Compiler nicht bekannt und er reagiert mit den von dir beschriebenen Fehlermeldungen.
Das wird auch auftreten , wenn du versuchst das Headerfile in Deklarationen und Implementation zu trennen. Du müsstest in jedem Fall dafür sorgen das der Compiler cstdlib inkludiert . Entweder durch durch Ergänzen im Quellcode von a.h oder durch equivalente Kommandozeilenoptionen
 
Zurück
Oben