2016-09-01 3 views
3

Ich schreibe ein Makefile, das sowohl unter Windows als auch unter Linux funktionieren sollte. Wo immer es möglich ist, vermeide ich OS-spezifische Shell-Befehle.Wie Benutzer in meinem Makefile (mit pure make syntaxis) zur Eingabe von [y/n] aufgefordert werden?

Hier ist ein Ausschnitt aus meiner Make-Datei mit der clean Funktion am Ende:

# OS specific part 
# ----------------- 
ifeq ($(OS),Windows_NT) 
    RM = del /F /Q 
    RMDIR = -RMDIR /S /Q 
    MKDIR = -mkdir 
    ERRIGNORE = 2>NUL || (exit 0) 
    SEP=\\ 
else 
    RM = rm -rf 
    RMDIR = rm -rf 
    MKDIR = mkdir -p 
    ERRIGNORE = 2>/dev/null 
    SEP=/ 
endif 
PSEP = $(strip $(SEP)) 

# Definitions for nullstring and space 
# ------------------------------------- 
nullstring := 
space := $(nullstring) #End 

# Lists of all files and folders to keep or remove 
# ------------------------------------------------- 
buildFiles_toKeep := ... # I wrote some scripts to 
buildDirs_toKeep := ...  # automatically generate 
buildFiles_toRemove := ... # these lists. But that would lead 
buildDirs_toRemove := ... # us too far here. 


