Was machen Programmier-Anfänger mit ihren Fragen?

Smalltalk
Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 24.04.2019 12:14:57

Das hoert sich gut an.

Du solltest es im gleichen Makefile realisieren koennen. Ich finde es nett, wenn man nach `make all' ein `make test' ausfuehren kann.
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 24.04.2019 14:19:53

So? (Funktioniert jedenfalls...)

Code: Alles auswählen

# rfm - Robert's file manager
# See LICENSE file for copyright and license details.
.POSIX:

INCS = -I. -I/usr/include
LIBS = -lncursesw
CPPFLAGS = -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700

CFLAGS = -ggdb -std=c99 -pedantic -Wall -Wextra -O0 $(INCS) $(CPPFLAGS)
LDFLAGS = $(LIBS)
CC = gcc

BIN = rfm
HDR = def.h config.h rfm.h
SRC = bind.c curses.c dir.c display.c filter.c info.c mycmp.c rfm.c wrappers.c
OBJ = ${SRC:.c=.o}

BIN_TEST = test/mycmp_test
HDR_TEST = test/mycmp_test.h
SRC_TEST = test/mycmp_test.c
OBJ_TEST = ${SRC_TEST:.c=.o}

all: $(BIN)

$(BIN): $(OBJ)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN) $^

$(OBJ): %.o: %.c $(HDR)
	$(CC) $(CFLAGS) -c -o $@ $<

clean:
	rm -f $(BIN) $(OBJ) $(BIN_TEST) $(OBJ_TEST)

test: $(BIN_TEST)

$(BIN_TEST): $(OBJ_TEST) mycmp.o
	$(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN_TEST) $^

$(OBJ_TEST): %.o: %.c $(HDR_TEST)
	$(CC) $(CFLAGS) -c -o $@ $<


.PHONY: all clean test

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 28.04.2019 17:01:40

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
24.04.2019 14:19:53
So?
?
RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
24.04.2019 14:19:53

Code: Alles auswählen

$(BIN_TEST): $(OBJ_TEST) mycmp.o
Welche Regel greift eigentlich für "mycmp.o"? So wie ich es verstehe, müsste das die von "$(OBJ)" sein, richtig?
(Bei der Regel für "$(BIN_TEST)" habe ich noch die LDFLAGS entfernt, da ncurses da ja nicht gebraucht wird.)

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 29.04.2019 10:43:06

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
28.04.2019 17:01:40
RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
24.04.2019 14:19:53
So?
?
War das ein Wunsch nach Feedback auf den du keines bekommen hast und dich nun fragst warum nicht? ;-)
RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
24.04.2019 14:19:53

Code: Alles auswählen

$(BIN_TEST): $(OBJ_TEST) mycmp.o
Welche Regel greift eigentlich für "mycmp.o"? So wie ich es verstehe, müsste das die von "$(OBJ)" sein, richtig?
(Bei der Regel für "$(BIN_TEST)" habe ich noch die LDFLAGS entfernt, da ncurses da ja nicht gebraucht wird.)
So Zeugs wie:

Code: Alles auswählen

$(OBJ): %.o: %.c $(HDR)
kenne ich nicht, darum kann ich dazu leider nichts sagen. Keine Ahnung, ob Make die verwendet ... weil ich schon nicht weiss, was die inhaltlich eigentlich besagt. Wie dem auch sei, Make kann *.o aus *.c automatisch bauen, mittels seiner impliziten (internen) Regeln. Dabei wird die Variable CFLAGS (und anderen Variablen die den Standardnamen entsprechen) automatisch beruecksichtigt.

Btw: Wenn du ein Programm mit nur einer einzigen Datei ``foo.c'' hast, dann kannst du das -- ganz ohne Makefile! -- mittel ``make foo'' bauen! Make arbeitet dann komplett mit internen Regeln. Das geht halt nur solange es 1:1-Beziehungen sind. Sobald es Abhaengigkeiten zwischen Dateien gibt, kann Make die nicht automatisch kennen und braucht diese Information dann ueber ein Makefile.
Use ed once in a while!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 29.04.2019 11:29:54

Meillo hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 10:43:06
War das ein Wunsch nach Feedback auf den du keines bekommen hast und dich nun fragst warum nicht? ;-)
Wenn Du so fragst, ja. ... Aber wie darf ich das jetzt verstehen?

Dies:

Code: Alles auswählen

