Probleme mit make unter windows

OP #7675581
Lesenswert?

Hallo, ich habe ein kleines Projekt (in C unter Windows10), welches ich gerne mit make bauen möchte. Hier komme ich aber nciht weiter Ordnerstruktur

1
-dokumentation
2
-out
3
-project
4
  -Makefile
5
-src
6
  main.c
7
  main.h
8
  -module
9
    -fun_1
10
      fun_1.c
11
      fun_1.h
1
TARGET = main
2
# Program for comipling C programs
3
CC = gcc
4

5
# Extra flags to give to the compiler
6
# -g    Turn on debug information
7
# -Wall   give verbose compiler warnings
8
# -O0      Compiler otimization (0: do not optimize generated code)
9
# -std=c99  use the C99 standard language definition
10
#  -c    only generate object file ('.o' file)
11
CFLAGS = -g -Wall -O0
12

13
# Extra flags to give to the C poreprocessor
14
CPPFLAGS =
15

16
# Extra flags to give to the linker
17
LDFLAGS =
18

19
# file path
20
PATH_MAIN = ../src
21
PATH_MODULE = $(PATH_MAIN)/module
22

23
# source files
24
SOURCES_MAIN = $(PATH_MAIN)/main.c
25
SOURCES_MODULE = $(PATH_MODULE)/fun_1/fun_1.c
26

27
SOURCES = $(SOURCES_MAIN) $(SOURCES_MODULE)
28

29
BUILD_DIR := ../out
30
OBJECTS = $(SOURCES:.c=.o)
31
  
32

33
$(TARGET) : $(OBJECTS)
34
  $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) 
35

36
.PHONY: clean
37

38
clean:
39
  @rm $(OBJECTS)

Wenn ich jetzt im Order "Project" bin und make ausführe (aus dem cmd fenster von Windows), wird mir neben jeder C-Sourcefile ein Objekt erstellt und im Ordner Project die main.exe

Allerdings wenn ich "make clean" aufrufe, bekomme ich den Fehler

1
process_begin: CreateProcess(NULL, rm ../src/main.o ../src/module/fun_1/fun_1.o, ...) failed.

Dieser Fehler kommt, da "rm" unter windows nicht existiert. wenn ich "rm" mit "del" ersetze bekomme ich den Fehler

1
Parameterformat nicht ordnungsgemäß - "src".

Wie bekomme ich "make clean" zum laufen? Und wie bekomme ich es, dass alle objects und die .exe im Out-Ordner erstellt werden?

Persönliche Seite #7675587
Lesenswert?

Chandler B. schrieb:

Wie bekomme ich "make clean" zum laufen?

Am Besten indem du die Unix-Tools inkl "rm" installierst. Da sehr viele Makefiles "rm" & Co benutzen, macht es nicht so viel Sinn stattdessen "del" zu nutzen.

z.B. in Form von Cygwin, MinGW, GnuWin32, oder auch damit:

https://gnu-mcu-eclipse.github.io/blog/2019/04/22/windows-build-tools-v2-12-20190422-released/

(funktioniert auch ohne Eclipse)

Gast #7675741
Lesenswert?

Ich habe in dem Verzeichnis, wo das Makefile liegt, eine rm.bat erstellt:

1
@echo off
2
REM Provides an rm command under Windows.
3

4
set tmp=%*
5
set tmp=%tmp:/=\%
6
set tmp=%tmp:-f = %
7

8
del /Q %tmp%

Im Makefile rufe ich das so auf:

1
rm -f $(OBJ) $(PRG).hex $(PRG).elf $(PRG).lst $(PRG).map

Windows verwendet dann die rm.bat und Linux den "normalen" rm Befehl. Die Batch Datei ersetzt / durch \ und entfernt das -f.

(Firma: Starfleet) #7675764
Lesenswert?

Es gibt ein Microsofteigens make - "nmake.exe" https://learn.microsoft.com/de-de/cpp/build/reference/nmake-reference?view=msvc-170

manchmal ist auch die frage ob man die powershell oder cmd.exe benutzt, die powershell ist näher an unix.

https://de.wikipedia.org/wiki/PowerShell

"help del" sollte dir eine Kurzanleitung zu del liefern. Und unter dem dos-promptwird variablensubstituion nicht mit $ eingeleitet sondern mit %, die powershell dagegen sollte auch das $ kennen.

Aber vielleicht solltest du dich erst für eine Shell unter windows entscheiden und dir für diese eine Kurzreferenz besorgen.

