Why exported variables in Makefile is not received by executable?
If I'm not mistaken each line in a Makefile is a separate shell-process. So shell-export does not work for several processes: One way to do it is to put them into one line:
test:
@ echo
@ echo "Testing Electric Fence."
@ echo "After the last test, it should print that the test has PASSED."
./eftest
./tstheap 3072
EF_ERRTRACK_START=3 EF_ERRTRACK_END=5 ./time-interval-measurement-test
@ echo
@ echo "Electric Fence confidence test PASSED."
@ echo
or line-break-escaped with '\'
test:
[..]
EF_ERRTRACK_START=3 \
EF_ERRTRACK_END=5 \
./time-interval-measurement-test
Like that the ENV-variables are available to ./time-interval-measrument
C Makefile: How to build environment variable into executable
You can use the -D
option to create preprocessor variables on the command line.
CC=gcc
CFLAGS=-I
BUILD_TIME=`date`
example: example.c
$(CC) -D "BUILD_TIME=\"$(BUILD_TIME)\"" -o example example.c
#include <stdio.h>
int main()
{
printf("build time = %s\n", BUILD_TIME);
return 0;
}
How to set child process' environment variable in Makefile
Make variables are not exported into the environment of processes make invokes... by default. However you can use make's export
to force them to do so. Change:
test: NODE_ENV = test
to this:
test: export NODE_ENV = test
(assuming you have a sufficiently modern version of GNU make >= 3.77 ).
Export current user id in makefile for docker-compose
Here is my solution
#!/usr/bin/make
SHELL = /bin/sh
CURRENT_UID := $(shell id -u)
CURRENT_GID := $(shell id -g)
export CURRENT_UID
export CURRENT_GID
up:
docker-compose up -d
Eclipse Makefile: Make Variables are skipped
This is not right:
obstacleDetection_cpp: src/obstacleDetection.cpp protoc_middleman
export APR_INCLUDE=/usr/include/apr-1
export CMS_HOME=~/Desktop/activemq-cpp-library-3.8.4
g++ $(APR_INCLUDE) -I $(CMS_HOME)/src/main ...
All lines in the recipe (that is, lines that are indented with a TAB in a target context like this) are passed to the shell. These are not make variable assignments. There are two things wrong with that:
First, each logical line in the recipe is passed to a new shell. That means any changes to the process context (such as the environment or the working directory) are present only for the duration of that logical line; once the shell processing that line exits, all those changes are lost. So, these lines have no impact: they set an environment variable in the shell, then the shell exits and that setting is gone.
Second, the variable references you make in your compile line, such as $(APR_INCLUDE)
, are make variable references, not environment variable references. So even if those environment variable assignments still had effect, they would not be used because you're not referring to environment variables here.
You want to create make variable assignments. That can only be done outside of a recipe. Also, you don't need to export them because only make needs to see them (make will expand them before invoking the shell). So, your makefile should look like this:
APR_INCLUDE = /usr/include/apr-1
CMS_HOME = $(HOME)/Desktop/activemq-cpp-library-3.8.4
obstacleDetection_cpp: src/obstacleDetection.cpp protoc_middleman
g++ -I $(APR_INCLUDE) -I $(CMS_HOME)/src/main -g -o src/obstacleDetection.o -c src/obstacleDetection.cpp
cd libs && cp $(CMS_HOME)/src/main/.libs/libactivemq-cpp.so.18.0.4 . && ln -sf libactivemq-cpp.so.18.0.4 libactivemq-cpp.so.18
g++ -L $(CMS_HOME)/src/main/.libs/ -g -o bin/obstacleDetection src/obstacleDetection.o src-gen/Point.pb.cc src-gen/Point.pb.h -lactivemq-cpp -lssl -lprotobuf -pthread
@echo "Success. Run the executable from the binary directory with: LD_LIBRARY_PATH=../libs/ ./obstacleDetection"
How to set environment variables in makefile?
Your question isn't entirely clear but there are a number of obvious things wrong there.
First off you are running make
under Windows but writing recipes as if they were shell scripts. That's not the case on Windows (by default at least).
So export
is being attempted to be run as an external command which is failing (hence the error message about CreateProcess
failing).
You also don't show us the target that is actually throwing that error.
Additionally you are expecting the export
and assignment on the first line of the recipe to be in effect for the second line in the recipe body (for the start
target).
But that isn't the case. Each line in a makefile target's recipe runs in an independent environment. So the export
and assignment on the first line of the START
target's recipe doesn't affect the second line.
To do that you need to use one long line or use the .ONESHELL
feature of recent versions of make
.
Additionally, you are using $(NODE_ENV)
in your recipe expecting that to be the shell variable you previously set. And even ignoring the previously stated problem that isn't correct.
make is going to expand $(NODE_ENV)
as a make variable before it even runs the recipe at all. You meant ${NODE_ENV}
or $NODE_ENV
for a shell variable. That said for a make recipe you actually need to escape the $
because ${NODE_ENV}
is also a valid make variable expansion. So you need $${NODE_ENV}
or $$NODE_ENV
there.
Put together you end up with this (assuming you have a shell somewhere to use).
SHELL := /path/to/your/shell
START:
export NODE_ENV=110; \
echo "$${NODE_ENV}"
(though you don't actually need export
at that point but that's a different issue entirely).
But if you don't have a shell to use then you get to use cmd.exe
and I'm not sure what the equivalent of export
there is (though as I just said you don't need it for this) and you end up with something like this (entirely untested):
START:
NODE_ENV=110; \
echo %NODE_ENV%
load environment variables from a file in a makefile on windows
The .
command is a feature of the POSIX shell. You are not using a POSIX shell on Windows, you're using Windows cmd.exe.
First, you can't name the file win.env
. Windows cares a lot about file extensions so you'll have to name this file win.bat
or something like that.
Second, in Windows cmd.exe you just run the script; it doesn't start a new command program like POSIX systems do.
run:
ifeq ($(OS),Windows_NT)
win.bat; go run .
else
. ./lin.env && go run .
endif
Related Topics
Installing Octave Package in Ubuntu
How to Measure the Stack Size of a Process
Npm Install Causes Errors Like Npm Err! Tar.Unpack Untar Error on Debian
Create Position Independent Object File from Llvm Bit Code
Explanation of Memcpy Memmove Glibc_2.14/2.2.5
Can Old Arm32 Binary Files Be Run on Aarch64 Kernel
Does the Linux Scheduler Prefer to Run Child Process After Fork()
How to Change Alignment of Code Segment in Elf
Building Opencv as Static Libraries
Total Number of Lines in a Directory
Why Exported Variables in Makefile Is Not Received by Executable
How to Use a Linux Expect Script to Enter Answer a Prompt for Password
How to Capture All the Commands Typed in Unix/Linux by Any User
How to Find the Count of Multiple Words in a Text File
How to Narrow Down Perf.Data to a Time Sub Interval
When We Run an Executable, Do All the Sections Get Loaded into Memory at Once