Create a variable in a makefile by reading contents of another file

Makefile

Makefile Problem Overview


How can I create a variable on-the-fly from makefile, the value of which would be the entire contents of another data file.

Makefile Solutions


Solution 1 - Makefile

Assuming GNU make:

file := whatever.txt
variable := $(shell cat ${file})

Solution 2 - Makefile

I'm guessing that you like to set a variable in your Makefile to the contents of another file:

FILE=test.txt
VARIABLE=`cat $(FILE)`

target:
	echo $(VARIABLE)

Solution 3 - Makefile

GNU make version 4.2 supports file reading operation, so with respect to Maxim Egorushkin's great answer there is an optional way to solve this problem now:

FILE     := test.txt
variable :=$(file < $(FILE))

Solution 4 - Makefile

cat doesn't exist on Windows. Solution that works for Linux and Windows:

cat := $(if $(filter $(OS),Windows_NT),type,cat)
variable := $(shell $(cat) filename)

Explanation: Seems like On Windows there is always OS environment variable defined to be equal to 'Windows_NT'. This way, for Windows type command is used, for non-Windows cat is used.

Solution 5 - Makefile

Much simpler since $(file op filename) was added:

VARIABLE = $(file < my_file.txt)

Manual page here: https://www.gnu.org/software/make/manual/html_node/File-Function.html#index-file_002c-reading-from

Solution 6 - Makefile

If you are using GNU make, another way to get this effect is to use a make "include" of another makefile:

From Makefile:

include "./MyFile.mak"

Create a file "MyFile.mak" with content:

FILE := "my file content"
FILE += "more content 1"
FILE += "more content 2"

Solution 7 - Makefile

As the platform has not been specified, this is the way how it works on Solaris:

VERSION:sh = cat VERSION

all:
        echo $(VERSION)

Solution 8 - Makefile

Here's a more portable solution, which works with MAKE version 3, where file directive isn't available. The downside is that it requires creating a temporary file in the process.

$(shell echo define my_variable > file.tmp)
$(shell cat my_file.txt >> file.tmp)
$(shell echo endef >> file.tmp)
include file.tmp

The main idea is to use define directive, which is specifically designed to declare multiline variables. Of course, you can avoid using shell and a temporary file if you can explicitly write file contents for Makefile usage.

Keep in mind that, if your file contains $ signs, MAKE will try to expand them as variables/directives when my_variable is expanded (or when assigned, of you define it with :=). If you want to avoid it, you need to escape them before including file contents. For example, instead of cat you can do this:

$(shell sed 's/\$$/$$$$/g' my_file.txt >> file.tmp)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSrinathView Question on Stackoverflow
Solution 1 - MakefileMaxim EgorushkinView Answer on Stackoverflow
Solution 2 - Makefilebb-generationView Answer on Stackoverflow
Solution 3 - MakefileyurimzView Answer on Stackoverflow
Solution 4 - MakefilePavel PView Answer on Stackoverflow
Solution 5 - MakefilegatopeichView Answer on Stackoverflow
Solution 6 - MakefileBimoView Answer on Stackoverflow
Solution 7 - MakefilecevingView Answer on Stackoverflow
Solution 8 - MakefileThunderbeefView Answer on Stackoverflow