$(OBJ): %.o: %.c $(HDR)
ist eine "static pattern"-Regel: https://www.gnu.org/software/make/manua ... atic-Usage
Damit kann ich unterschiedliche Rezepte aufstellen für $(OBJ) und $(OBJ__TEST). Das brauche ich zwar im Moment vielleicht nicht, aber ich mache das Ganze ja um was zu lernen und deswegen lote ich eben ein bisschen aus, was so möglich ist.
Außerdem schien es mir nötig, für "$(OBJ)" und "$(OBJ_TEST)" unterschiedliche Regeln zu schaffen, da dafür ja unterschiedliche Header benötigt werden...
Aber vielleicht habe ich das mit der Header-Zuteilung noch nicht verstanden, denn es scheint gar keine Angabe von Headern notwendig zu sein.
Diese Makefile funktioniert nämlich auch:

Code: Alles auswählen

# See LICENSE file for copyright and license details.
.POSIX:

INCS = -I. -I/usr/include
LIBS = -lncursesw
CPPFLAGS = -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700

CFLAGS = -ggdb -std=c99 -pedantic -Wall -Wextra -O0 $(INCS) $(CPPFLAGS)
LDFLAGS = $(LIBS)
CC = gcc

BIN = rfm
SRC = bind.c curses.c curses_readline.c dir.c display.c filter.c info.c mycmp.c rfm.c wrappers.c
OBJ = ${SRC:.c=.o}

BIN_TEST = test/mycmp_test
SRC_TEST = test/mycmp_test.c
OBJ_TEST = ${SRC_TEST:.c=.o}

%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<

all: $(BIN)

$(BIN): $(OBJ)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN) $^

clean:
	rm -f $(BIN) $(OBJ) $(BIN_TEST) $(OBJ_TEST)

test: $(BIN_TEST)

$(BIN_TEST): $(OBJ_TEST) mycmp.o
	$(CC) $(CFLAGS) -o $(BIN_TEST) $^

.PHONY: all clean test

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von Meillo » 29.04.2019 11:39:07

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 11:29:54
Meillo hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 10:43:06
War das ein Wunsch nach Feedback auf den du keines bekommen hast und dich nun fragst warum nicht? ;-)
Wenn Du so fragst, ja. ... Aber wie darf ich das jetzt verstehen?
Ich habe nur versucht dein Fragezeichen in Worte zu fassen. Vermutlich hat niemand auf deine Frage (``So?'') reagiert, weil niemandem etwas Offensichtliches aufgefallen ist und weil du schon geschrieben hast, dass es funktioniert und weil niemand sich die Muehe gemacht hat, genauer hinzuschauen.

Dies:

Code: Alles auswählen

$(OBJ): %.o: %.c $(HDR)
ist eine "static pattern"-Regel: https://www.gnu.org/software/make/manua ... atic-Usage
Damit kann ich unterschiedliche Rezepte aufstellen für $(OBJ) und $(OBJ__TEST). Das brauche ich zwar im Moment vielleicht nicht, aber ich mache das Ganze ja um was zu lernen und deswegen lote ich eben ein bisschen aus, was so möglich ist.
Das ist auch recht so. Ich kann dir dabei halt nicht helfen. Aber dieses Forum bin ja nicht nur ich -- zum Glueck! :-D
Außerdem schien es mir nötig, für "$(OBJ)" und "$(OBJ_TEST)" unterschiedliche Regeln zu schaffen, da dafür ja unterschiedliche Header benötigt werden...
Aber vielleicht habe ich das mit der Header-Zuteilung noch nicht verstanden, denn es scheint gar keine Angabe von Headern notwendig zu sein.
Diese Makefile funktioniert nämlich auch:
[...]
Was heisst ``funktionieren''? Aendere etwas in einer C-Datei und es funktioniert. Aendere nur etwas in einem Header und er wird gar nicht neu kompilieren wollen, weil noch alles up-to-date sei! (Vermute ich, ohne genauer hingeschaut zu haben.)

Ein Makefile ist ein Abhaengigkeitsgraph. Jede Datei, die einen Beitrag zu anderen Dateien leistet, muss (explizit oder implizit) aufgefuehrt sein.
Use ed once in a while!

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von JTH » 29.04.2019 15:03:16

Mag kleine Fehler enthalten, mein make ist etwas eingestaubt:
RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 11:29:54
Aber vielleicht habe ich das mit der Header-Zuteilung noch nicht verstanden, denn es scheint gar keine Angabe von Headern notwendig zu sein.
Es ist durchaus nicht verkehrt, make die Header auch als Abhängigkeit bekannt zu machen. Sonst wird bei einer Änderung in einem Header, wie meillo schreibt, nicht neu gebaut.

