I am just experimenting with Bash and Makefiles to make my life easier, and here's what I came up with.
Scenario: Files are in a directory containing a tutorial, or an iteration. For example, one wants to experiment with Boost Libraries.
Code: There's two bashes and a Makefile. First the Makefile
Makefile
#PROJECT=
#DIRECTORY=
#PARAMETER=
OBJ=$(DIRECTORY)$(PROJECT).o
OUT=$(DIRECTORY)$(PROJECT)
CPP=$(DIRECTORY)$(PROJECT).cpp
CC=g++-7
DEBUG=-g
CFLAG=-Wall -c $(DEBUG)
LFLAG=-Wall $(DEBUG)
I=-I/user/local/boost
L=-lboost_system -lboost_thread -lpthread
STD=-std=c++1z
$(OBJ): $(CPP)
$(CC) $(STD) $(CFLAG) $(CPP)
$(OUT): $(OBJ)
$(CC) $(STD) $(LFLAG) $(OBJ) -o $(OUT) $(I) $(L)
clean:
rm -rf $(OUT) || true
rm -rf $(OBJ) || true
redo:
make PROJECT=$(PROJECT) DIRECTORY=$(DIRECTORY) PARAMETER=$(PARAMETER) clean
clear
make PROJECT=$(PROJECT) DIRECTORY=$(DIRECTORY) PARAMETER=$(PARAMETER) $(OBJ)
mv $(PROJECT).o $(DIRECTORY) || true
make PROJECT=$(PROJECT) DIRECTORY=$(DIRECTORY) PARAMETER=$(PARAMETER) $(OUT)
./$(DIRECTORY)$(PROJECT) $(PARAMETER)
What this does is make the file with minimal editing allowing bash scripts to run the makes. Though I still need to work-out and externalize the L variable for bash scripts.
Here's m.sh. A better name could be chosen, but I was in a hurry. Perhaps bmake.sh.
#!/bin/bash
PROJECT=$1
DIRECTORY=$2
ACTION=$3
FLAG=$4
PARAMETER=$5
make PROJECT=$PROJECT DIRECTORY=$DIRECTORY PARAMETER=$PARAMETER $ACTION $FLAG
unset PROJECT
unset DIRECTORY
unset ACTION
unset FLAG
unset PARAMETER
This is the function that calls the Makefile. So instead of "make me some blah blah, it's "bash make.sh".
So, the test case is for this tutorial found here. It's a remarkable tutorial on network programming with Boost::Asio, and all of the examples are in a zip (1a.cpp, 1b.cpp, etc.). THe files are to be unzipped into a directory, which is hard coded in a bash, in this example "example/" is used. The scripts do what I wish. I suppose I have two scripts to make the distinction between the general and the specific.
#!/bin/bash
PROJECT=$1
DIRECTORY=example/ # or $2
ACTION=$3
FLAG=$4
PARAMETER=$5
bash m.sh $PROJECT $DIRECTORY $ACTION $FLAG $PARAMETER
This file is not strictly necessary, though, as you can simply execute m.sh. I simply created it for this test example. For FLAG, I recommend passing in -n, which outputs what the make file would've done if it had not been a test. This is very useful as it is dangerous to execute the makes cold out of the code freezer.
I thought I'd share and get some feedback on how to make it better as I am somewhat of a beginner on both bash scripting and Makefiles.
This is how to do a trial run:
bash example.sh 1a example redo -n
And, this is how to run it:
bash example.sh 1a example redo
Result:
make PROJECT=1a DIRECTORY=example/ PARAMETER= example/1a.o
make[1]: Entering directory '/wherever'
g++-7 -std=c++1z -Wall -c -g example/1a.cpp
make[1]: Leaving directory '/wherever'
mv 1a.o example/ || true
make PROJECT=1a DIRECTORY=example/ PARAMETER= example/1a
make[1]: Entering directory '/wherever'
g++-7 -std=c++1z -Wall -g example/1a.o -o example/1a -I/user/local/boost -lboost_system -lboost_thread -lpthread
make[1]: Leaving directory '/wherever'
./example/1a
Do you reckon this line displays?
The redo allows it to clean itself from the last build, and do the build over again. It's important to force the directory so that you never do something stupid like delete a bunch of files.
Makefile (redo)
redo:
make PROJECT=$(PROJECT) DIRECTORY=$(DIRECTORY) PARAMETER=$(PARAMETER) clean
clear
make PROJECT=$(PROJECT) DIRECTORY=$(DIRECTORY) PARAMETER=$(PARAMETER) $(OBJ)
mv $(PROJECT).o $(DIRECTORY) || true
make PROJECT=$(PROJECT) DIRECTORY=$(DIRECTORY) PARAMETER=$(PARAMETER) $(OUT)
./$(DIRECTORY)$(PROJECT) $(PARAMETER)
Though, instead of two bash files, I really only need one bash file with a configuration file, which the bash file can draw upon, which I think is the next logical step. Though it does suit my needs. Enjoy, and if so inclined, comment, and let me know how to best make a config file for this. Bash it if you must, haha.