Gast #7675780
Lesenswert?

Steve van de Grens schrieb:

Windows verwendet dann die rm.bat und Linux den "normalen" rm Befehl. Die Batch Datei ersetzt / durch \ und entfernt das -f.

Windows versteht / anstatt \ . Eventuell ist es einfacher im makefile eine RM variable zu definieren. MS nmake kann übrigens auch mit Leerzeichen besser umgehen.

1
#RM    = rm -f
2
RM    = del
3

4
clean:
5
  $(RM) *.obj *.lst *.exe
#7675853
Lesenswert?

Udo K. schrieb:

Windows versteht / anstatt \ .

Windows selber ja, Windows-Programme häufig nicht. Besonders pervers ist, dass das zum Beispiel bei del und Konsorten vom verwendeten Befehlszeileninterpreter abhängt:

cmd.exe, del versteht / nicht

1
C:\>type nul > %TEMP%\dummy.txt
2

3
C:\>dir %TEMP%\dummy.txt
4
 Datenträger in Laufwerk C: ist xxx
5
 Volumeseriennummer: xxx
6

7
 Verzeichnis von C:\Users\xxx\AppData\Local\Temp
8

9
2024-05-31  23:50                 0 dummy.txt
10
               1 Datei(en),              0 Bytes
11
               0 Verzeichnis(se), 1040.942.960.640 Bytes frei
12

13
C:\>del %TEMP%/dummy.txt
14
Ungültige Option - "dummy.txt".
15

16
C:\>del %TEMP%\dummy.txt

Powershell, del versteht / und \

1
PS C:\> New-Item $Env:temp\dummy.txt
2

3

4
    Verzeichnis: C:\Users\xxx\AppData\Local\Temp
5

6

7
Mode                 LastWriteTime         Length Name
8
----                 -------------         ------ ----
9
-a----        2024-05-31     23:52              0 dummy.txt
10

11

12
PS C:\> del $Env:temp\dummy.txt
13
PS C:\> New-Item $Env:temp\dummy.txt
14

15

16
    Verzeichnis: C:\Users\xxx\AppData\Local\Temp
17

18

19
Mode                 LastWriteTime         Length Name
20
----                 -------------         ------ ----
21
-a----        2024-05-31     23:52              0 dummy.txt
22

23

24
PS C:\> del $Env:temp/dummy.txt

Kurz gesagt, ist halt Windows, ist halt scheiße.

Gast #7675963
Lesenswert?

Hannes J. schrieb:

Windows selber ja, Windows-Programme häufig nicht. Besonders pervers ist, dass das zum Beispiel bei del und Konsorten vom verwendeten Befehlszeileninterpreter abhängt:

Ok, interessanterweise hatte ich das Problem nie. Meine Makefiles sind vielleicht zu einfach.

Kurz gesagt, ist halt Windows, ist halt scheiße.

Das ist mal wieder eine polemische und überflüssige Aussage. Windows ist halt komplex und hat historische Altlasten. Aber Microsoft zahlt wenigstens sehr gutes Schmerzensgeld.

Linux ist da nicht besser. Da gibt es sh, bash, ash, dash, csh, ksh, und ein Duzend weitere. Jede mit eigener Syntax, jede inkompatibel. Und sh auf Debian ist nicht kompatibel mit der sh in Ubuntu. Und das gnu rm ist nicht kompatibel mit dem FreeBSD rm. Ah ja, gmake das meist unter dem Name make installiert ist, ist nicht kompatibel zu sysv make.

Wieviel Stunden habe ich mit der Suche nach Fehlern in Shell Skripten verbraten? Dann war es das "alias" Kommando, das Befehle auf der interaktiven Kommandozeile umdefiniert, oder eine Umgebungsvariable, die mal gesetzt war und dann wieder nicht. Und Schmerzensgeld hat da keiner gezahlt.

Gast #7675973
Lesenswert?

Udo K. schrieb:

Aber Microsoft zahlt wenigstens sehr gutes Schmerzensgeld.

Ich habe von denen noch keinen Cent erhalten. Im Gegenteil: Ich muss seit 25 Jahren meine PC mit OEM Windows kaufen, obwohl ich kein Windows haben will. Und ich kann es danach nicht einmal weiter verkaufen, an andere die Interesse hätten.

Und sh auf Debian ist nicht kompatibel mit der sh in Ubuntu.

Alternative Fakten?