Das muss man allerdings nicht von Hand. Der gcc und auch clang können dir die Abhängigkeiten raussuchen und in eine Datei schreiben, üblicherweise mit der Endung .d. Dazu reicht es, die CFLAGS zu ergänzen und die generierten *.d einzubinden. Grobes Beispiel:

Code: Alles auswählen

CFLAGS:=... -MMD ...

clean:
	$(RM) ... *.d ...

-include $(wildcard *.d)
Oder auch die *.d ohne Wildcard auflisten:

Code: Alles auswählen

CFLAGS:=... -MMD ...

DEPENDENCIES=$(OBJ:.o=.d) $(OBJ_TEST:.o=.d)

clean:
	$(RM) ... $(DEPENDENCIES) ...

-include $(DEPENDENCIES)
-MMD erzeugt nur Abhängigkeiten zu „eigenen“ Headern. Alternativ erzeugt -MD Abhängigkeiten zu System- und eigenen Headern.

Das include hat ein - vorgestellt, da die *.d beim ersten Durchlauf noch nicht existieren, make ignoriert den Fehler mit dem -. Der Compiler erzeugt die *.d beim ersten Durchlauf als Schritt vor dem Kompilieren.

Noch zweidrei Anregungen:
RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 11:29:54

Code: Alles auswählen

%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<
Die Regel könntest du dir auch sparen, sie entspricht GNU makes eingebauter Regel für .o.

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 11:29:54

Code: Alles auswählen

$(BIN): $(OBJ)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN) $^
Auch das entspricht der eingebauten Regel fürs Linken, es würde reichen, die Abhängigkeit anzugeben:

Code: Alles auswählen

$(BIN): $(OBJ)

Für ein make test wäre es noch üblich, den oder die Tests direkt auszuführen, z.B.:

Code: Alles auswählen

test: $(BIN_TEST)
	./$(BIN_TEST)
Manchmal bekannt als Just (another) Terminal Hacker.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 29.04.2019 22:45:26

JTH hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 15:03:16
Es ist durchaus nicht verkehrt, make die Header auch als Abhängigkeit bekannt zu machen. Sonst wird bei einer Änderung in einem Header, wie meillo schreibt, nicht neu gebaut.
Ach so ist das - danke!

Die Sache mit den impliziten Regeln gefällt mir. Ich habe noch nachgeschaut, ob die auch kompatibel mit anderen Implementationen von "make" sind:
This manual only documents the default rules available on POSIX-based operating systems.
[...]
n.o is made automatically from n.c with a recipe of the form ‘$(CC) $(CPPFLAGS) $(CFLAGS) -c’.
[...]
n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise recipe used is ‘$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)’. This rule does the right thing for a simple program with only one source file. It will also do the right thing if there are multiple object files (presumably coming from various other source files), one of which has a name matching that of the executable file. [...]
In more complicated cases, such as when there is no object file whose name derives from the executable file name, you must write an explicit recipe for linking.
Quelle: https://www.gnu.org/software/make/manua ... e-of-Rules
Ich habe allerdings fürs Linking die expliziten Regeln gelassen, damit mycmp_test nicht die ncurses-library abbekommt (sowas stört mich irgendwie, obwohl es ja nix macht).

Die automatische Abhängigkeitslisten für die Header sind natürlich elegant, aber ich würde gerne auch kompatibel zu anderen Compilern sein - aber dennoch vielen Dank!

Somit hätte ich die Makefile nun fertig. :THX:
Falls interessierte Mit-Lernende das lesen - hier noch einmal die letzte Version:

Code: Alles auswählen

# rfm - Robert's file manager
# See LICENSE file for copyright and license details.
.POSIX:

INCS = -I. -I/usr/include
LIBS = -lncursesw
CPPFLAGS = -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700

CFLAGS = -ggdb -std=c99 -pedantic -Wall -Wextra -O0 $(INCS)
LDFLAGS = $(LIBS)
CC = gcc

BIN = rfm
HDR = config.h def.h rfm.h
SRC = bind.c curses.c curses_readline.c dir.c display.c filter.c info.c mycmp.c rfm.c wrappers.c
OBJ = ${SRC:.c=.o}

