Was machen Programmier-Anfänger mit ihren Fragen?

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

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

Beitrag von Meillo » 18.12.2018 22:53:50

Aber schau dir das Byte-Order-Zeug ruhig mal an. Dann verstehst du z.B. auch, warum es UTF-16-LE und UTF-16-BE gibt, aber nur ein UTF-8.

Ich finde es gut, dass du diese ganzen Experimente machst. Nur weiter so!
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 » 18.12.2018 23:14:51

Danke. Leider muss ich spätestens zum 20.12. (also übermorgen) mit dem Experimentieren erstmal praktisch aufhören, da ich Mitte Januar Prüfungen habe (und Anfang April noch einmal...). Nennt sich Abitur oder so. :mrgreen: (Für Leistungskurs Mathematik bin ich ja schonmal bestens gerüstet, da ich nun ja weiß, dass 1+1=1 ist... 8) )
Aber ein Zwischenergebnis können wir ja auf jeden Fall schon einmal festhalten: Als Programmier-Anfänger ist man mit seinen Fragen hier im debianforum auf jeden Fall richtig. Danke! :THX:

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

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

Beitrag von RobertDebiannutzer » 07.03.2019 10:42:32

Ich muss mal für interessierte Mitleser ein kleines Update machen, auch wenn meine Funktion immer noch nicht fertig ist (ich habe bisher aber schon mindestens 10 Entwürfe angefertigt).
Denn ich glaube, dass mir kürzlich etwas Wesentliches klar geworden ist:

Für den Linux-Kernel sind Dateinamen eine Kette von Bytes, also in C ausgedrückt ein "char"-Array. Deswegen gibt es für Linux-Systeme auch nur Funktionen wie "open()" oder "fopen()", die als Dateinamen einen Pointer zu einem "char"-Array erwarten, nicht etwa einen Pointer zu einem "wchar_t"-Array.
So, aber damit ist auch klar, dass Dateinamen niemals in UTF-16 oder UTF-32 codiert sein können! Denn beide Encodings nutzen Null-Bytes, um überflüssigen Platz in den zwei-/vier-Byte-Einheiten aufzufüllen.
Ihr könnt das sehr schön an einem kleinen Experiment sehen. Man öffne vim und tippe ein "ä" in den Buffer. Anschließend speichere man es unter verschiedenen Encodings in verschiedenen Dateien, also z.B. mit:

Code: Alles auswählen

:w ++enc=utf-8 u8
:w ++enc=utf-16 u16
:w ++enc=utf-32 u32
Anschließend hat man:

Code: Alles auswählen

user@hostname:~$ ll u*
-rw-r--r-- 1 user user 4 Mar  7 10:09 u16
-rw-r--r-- 1 user user 8 Mar  7 10:09 u32
-rw-r--r-- 1 user user 3 Mar  7 10:09 u8
und:

Code: Alles auswählen

user@hostname:~$ hd u16
00000000  00 e4 00 0a                                       |....|
00000004
user@hostname:~$ hd u32
00000000  00 00 00 e4 00 00 00 0a                           |........|
00000008
user@hostname:~$ hd u8
00000000  c3 a4 0a                                          |...|
00000003
("0a" ist das newline-Zeichen)

Wichtig ist zudem:
The external encoding is byte-based and can be chosen appropriately for the environment and for the texts to be handled. A variety of different character sets can be used for this external encoding (information that will not be exhaustively presented here–instead, a description of the major groups will suffice). All of the ASCII-based character sets fulfill one requirement: they are "filesystem safe." This means that the character '/' is used in the encoding only to represent itself. Things are a bit different for character sets like EBCDIC (Extended Binary Coded Decimal Interchange Code, a character set family used by IBM), but if the operating system does not understand EBCDIC directly the parameters-to-system calls have to be converted first anyhow.
Quelle: https://www.gnu.org/software/libc/manua ... Char-Intro (aus dem glibc-Handbuch)

