I am trying to export an env variable in make to use in on the next lines. I am doing as suggested here Setting environment variables in a makefile.
eks-apps:
export KUBECONFIG=$(CURDIR)/terraform/kubernetes/cluster/$(shell ls terraform/kubernetes/cluster/ | grep kubeconfig)
kubectl get all
But its not using that kubeconfig in the kubectl command. What am I missing?
Every line in a recipe will be executed in a new shell. As this you have to use a single shell for all your commands:
eks-apps:
( \
export KUBECONFIG=$(CURDIR)/terraform/kubernetes/cluster/$(shell ls terraform/kubernetes/cluster/ | grep kubeconfig); \
kubectl get all \
)
From the answer you are linked to:
Please note: this implies that setting shell variables and invoking shell commands such as cd that set a context local to each process will not affect the following lines in the recipe.2 If you want to use cd to affect the next statement, put both statements in a single recipe line
$(shell command -v docker) What command means? it's being used in a Makefile.
I saw this in a github repository that I'm trying to understand.
It looks like it's setting a variable with a command to test if docker is installed, and stop the build if its not, the problem is this that I don't have a command installed and I tryed to install command in ubuntu but it can't find it, looking on internet how to install this commad command seems realy difficult because of its name, how to install command in linux/ubuntu didn't bring anything useful, also search for this being using on Makefiles trying to get some clue but nothing so far.
Running the build command seems to work becuse it build the image and yes I have docker installed, but still getting that message in the terminal make: command: Command not found
Any idea?
make build output (trucated):
$ make build
make: command: Command not found
make: command: Command not found
docker build -t codelytv/typescript-ddd-skeleton:dev .
Sending build context to Docker daemon 1.023MB
.....
This is the Makefile:
.PHONY = default deps build test start clean start-database
IMAGE_NAME := codelytv/typescript-ddd-skeleton
SERVICE_NAME := app
# Test if the dependencies we need to run this Makefile are installed
DOCKER := $(shell command -v docker)
DOCKER_COMPOSE := $(shell command -v docker-compose)
deps:
ifndef DOCKER
#echo "Docker is not available. Please install docker"
#exit 1
endif
ifndef DOCKER_COMPOSE
#echo "docker-compose is not available. Please install docker-compose"
#exit 1
endif
default: build
# Build image
build:
docker build -t $(IMAGE_NAME):dev .
# Run tests
test: build
docker-compose run --rm $(SERVICE_NAME) bash -c 'npm run build && npm run test'
# Start the application
start: build
docker-compose up $(SERVICE_NAME) && docker-compose down
# Clean containers
clean:
docker-compose down --rmi local --volumes --remove-orphans
# Start mongodb container in background
start_database:
docker-compose up -d mongo
What it means is that the person who wrote this makefile wasn't careful enough to write it in a portable way.
The command command is part of the shell (which is why you won't see it if you look for it in the GNU make manual). Not only that, it's part of the bash shell specifically: it is not a POSIX sh standard command. The bash man page says:
command [-pVv] command [arg ...]
Run command with args suppressing the normal shell function
lookup. Only builtin commands or commands found in the PATH are
executed.
Basically, running command docker ... means that any shell alias or function named docker is ignored, and only the actual docker command is run.
However, GNU make always runs /bin/sh as its shell, including for both recipes and for the $(shell ...) function.
So, if you're on a system (such as Red Hat or CentOS or Fedora GNU/Linux) where the /bin/sh is a link to the bash shell, then the above command will work.
However, if you're on a system (such as Debian or Ubuntu GNU/Linux) where the /bin/sh is a link to a simpler POSIX shell such as dash, then the above command will not work.
In reality, this is not needed because there won't be any shell aliases or functions defined in the shell that make invokes, regardless. However, if the author wants to use bash shell features in their makefiles and allow them to work, they also need to tell make to use bash as its shell, by adding this to their makefile:
SHELL := /bin/bash
(of course this assumes that the user has a /bin/bash on their system, but...)
I have following Makefile target defined:
.PHONY: docker-build
docker-build:
# Build Docker image
docker build \
--squash \
...
-t $(DOCKER_IMAGE):$(DOCKER_TAG) .
output:
#echo Docker Image: $(DOCKER_IMAGE):$(DOCKER_TAG)
I need to use the variables DOCKER_IMAGE and DOCKER_TAG as input for another script to run right after the make docker-build.
Do you have any idea how to do it? Thanks in advance.
I have tried many ways but can't get the output from Makefile to environment variables or even just to terminal.
Consider the following npm scripts.
$ npm run
available via `npm run-script`:
make
OUTPUT=dist/main.js bash -c 'elm make src/Main.js --output=$0 $1'
make:dev
npm run make -- '$OUTPUT' --debug
make:prod
npm run make -- '>(npm run uglify -- $OUTPUT)' --optimize
uglify
uglifyjs --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle --output=
I'd like to use it as follows:
$ npm run make -- '$OUTPUT' '--debug'
> experiment#0.1.0 experiment /Users/Adit/experiment
> OUTPUT=dist/main.js bash -c 'elm make src/Main.js --output=$0 $1' '$OUTPUT' '--debug'
This would correctly create the debug build of the Elm application. However, this is not what happens. Instead of using single quotes, npm run uses double quotes:
$ npm run make -- '$OUTPUT' '--debug'
> experiment#0.1.0 experiment /Users/Adit/experiment
> OUTPUT=dist/main.js bash -c 'elm make src/Main.js --output=$0 $1' "$OUTPUT" "--debug"
Due to this the output is not what I expect it to be. What's the best way to resolve this issue without writing a custom shell script? I want to use the OUTPUT variable in two different commands. However, I only want to define it in one place.
I solved the problem as follows.
{
"config": {
"input": "src/Main.elm",
"output": "dist/main.js"
},
"scripts": {
"make": "elm make $npm_package_config_input --output $npm_package_config_output",
"make:dev": "npm run make -- --debug",
"make:prod": "npm run make -- --optimize",
"postmake:prod": "uglifyjs $npm_package_config_output --compress 'pure_funcs=\"F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9\",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle --output=$npm_package_config_output"
}
}
Hence, if you have a configuration variables that you'd like to use in multiple npm scripts, you can add them to the config dictionary of package.json. After that, you can access them as environment variables in the npm scripts via the name $npm_package_config_<name> where <name> is the name of your config variable.
I also used a post script instead of process substitution to uglify the output of the Elm compiler. Doing so was overall less of a hassle than using process substitution via bash -c.
Finally, you can run make, make:dev, or make:prod for different builds. The first one is a regular build. The second one is a development build with the Elm debugging tools. The third one is a regular build which is optimized and minified for production use.
this is my first time using makefile to simplify my hybrid mobileapps developement. So, i have this pretty makefile which refuses to run after some commands. Please have a check.
.PHONY: run
OUTPUT_FILE=final.apk
ALIAS=mycert
KEYPASS=shittypass
KEYSTORE=certs/bang.keystore
UNSIGNED=platforms/android/build/outputs/apk/android-release-unsigned.apk
PACKAGE='com.example.testapp'
sign:
del -f ${OUTPUT_FILE}
cordova build android --release
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore ${KEYSTORE} -storepass ${KEYPASS} ${UNSIGNED} ${ALIAS}
zipalign -v 4 ${UNSIGNED} ${OUTPUT_FILE}
execute:
adb shell am start -n ${PACKAGE}/${PACKAGE}.MainActivity
install:
adb install -r ${OUTPUT_FILE}
log:
adb logcat | grep `adb shell ps | grep ${PACKAGE} | cut -c10-15`
run: sign install execute log
The commands under "sign:" section are running perfectly but log: execute: and install: are not even showing in the cmd.
I am using Windows 7 and GnuWin32 make program.
make always tries to build only the first target in the makefile, unless you specify a specific target on the command line; for example you could invoke make sign install execute log and it would run them all.
It looks like you wanted the run target to be the default target when you type make; if so it must be the first target in the makefile not the last one.
Also, you should not be indenting the log and run targets like you do in your example above. It's confusing at best and an error at worst.