BIN_TEST = test/mycmp_test
HDR_TEST = test/mycmp_test.h
SRC_TEST = test/mycmp_test.c
OBJ_TEST = ${SRC_TEST:.c=.o}

all: $(BIN)

$(BIN): $(OBJ)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $(BIN) $^

$(OBJ): $(HDR)

clean:
	rm -f $(BIN) $(OBJ) $(BIN_TEST) $(OBJ_TEST)

test: $(BIN_TEST)
	@echo Starting unit test for mycmp.c ...
	./$(BIN_TEST)

$(BIN_TEST): $(OBJ_TEST) mycmp.o
	$(CC) $(CFLAGS) -o $(BIN_TEST) $^

$(OBJ_TEST): $(HDR_TEST)


.PHONY: all clean test
Meillo hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 11:39:07
Vermutlich hat niemand auf deine Frage (``So?'') reagiert, weil niemandem etwas Offensichtliches aufgefallen ist und weil du schon geschrieben hast, dass es funktioniert und weil niemand sich die Muehe gemacht hat, genauer hinzuschauen.
Alles klar, kein Problem. :)

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von JTH » 30.04.2019 00:05:15

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 22:45:26
Die automatische Abhängigkeitslisten für die Header sind natürlich elegant, aber ich würde gerne auch kompatibel zu anderen Compilern sein - aber dennoch vielen Dank!
Das ist ein sinnvolles Ziel. Da kommt man aber gerade bei Makefiles/Buildsystemen schnell an Grenzen und muss Compiler unterschiedlich behandeln oder greift irgendwann zu Autotools, CMake oder anderen Makefile-Generatoren (hier natürlich noch nicht notwendig ;) ). Solange du laut Titel anscheinend eher noch am Lernen bist, würd ich mir mit Kompatibilität zu allen nur möglichen Compilern nicht bis ins letzte Detail Arbeit machen. Wo es sich mal am Rande anbietet, kann mans natürlich beachten.

Denkst du an einen konkreten Compiler? Das -MMD und -MD funktioniert neben GCC und Clang mindestens auch mit Intels icc. Mit Compilern, die GCC-ähnliche Optionen nicht unterstützen, bist du mit den anderen benutzten CFLAGS
RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 22:45:26

Code: Alles auswählen

CFLAGS = -ggdb -std=c99 -pedantic -Wall -Wextra -O0 $(INCS)
sowieso längst nicht mehr kompatibel.


RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
29.04.2019 22:45:26
Ich habe allerdings fürs Linking die expliziten Regeln gelassen, damit mycmp_test nicht die ncurses-library abbekommt (sowas stört mich irgendwie, obwohl es ja nix macht).
Das ist auch sinnvoll, möglichst wenige Flags können bei großem Projekt mit Glück die Buildzeiten kürzer halten.

Vielleicht findest du den umgekehrten Weg noch eleganter, LDFLAGS nur für das eine Target zuzuweisen? Dann kannst du dich wieder auf die eingebauten Regeln verlassen:

Code: Alles auswählen

$(BIN): LDFLAGS+=-lncursesw

$(BIN): $(OBJ)

$(BIN_TEST): $(OBJ_TEST) mycmp.o

Manchmal bekannt als Just (another) Terminal Hacker.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 30.04.2019 16:55:38

JTH hat geschrieben: ↑ zum Beitrag ↑
30.04.2019 00:05:15
Denkst du an einen konkreten Compiler?
Nee, höchstens an tcc, weil der beim suckless-Projekt erwähnt wird (https://suckless.org/rocks/).
JTH hat geschrieben: ↑ zum Beitrag ↑
30.04.2019 00:05:15
Mit Compilern, die GCC-ähnliche Optionen nicht unterstützen, bist du mit den anderen benutzten CFLAGS
[...]
sowieso längst nicht mehr kompatibel.
:facepalm: Stimmt ja. Dann werde ich das jetzt mal so machen mit den automatischen Abhängigkeitslisten.
JTH hat geschrieben: ↑ zum Beitrag ↑
30.04.2019 00:05:15
Vielleicht findest du den umgekehrten Weg noch eleganter, LDFLAGS nur für das eine Target zuzuweisen?
Das ist toll, danke!
Und in meinem Fall kann ich ja auch lediglich "LDFLAGS = -lncursesw" machen, statt "+=" - dann ist es vielleicht noch kompatibler zu anderen make-Implementationen:
The following features were inspired by various other versions of make. In some cases it is unclear exactly which versions inspired which others.
[...]
The ‘+=’ syntax to append to the value of a variable comes from SunOS 4 make.
Quelle: https://www.gnu.org/software/make/manua ... l#Features

Dann sieht die Makefile jetzt so aus (übersichtlicher!):

Code: Alles auswählen

# rfm - Robert's file manager
# See LICENSE file for copyright and license details.
.POSIX:

INCS = -I. -I/usr/include
CPPFLAGS = -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700
CFLAGS = -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD $(INCS)
CC = gcc

BIN = rfm
SRC = bind.c curses.c curses_readline.c dir.c display.c filter.c info.c \
      mycmp.c rfm.c wrappers.c
OBJ = $(SRC:.c=.o)

BIN_TEST = test/mycmp_test
SRC_TEST = test/mycmp_test.c
OBJ_TEST = $(SRC_TEST:.c=.o)

DEPENDENCIES = $(OBJ:.o=.d) $(OBJ_TEST:.o=.d)
-include $(DEPENDENCIES)

all: $(BIN)

$(BIN): LDFLAGS = -lncursesw
$(BIN): $(OBJ)

clean:
	rm -f $(BIN) $(OBJ) $(BIN_TEST) $(OBJ_TEST) $(DEPENDENCIES)

test: $(BIN_TEST)
	@echo Starting unit test for mycmp.c ...
	./$(BIN_TEST)

$(BIN_TEST): $(OBJ_TEST) mycmp.o


.PHONY: all clean test
Das sind die Ausgaben beim Testen:

Code: Alles auswählen

(dev)user@hostname:~/dev/rfm$ make clean
rm -f rfm bind.o curses.o curses_readline.o dir.o display.o filter.o info.o mycmp.o rfm.o wrappers.o test/mycmp_test test/mycmp_test.o bind.d curses.d curses_readline.d dir.d display.d filter.d info.d mycmp.d rfm.d wrappers.d test/mycmp_test.d
(dev)user@hostname:~/dev/rfm$ make
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o rfm.o rfm.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o bind.o bind.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o curses.o curses.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o curses_readline.o curses_readline.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o dir.o dir.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o display.o display.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o filter.o filter.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o info.o info.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o mycmp.o mycmp.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o wrappers.o wrappers.c
gcc -lncursesw  rfm.o bind.o curses.o curses_readline.o dir.o display.o filter.o info.o mycmp.o wrappers.o   -o rfm
(dev)user@hostname:~/dev/rfm$ make clean
rm -f rfm bind.o curses.o curses_readline.o dir.o display.o filter.o info.o mycmp.o rfm.o wrappers.o test/mycmp_test test/mycmp_test.o bind.d curses.d curses_readline.d dir.d display.d filter.d info.d mycmp.d rfm.d wrappers.d test/mycmp_test.d
(dev)user@hostname:~/dev/rfm$ make test
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o test/mycmp_test.o test/mycmp_test.c
gcc -ggdb -std=c99 -pedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o mycmp.o mycmp.c
gcc   test/mycmp_test.o mycmp.o   -o test/mycmp_test
Starting unit test for mycmp.c ...
./test/mycmp_test
There were 0 errors.
(dev)user@hostname:~/dev/rfm$ make clean
rm -f rfm bind.o curses.o curses_readline.o dir.o display.o filter.o info.o mycmp.o rfm.o wrappers.o test/mycmp_test test/mycmp_test.o bind.d curses.d curses_readline.d dir.d display.d filter.d info.d mycmp.d rfm.d wrappers.d test/mycmp_test.d

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von JTH » 30.04.2019 19:04:28

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
30.04.2019 16:55:38
Nee, höchstens an tcc, weil der beim suckless-Projekt erwähnt wird (https://suckless.org/rocks/).
Der kann -MD (statt -MMD) und -g (statt -ggdb; -g eigentlich immer ausreichend). Aber bei -pedantic und -Wextra hörts dann auf ;)
Manchmal bekannt als Just (another) Terminal Hacker.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 30.04.2019 21:44:00

Ich stehe gerade auf dem Schlauch: Ich habe etwas an "curses_readline.c" geändert und wollte ohne vorangegangenes "make clean" neu kompilieren. Da kam dann aber nur:

Code: Alles auswählen

make: 'bind.o' is up to date.
Dann habe ich einfach - so wie im Beispiel von @JTH - die Zeile "-include $(DEPENDENCIES)" von ihrem bisherigen Platz (s. meine letzte Makefile) nach ganz unten über die ".PHONY"-Zeile gesetzt. Anschließend funktionierte es:

Code: Alles auswählen

gcc -g -std=c99 -Wpedantic -Wall -Wextra -O0 -MMD -I. -I/usr/include -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700  -c -o curses_readline.o curses_readline.c
gcc -lncursesw  rfm.o bind.o curses.o curses_readline.o dir.o display.o filter.o info.o mycmp.o wrappers.o   -o rfm
:?:
JTH hat geschrieben: ↑ zum Beitrag ↑
30.04.2019 19:04:28
Der kann -MD (statt -MMD) und -g (statt -ggdb; -g eigentlich immer ausreichend). Aber bei -pedantic und -Wextra hörts dann auf ;)
Danke, dann lasse ich das erstmal, denn "-pedantic" und "-Wextra" erscheinen mir wichtig. BTW: Dank Deinem Tipp mit "-g" habe ich mir nochmal die Optionen von gcc genauer angeschaut und dabei zufällig auch gesehen, dass man neuerdings lieber "-Wpedantic" nutzen sollte statt nur "pedantic"...

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von JTH » 30.04.2019 22:07:44