Das alles scheint mir u.a. zu bedeuten:
1. Die Umwandlung von char* zu wchar_t* in meiner Funktion - das habe ich u.a. auch probiert - kann ich mir total schenken.
2. Ich kann ganz normal ein "char" mit einem character-literal vergleichen, also z.B. "if (*str == '.')" oder "if (*str == '0')" oder "if (*str == '/')".

In einer früheren Version des glibc-Manual stand sogar explizit:
Because the basic ASCII characters in the range from 0 to 0177 are so important, they stand for themselves in all multibyte character codes. That is to say, a byte whose value is 0 through 0177 is always a character in itself. The characters which are more than one byte must always start with a byte in the range from 0200 through 0377.
Quelle: http://kirste.userpage.fu-berlin.de/che ... bc_18.html
(Achtung: Die Zahlen dort sind nach dem Oktalsystem angegeben.)
Warum das so klar nicht mehr im aktuellen glibc-Handbuch steht, weiß ich nicht, liegt vielleicht daran, dass man nun noch mehr Spezialfälle berücksichtigen will?

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

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

Beitrag von RobertDebiannutzer » 08.03.2019 12:02:41

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
07.03.2019 10:42:32
1. Die Umwandlung von char* zu wchar_t* in meiner Funktion - das habe ich u.a. auch probiert - kann ich mir total schenken.
Ergänzung: Damit meinte ich nur: Es ist nicht zwingend notwendig. Es kann dennoch praktisch sein, wenn man ein Zeichen pro Einheit haben möchte. Ob das bei meiner Vergleichs-Funktion allerdings notwendig ist, hängt von der Herangehensweise ab.

Somit macht wchar_t wohl hauptsächlich für Programme wie Texteditoren Sinn.
Wobei - zu wchar_t sagt das glibc-Handbuch:
The ISO C90 standard, where wchar_t was introduced, does not say anything specific about the representation. It only requires that this type is capable of storing all elements of the basic character set. Therefore it would be legitimate to define wchar_t as char, which might make sense for embedded systems.

But in the GNU C Library wchar_t is always 32 bits wide and, therefore, capable of representing all UCS-4 values and, therefore, covering all of ISO 10646. Some Unix systems define wchar_t as a 16-bit type and thereby follow Unicode very strictly. This definition is perfectly fine with the standard, but it also means that to represent all characters from Unicode and ISO 10646 one has to use UTF-16 surrogate characters, which is in fact a multi-wide-character encoding. But resorting to multi-wide-character encoding contradicts the purpose of the wchar_t type.
Quelle: https://www.gnu.org/software/libc/manua ... Char-Intro

Wenn wchar_t nicht zwingend fähig ist, alle Zeichen zu enthalten, ist das natürlich keine Vereinfachung zum normalen "char"-Array, sondern eine Verschlechterung, weil man ja dennoch den überflüssig beschlagnahmten Speicherplatz hat.
Da wären dann möglicherweise so Neuigkeiten wie char32_t besser. Wobei es dazu soweit ich herausgefunden habe keine Funktionen gibt, außer welche, die multi-byte-strings zu char32_t-strings umwandeln oder umgekehrt. Ansonsten müsste man halt einen eigenen Datentyp definieren... Aber das hat dann nix mehr mit meiner compare-Funktion zu tun. Ist aber trotzdem interessant... :D

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

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

Beitrag von RobertDebiannutzer » 12.04.2019 13:50:28

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 23:14:51
Nennt sich Abitur oder so.
Successfully completed. :D
Meillo hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 22:53:50
warum es UTF-16-LE und UTF-16-BE gibt, aber nur ein UTF-8
Hm, nach allem, was ich bisher meine verstanden zu haben, kann man das so absolut nicht sagen. Denn byte order spielt ja nur dann eine Rolle, wenn wir Einheiten verwenden, die aus mehreren Bytes bestehen (also z.B. wchar_t, int, char16_t, char32_t). Diese können wir aber im Prinzip ebenso für UTF-8 verwenden, wie für UTF-16/-32 (es würde nur wenig Sinn ergeben). Genauso könnten wir (im Prinzip!) auch UTF-16 bzw. UTF-32 in einzelnen Bytes speichern (also als char-array in C). Nur dann müsste man darauf achten, statt der str*-Funktionen die mem*-Funktionen zu verwenden, also z.B. statt strcpy() memcpy(). Und man müsste natürlich die Länge der strings separat speichern.
Vorteil der Speicherung von UTF-16/-32 als char-array wäre, dass man sich nicht auf die Anzahl der Bytes in wchar_t verlassen müsste bzw. viele Bibliotheks-Funktionen zur Auswahl hat. Da allerdings diese Form des Umgangs mit diesen Encodings sehr wenig Sinn macht, wäre imho bewiesen, dass @meillo Recht hat, wenn er meint, dass UTF-8 das einzig wahre Encoding für das Unicode-Charset ist... :idea:

Benutzeravatar
novalix
Beiträge: 1908
Registriert: 05.10.2005 12:32:57
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: elberfeld

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

Beitrag von novalix » 12.04.2019 17:42:07

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
12.04.2019 13:50:28
RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 23:14:51
Nennt sich Abitur oder so.
Successfully completed. :D
<AltHerrenGemoppere>Die lassen heutzutage aber auch jeden durchkommen.</AlteHerrenRaus> :mrgreen:
Gratulation!
Das Wem, Wieviel, Wann, Wozu und Wie zu bestimmen ist aber nicht jedermannns Sache und ist nicht leicht.
Darum ist das Richtige selten, lobenswert und schön.

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

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

Beitrag von Meillo » 22.04.2019 08:59:49

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
12.04.2019 13:50:28
Meillo hat geschrieben: ↑ zum Beitrag ↑
18.12.2018 22:53:50
warum es UTF-16-LE und UTF-16-BE gibt, aber nur ein UTF-8
Denn byte order spielt ja nur dann eine Rolle, wenn wir Einheiten verwenden, die aus mehreren Bytes bestehen (also z.B. wchar_t, int, char16_t, char32_t).
Ja.
Diese können wir aber im Prinzip ebenso für UTF-8 verwenden, wie für UTF-16/-32 (es würde nur wenig Sinn ergeben).
Nein, koennen wir nicht, denn: Wie gross waere denn die Einheit, die du lesen wuerdest, wenn du genau ein weiteres UTF-8-Zeichen *lesen* willst? ;-)
Genauso könnten wir (im Prinzip!) auch UTF-16 bzw. UTF-32 in einzelnen Bytes speichern (also als char-array in C).
Aber welches der zwei UTF-16-Bytes speicherst du dann als erstes ab? Erst das niederwertige oder erst das hoeherwertige? Da diese Entscheidung frei ist, haben wir eben LE und BE.


[...] wäre imho bewiesen, dass @meillo Recht hat, wenn er meint, dass UTF-8 das einzig wahre Encoding für das Unicode-Charset ist... :idea:
Klasse, dass nun auch bewiesen ist, dass ich Recht habe. ;-P

Der einzige Nachteil von UTF-8 ist, dass die Laenge eines Zeichens dynamisch ist und damit z.B. bei einem UTF-8 strlen() mehr Rechenarbeit noetig ist als bei eiem Festlaengen-Encoding. Auch die Datenstrukturen muessen dynamischer sein. Davor will man sich druecken. Das ist aber ein sich Druecken davor, die Realitaet zu akzeptieren. Festlaengen-Encodings entsprechen nicht der Natur der Sache und koennen darum nur vereinfachte und darum begrenzte Uebergangsloesungen sein. Wir koennten diese zeitweisen Uebergangsloesungen auch einfach mal bleiben lassen und es gleich richtig machen ...
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 » 22.04.2019 10:54:18

Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Wie gross waere denn die Einheit, die du lesen wuerdest, wenn du genau ein weiteres UTF-8-Zeichen *lesen* willst?
Vier Bytes - der Rest würde wie bei UTF-16/-32 mit '\0' aufgefüllt werden. (Macht natürlich keinen Sinn.)
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Aber welches der zwei UTF-16-Bytes speicherst du dann als erstes ab? Erst das niederwertige oder erst das hoeherwertige? Da diese Entscheidung frei ist, haben wir eben LE und BE.
So könnte man ja (im Prinzip!) doch auch bei UTF-8 argumentieren, oder?
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Klasse, dass nun auch bewiesen ist, dass ich Recht habe. ;-P
Ich hoffe, dass Du mich nicht falsch verstanden hast. Ich freue mich halt immer, wenn ich meine, dass auch ich zu tieferer Einsicht gekommen bin. :wink:

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

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

Beitrag von Meillo » 22.04.2019 11:17:39

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 10:54:18
Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Wie gross waere denn die Einheit, die du lesen wuerdest, wenn du genau ein weiteres UTF-8-Zeichen *lesen* willst?
Vier Bytes - der Rest würde wie bei UTF-16/-32 mit '\0' aufgefüllt werden. (Macht natürlich keinen Sinn.)
Vorsicht, hier darfst du nicht schlampig sein, in deinen Ueberlegungen.

Wenn du vier Bytes liest aus einem reinen ASCII-Text, dann hast du nicht ein, sondern vier Zeichen gelesen! Wenn du genau ein UTF-8-Zeichen lesen willst, dann geht das nicht en bloc. Du musst Byte fuer Byte lesen und zwar so lange, bis das hoechstwertigste Bit des Bytes 0 ist, dann ist das Zeichen vollstaendig. Das kann nach einem, nach zwei, nach drei oder nach vier Bytes der Fall sein. Wann es aber der Fall ist, kannst du erst wissen, wenn du die Bytes davor eines nach dem anderen gelesen hast.

Bislang denkst du zu sehr in Datenstrukturen in der Programmiersprache. dort kannst du natuerlich irgendwas mit Nullen auffuellen, beim Lesen muss man anders denken, denn wenn du vier Bytes von Stdin gelesen hast, dann sind die dort weg. Wenn du nur ein Zeichen lesen wolltest und es waren vier, dann hast du mit den restlichen drei ein Problem.

Die einzige Moeglichkeit wie man UTF-8-Zeichen lesen kann ist byteweise.

Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Aber welches der zwei UTF-16-Bytes speicherst du dann als erstes ab? Erst das niederwertige oder erst das hoeherwertige? Da diese Entscheidung frei ist, haben wir eben LE und BE.
So könnte man ja (im Prinzip!) doch auch bei UTF-8 argumentieren, oder?
Nein, in UTF-8 ist definiert wie die einzig moegliche Reihenfolge ist. UTF-8 kann man auch nur byteweise lesen und byteweises Lesen hat immer eine definierte Reihenfolge.

UTF-8 ist in seiner Art wie `char'. Char kann man auf allen Systemen portabel speichern und lesen.

UTF-16 ist dagegen in seiner Art viel mehr wie `int'. Int kann nicht einfach von LE- auf BE-Systeme uebertragen werden.


Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 08:59:49
Klasse, dass nun auch bewiesen ist, dass ich Recht habe. ;-P
Ich hoffe, dass Du mich nicht falsch verstanden hast. Ich freue mich halt immer, wenn ich meine, dass auch ich zu tieferer Einsicht gekommen bin. :wink:
Nee, nee, ich fand's nur lustig wie du das geschrieben hast. Wenn mir von nun an in irgendwelchen kontroversen Diskussionen irgendjemand mal widersprechen will, dann werde ich einfach darauf verweisen, dass du bewiesen hast, dass ich Recht habe. *hohoho* :-D Danke dafuer! ;-)
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 » 22.04.2019 11:49:47

Meillo hat geschrieben: ↑ zum Beitrag ↑
22.04.2019 11:17:39
Bislang denkst du zu sehr in Datenstrukturen in der Programmiersprache. dort kannst du natuerlich irgendwas mit Nullen auffuellen, beim Lesen muss man anders denken, denn wenn du vier Bytes von Stdin gelesen hast, dann sind die dort weg. Wenn du nur ein Zeichen lesen wolltest und es waren vier, dann hast du mit den restlichen drei ein Problem.

Die einzige Moeglichkeit wie man UTF-8-Zeichen lesen kann ist byteweise.
Ja klar, sorry, da war ich vorher echt unkonzentriert... :oops:

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

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

Beitrag von RobertDebiannutzer » 23.04.2019 18:55:19

Mal zurück zu meiner compare-Funktion und apropos UTF-8-strlen...
Mir ist gerade aufgefallen, dass eine Einteilung in chunks von "Zahlen" und "Nicht-Zahlen" nicht wirklich funktioniert:
Man nehme z.B. "abc-1.2.3.x86_64.rpm" und "abc-1.2.3.4.x86_64.rpm" - imho sollte ersteres kleiner sein als zweiteres bzw. ich würde gerne folgendes Paradigma aufrechterhalten:

Code: Alles auswählen

- an Position "0" im string gilt: Zahl < Nicht-Zahl
  für den Fall "string is dotfile" gilt obige Regel für Position "1" im string
- an allen anderen Positionen im string gilt: Zahl > Nicht-Zahl
Da muss ich mir noch was dazu überlegen... Aber ich bin guten Mutes, dass meine compare-Funktion noch vor "hurd" fertig ist ... (war das ein guter Insider-Witz? :mrgreen: )

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

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

Beitrag von Meillo » 23.04.2019 19:57:07

Der Witz hat einen noch laengeren Bart als ich ... ;-)
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 » 23.04.2019 22:56:33

Meillo hat geschrieben: ↑ zum Beitrag ↑
23.04.2019 19:57:07
Der Witz hat einen noch laengeren Bart als ich ... ;-)
Und ist somit aktuell wieder in? :wink:

Glücklicherweise gibt es übrigens ja bereits eine UTF-8-strlen-Funktion in stdlib.h :facepalm: :

Code: Alles auswählen

len = mbstowcs(NULL, str, 0);
(s. manpage mbstowcs, z.B. https://manpages.debian.org/stretch/man ... .3.en.html - unten auf der Seite sind sogar entsprechende Beispiele).

Ich kenne diese Funktion ja schon länger, doch ich denke, dass ich jetzt auf einen recht eleganten Plan gekommen bin, der unter Einbindung dieser Funktion die ganze Sache schön lesbar macht und sogar richtig agieren lässt.
Doch bevor ich hier mal wieder eine neue Version einstelle um euch um eure Meinung zu bitten, will ich erst noch ein wenig mehr testen. Der Teufel versteckt sich ja bekanntlich im Detail...

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
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 09:09:48

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
23.04.2019 22:56:33
Meillo hat geschrieben: ↑ zum Beitrag ↑
23.04.2019 19:57:07
Der Witz hat einen noch laengeren Bart als ich ... ;-)
Und ist somit aktuell wieder in? :wink:
Gepflegt kurze Baerte sind wieder in, so Unix-Guru-Baerte, ich weiss nicht. :-D

Doch bevor ich hier mal wieder eine neue Version einstelle um euch um eure Meinung zu bitten, will ich erst noch ein wenig mehr testen. Der Teufel versteckt sich ja bekanntlich im Detail...
Hast du denn ein Testset? Also eine Liste von Strings, mit den erwarteten Erkennungs-/Vergleichsergebnissen, die du automatisch durchlaufen lassen kannst? Falls nicht, solltest du dir das unbedingt anlegen, weil deine Testerei sonst nicht nur aufwaendiger sondern auch lueckenhafter sein wird. Ausserdem ist so ein Testset zugleiche eine Dokumentation deiner Erwartungshaltung an das Programm.
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 10:53:04

Meillo hat geschrieben: ↑ zum Beitrag ↑
24.04.2019 09:09:48
Hast du denn ein Testset?
Ja, aber das werde ich jetzt noch erweitern und zudem versuchen, das Ganze als "Unit-Test" professioneller zu gestalten. Dann kann die .c-Datei meiner compare-Funktion und ihrer Hilfsfunktionen in dem Projektordner meines file managers bleiben, bekommt aber eine eigene Makefile und ein extra Unit-Test-Programm mit einer header-Datei, welche die Test-Strings enthält. Dadurch, dass mein file-manager langsam hübsch modular wird, ist das ja nicht weiter schwierig. 8)

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
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: 8782
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: 8782
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: 3014
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: 3014
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

Antworten