.PHONY: clean 
clean: 
    @echo. 
    @echo ---------------------------------------------------------- 
    @echo.$(space)  __   ************** $(space) 
    @echo.$(space)  __\ \___  * make clean * $(space) 
    @echo.$(space)  \ _ _ _ \ ************** $(space) 
    @echo.$(space)  \_`_`_`_\      $(space) 
    @echo.$(space)          $(space) 
    @echo.$(space)Keep these files: 
    @echo.$(space) $(buildFiles_toKeep) 
    @echo.$(space) 
    @echo $(space)Keep these directories: 
    @echo.$(space) $(buildDirs_toKeep) 
    @echo.$(space) 
    @echo.$(space)Remove these files: 
    @echo.$(space) $(buildFiles_toRemove) 
    $(RM) $(buildFiles_toRemove) 
    @echo. 
    @echo.$(space)Remove these directories: 
    @echo.$(space) $(buildDirs_toRemove) 
    $(RMDIR) $(buildDirs_toRemove) 
    @echo. 
@echo ---------------------------------------------------------- 

Diese Make-Datei funktioniert super. Sowohl unter Windows als auch unter Linux ersetzt es $(RM) und $(RMDIR) durch die richtigen Shell-Befehle zum Löschen von Dateien und Ordnern. Aber ich möchte den Benutzer darauf hinweisen, dass er Y oder N drücken kann. Ich möchte keine Dateien löschen, die er behalten möchte. Ich habe versucht, einige Batch-Befehle in die Rezepte des clean Ziels einzufügen, die den Benutzer zur Eingabe auffordern. Aber die Aufforderung wird nicht angezeigt. Vielleicht, weil GNU make den Eingabestrom verzögert.

Ich frage mich, ob es möglich ist, eine Eingabeaufforderung [Y/N] mit 'pure' make Syntaxis (keine OS-spezifische Shell-Befehle) zu generieren. Ich weiß, dass die Markensprache ihre Grenzen hat. Vielleicht kann eine clevere Lösung auf einem Betriebssystem (zB Linux) funktionieren und mit minimalem Overhead auf einen anderen (zB Windows) portiert werden.

Wer eine Idee?


EDIT:

ich zu diesem Link verwiesen wurde: How do I get `make` to prompt the user for a password and store it in a Makefile variable?

Gnu die Variable PASSWORD durch den Benutzer auffordert, machen erstellen:

$ cat Makefile 
PASSWORD ?= $(shell bash -c 'read -s -p "Password: " pwd; echo $$pwd') 

Diese Art der Aufforderung Der Benutzer für die Eingabe funktioniert gut, solange Sie die Eingabeaufforderung im Moment Ihrer Mak erscheinen soll efile ist geparst. Aber mein Fall ist anders. Ich möchte den Benutzer auffordern, wenn das Makefile bereits ausgeführt wird, mit anderen Worten, wenn die Rezepte im Makefile ausgeführt werden.


EDIT:

Auffordern des Benutzers nicht möglich sein wird, wenn Sie mit mehreren Threads laufen lassen. So bin ich völlig in Ordnung mit dem Aufruf der Funktion clean Single-Threaded:

>> make clean -j1 

Denn die clean Funktion nicht zu beenden dauert lange. Ich beabsichtige nicht, den Benutzer für etwas in der build Funktion zu veranlassen, so dass Multi-Threaded :-)

>> make all -j8 --output-sync=target 
+1

Was, also können Sie nur von einem Terminal bauen? Bitte beachten Sie Ihre Benutzer; Lass sie aus Jenkins oder 'M-x kompilieren' oder was auch immer sie brauchen, bauen, ohne für die Interaktion geärgert zu werden. Wie wollen Sie sicherstellen, dass die Eingaben ohnehin an den richtigen Prozess gehen - werden Sie eine serialisierte (Single-CPU) Build erzwingen? Das ist die schlechteste Idee, die ich seit Jahren gesehen habe^Wweeks (ich verbringe zu viel Zeit mit SO in diesen Tagen). –

+0

Dies könnte hilfreich sein http://stackoverflow.com/a/20671804/5291015. Sie können das gleiche für Ihre Ja/Nein-Eingabe ändern – Inian

+0

@Tobi: Ich erzwinge keine serialisierte (Single-CPU) Build. Vielleicht sollte der 'clean'-Befehl Single-CPU sein (weil es eine Eingabeaufforderung gibt). Aber das ist keine große Sache. Der Befehl 'build' kann beliebig viele Kerne verwenden. Normalerweise setze ich die Flagge auf "-j8". –

Antwort

1

Konzeptionell eine sehr einfache Anwendung mit einem Ziel ist machen ausgeführt werden kann - bauen, einen Baum von Abhängigkeiten, und Remake Sachen, die einen neueren Vorfahren hat. Interaktion sollte kein Faktor sein, also make nicht nativ bereitstellen, idealerweise sollte sie bereits alle benötigten Informationen haben. Wenn Sie wirklich brauchen, können Sie dies umgehen mit shell, !=, oder sogar Ihre eigene Erweiterung mit Guile oder load.

Dies gilt jedoch nicht wirklich für die clean Regel, denn clean macht nichts in erster Linie Remake, es ist nur ein kurzer Hack, damit Sie bequem eine Nicht-Make-Operation mit Make-Syntax ausdrücken können.

Persönlich sehe ich nicht den Wert der Aufforderung den Benutzer beim Löschen von Dateien, es sei denn, Sie löschen Dinge, die Sie nicht verantwortlich sind, die bereits ein Antipattern in sich ist.

Wenn Sie absolut positiv sind, brauchen Sie dies dann wickeln Sie die clean Rezept in ein Skript und bieten zwei Versionen für Bash und Windows. Sie können auch einfach davon ausgehen, dass jeder, der GNU unter Windows ausführt, bereits MSYS2, Cygwin oder MS 'sanktionierte Version bash for Windows 10 verwendet und auf das cmd/powershell-Skript ganz verzichtet.

+0

Ich stimme dir zu, dass make einfach gehalten werden sollte, und nicht auf Benutzereingaben angewiesen ist. Ich würde eine Bestätigungsaufforderung stellen, solange ich noch mit Gnu Make experimentiere. Ich habe versucht, die Eingabeaufforderung in ein separates .bat-Skript zu schreiben und dieses Skript in einer Rezeptzeile aufzurufen. Leider scheint es, als würde Gnu make den Eingabestream so verschieben, dass die Eingabeaufforderung nicht im Terminal erscheint. Irgendeine Idee, wie man das löst? –

+0

Ich habe gerade versucht, ein Skript mit 'set/p yn =" Y/N: "' zu verwenden und es scheint gut zu funktionieren, was machst du in deinem Skript? – user657267

+0

Ja, du hast Recht. 'set/p yn =" Y/N: 'funktioniert perfekt, wenn es in ein' .bat' Skript gestellt wird. Vielen Dank für deine Hilfe :-) –

Verwandte Themen