Hehe, gemeiner Fehler :twisted: Es hatte einen Grund, warum ich das include im Beispiel ans Ende geschrieben hab. Habe aber vergessen, drauf hinzuweisen.

Die *.d (einfach mal mit nem Editor reingucken) enthalten letztendlich auch nur Buildregel, bzw. Abhängigkeiten;

Code: Alles auswählen

$ cat foo.d
foo.o: foo.c foo.h bar.h baz.h
Wenn du die include-Zeile vor allen anderen Buildregeln einfügst, landet eine dieser Zeilen aus den *.d als erste Buildregel in deinem Makefile. Und: Wenn du make ohne konkretes Target aufrufst

Code: Alles auswählen

$ make
baut es das allererste Target in deinem Makefile. Das war dann in deinem Fall die importierte Regel

Code: Alles auswählen

bind.o: bind.c usw.
Die Regel für dein Hauptprogramm $(BIN) oder eine all-Regel (wenn vorhanden) sollte immer die erste Regel im Makefile sein.


Hast du eine Begründung dafür gefunden, -Wpedantic dem -pedantic vorzuziehen? Ich dachte bisher, beide seien identisch, -Wpedantic aber erst bei neueren GCCs neu dazugekommen. Und -pedantic gibts eher auch bei anderen Compilern, von wegen der Kompatibilität ;)
Manchmal bekannt als Just (another) Terminal Hacker.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Was machen Programmier-Anfänger mit ihren Fragen?

Beitrag von RobertDebiannutzer » 30.04.2019 22:39:32

Aha! Vielen Dank für die Erklärung! :THX:

JTH hat geschrieben: ↑ zum Beitrag ↑
30.04.2019 22:07:44
Hast du eine Begründung dafür gefunden, -Wpedantic dem -pedantic vorzuziehen? Ich dachte bisher, beide seien identisch, -Wpedantic aber erst bei neueren GCCs neu dazugekommen. Und -pedantic gibts eher auch bei anderen Compilern, von wegen der Kompatibilität ;)
Oh. Bei der Kommandozeilen-Hilfe von gcc stand:

Code: Alles auswählen

  --pedantic                  Same as -Wpedantic.  Use the latter option instead.
  -Wlong-long                 Do not warn about using "long long" when -pedantic.
  -Wpedantic                  Issue warnings needed for strict compliance to the standard.
  -pedantic                   Same as -Wpedantic.  Use the latter option instead.
  --pedantic-errors           Same as -pedantic-errors.  Use the latter option instead.
Ich habe mal gesucht und bin im Changelog von gcc 4.8 fündig geworden:
The new option -Wpedantic is an alias for -pedantic, which is now deprecated.
Quelle: https://gcc.gnu.org/gcc-4.8/changes.html

Allerdings habe ich tatsächlich z.B. im clang-manual nur "-pedantic" gefunden, nicht "-Wpedantic" - Quelle: https://clang.llvm.org/docs/UsersManual ... g-messages .
Dann bleibe ich zugunsten der Kompatibilität also doch bei "-pedantic", dazumal das auch noch im neuesten gcc-manual dokumentiert ist: https://gcc.gnu.org/onlinedocs/gcc-8.3. ... ng-Options . Danke für den Hinweis!

Antworten