Alle Linux Versionen nutzen standardmäßig eine Bourne Shell oder eine dazu kompatible. Wenn du Erweiterungen spezifischer Shells nutzt, und diese dann bei anderen Shells nicht zur Verfügung stehen, dann ist das dein eigenes hausgemachtes Problen. Dafür kann weder der Herr Torvalds etwas, noch das Linux System.

Dass Leute alternative Shells bereit stellen ist weder ein Problem von Linux noch von Windows. Genieße die Freiheit, oder lasse es sein, wenn du nicht magst.

Gast #7676039
Lesenswert?

Steve van de Grens schrieb:

Und sh auf Debian ist nicht kompatibel mit der sh in Ubuntu.

Alternative Fakten?

https://wiki.ubuntu.com/DashAsBinSh Was glaubst du wie viele Shell Skripte es da aufgehaut hat.

Hier Gehälter von Microsoft - und von da ist es ja nur ein kleiner Sprung über den Atlantik, wo die Gehälter noch mal deutlich zulegen: https://www.kununu.com/de/microsoft-deutschland/gehalt

Und hier beispielhaft die Situation der OSS: https://is.gd/4sXESA (*)

(*) Die Forensoftware zensuriert Links die nicht ins Konzept passen, daher der is.gd Link.

#7676044
Lesenswert?

Steve van de Grens schrieb:

Ha, aber noch teurer als mit Windows.

Nicht beim Kistenschieber.

Zurück zur Diskussion:

Wer darauf besteht, unixoide Makefiles unter Windows zu verwenden, muss entweder eine unixoide Umgebung dafür schaffen, oder sich die Mühe machen, die Makefiles portabel zu gestalten.

Das ist, wenn man sich drauf einlässt, keine Raketenwissenschaft.

1
ifeq ($(OS),Windows_NT)
2
  RM = del
3
  PATHSEP = \
4
else
5
  RM = rm
6
  PATHSEP = /
7
endif
8

9
TARGET = main
10

11
CC = gcc
12
CFLAGS = -g -Wall -O0
13

14
CPPFLAGS =
15
LDFLAGS =
16

17
PATH_MAIN = ..$(PATHSEP)src
18
PATH_MODULE = $(PATH_MAIN)$(PATHSEP)module
19

20
# source files
21
SOURCES_MAIN = $(PATH_MAIN)$(PATHSEP)main.c
22
SOURCES_MODULE = $(PATH_MODULE)$(PATHSEP)fun_1$(PATHSEP)fun_1.c
23
SOURCES = $(SOURCES_MAIN) $(SOURCES_MODULE)
24
BUILD_DIR := ..$(PATHSEP)out
25
OBJECTS = $(SOURCES:.c=.o)  
26

27
$(TARGET) : $(OBJECTS)
28
  $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) 
29

30
.PHONY: clean
31
clean:
32
  RM $(OBJECTS)

Man kann sich natürlich auch hinstellen und jahrzehntelang herumheulen, wie schlecht die Welt und wie falsch alles außer Linux ist.

Gast #7676124
Lesenswert?

Oliver S. schrieb:

Braucht und will aber doch heutzutage kein Mensch mehr…

Auf der Arbeit haben wir noch ein paar alte Softwareprojekte mit Build Scripten, die für Linux gedacht waren. Ein paar Entwickler hängen aber so sehr an Windows, dass sie nicht mal mit WSL zurecht kommen. Für die ist CygWin optimal, denn damit laufen unsere Scripte alle "einfach so".

Inzwischen stellen wir nur noch Leute ein, die zumindest Grundkenntnisse über Linux mitbringen. Wir könnten eher auf Windows Know-How verzichten.

#7676280
Lesenswert?

Udo K. schrieb:

Wenn du hier schon gmake eigene Abfragen verwendest, dann wird das nichts.

Dann nimm halt 'ne andere Abfrage, ich habe das hier nur zusammengetippt, um das eigentliche Problem zu lösen.

Da ist es einfacher, die WSL2 oder MSYS2 zu installieren, und sich mit den Linux Problemen unter Windows herumzuärgern :-)

Klar. Weil die Scheuklappen so eng sitzen, daß man jede Pfadschreibweise akzeptiert, die unter Linux die richtige ist, muss man Linux installieren ... statt einfach nur ein portables Makefile zu verwenden.

Die Abfrage am Anfang lässt sich sicherlich besser machen (man könnte eine Umgebungsvariable auswerten, die unter Windows immer existiert oder halt irgendwas was anderes anstellen)

Bekommt man das nicht hin, ließe sich der Kram am Anfang des Makefiles auch in zwei Zeilen fest codieren, und der Rest macht dann das, was er soll: Funktionieren. Ohne, daß man sich ein Linux oder sonstwas installieren muss.

Das eigentliche Problem ist trivial, und trivial simpel gelöst.

Gast #7676412
Lesenswert?

Rolf M. schrieb:

Gerade in make kommt z.B. unter Debian die dash zu Einsatz.

Die dash ist zur Bourne Shell kompatibel. Scripte die damit nicht funktionieren, sind nicht zur Bourne Shell kompatibel. Sie sollten dann auch nicht mit #!/bin/sh beginnen, sondern mit dem Namen der Shell, für die sie geschrieben wurden.

Udo K. schrieb:

sh auf Debian ist nicht kompatibel mit der sh in Ubuntu

Die Inkompatibilität liegt in den betroffenen Scripten, nicht in den Shells und auch nicht in Ubuntu vs. Debian. Nervig ist es für betroffene trotzdem. Ich kann deinen Frust nachvollziehen.

#7676436
Lesenswert?

Nicht Joachim B. schrieb:

Rolf M. schrieb:

Gerade in make kommt z.B. unter Debian die dash zu Einsatz.

Die dash ist zur Bourne Shell kompatibel.

Ja, ok, Bourne Shell. Ich hatte an die bash gedacht.

Scripte die damit nicht funktionieren, sind nicht zur Bourne Shell kompatibel. Sie sollten dann auch nicht mit #!/bin/sh beginnen, sondern mit dem Namen der Shell, für die sie geschrieben wurden.

Ich spreche nicht nur von Skripten, sondern von Shell-Kommandos, die direkt im Makefile stehen, ganz ohne Shebang, das man dort ja auch gar nicht angeben kann. Diese werden unter Debian defaultmäßig mit der dash ausgeführt.

#7678802
Lesenswert?

Rolf M. schrieb:

Ich spreche nicht nur von Skripten, sondern von Shell-Kommandos, die direkt im Makefile stehen, ganz ohne Shebang, das man dort ja auch gar nicht angeben kann. Diese werden unter Debian defaultmäßig mit der dash ausgeführt.

In GNU Make kann man die über die SHELL variable setzen. Auch direkt aus dem Makefile. Beispiel:

1
# Wit schreiben das Makefile in Python!
2
SHELL=/usr/bin/python3
3
# Wir wollen keine neue Shell für jede Zeile
4
.ONESHELL:
5

6
hello:
7
  message = "Hello Python!"
8
  print(message)
#7685050
Lesenswert?

Chandler B. schrieb:

ich habe ein kleines Projekt (in C unter Windows10), welches ich gerne mit make bauen möchte.

Ja schön, und welches Compilerpacket? Man nimmt entweder native Entwicklungswerkzeuge, wie das normale VS oder z.B. Watcom C oder Linux/Unix-Importhilfen.

Für Linux-Imports gibt es fertige (und bewährte) Packete (s.o.) mit Runtimes oder Dll-Ersatz, VMs und weiß der Geier, was noch (s.o.) - früher gab es die Haskell Plattform, die konnte man auch missbrauchen. Bei Windows 10 gibt es immerhin das WSL - auf jedenfall schon mal etwas gutes zum Nachlesen in diesem Zusammenhang.

#7685321
Lesenswert?

Monk schrieb:

Das Problem wurde längst beschrieben und gelöst.

Ach ja? Der TE hat sich bisher nicht zurückgemeldet. Der Thread gibt allenfalls Auskunft darüber, das viele Leute sich bereits mit Linux in Windows und Windows in Linux ganz gut auskennen. Der Threadstarter selber scheint sich mit solchen Thematiken noch nicht groß auseinandergesetzt haben, denn dann wäre eine konkretere Frage zu einem konkreten Entwicklungspacket angesagt gewesen, welche auch nicht immer im Plug und Play-Sinne gleich funktionieren.

Eine andere Sache ist, dass normalerweise die meisten wichtigen Sachen in der Dokumentation vom Entwicklungssystem stehen. Man könnte jetzt auch LLVM einsetzen (https://llvm.org/docs/GettingStartedVS.html) oder von mir aus Tiny C (https://bellard.org/tcc/tcc-doc.html) - man wird aber auch diese konkret referenzieren müssen, wenn Probleme auftauchen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren