Add command line argument to Makefile from CMake - makefile

I am using CMake to create a makefile for my project. I would like my Makefile to have several if's like:
ifeq "$(ARM)" "1"
# do something
endif
Is something like that possible from CMake?

Related

How to use a static library's module in Fortran program depending on Makefile's configuration [duplicate]

This question already has an answer here:
Conditional compilation in gfortran
(1 answer)
Closed 4 years ago.
I'm importing the following module (from an static library) in a file named initprogram.f90 this way:
use device_info
However I only want to include this library when this option in the Makefile is selected:
ifeq ($(strip $(WITH_GPU)),1)
(When WITH_GPU is equal to 1). If I'm not using a GPU, device_info.mod should not be available, since I don't need it. How can I do that?
Basically I want to get rid of this error:
Fatal Error: Can't open module file 'device_info.mod' for reading at (1): No such file or directory
When compiling without the library where device_info.mod is defined.
You probably need:
A preprocessor to hide or not the use device_info declaration in your Fortran source file, depending on an option you pass to it. Do you have a preprocessor in your Fortran compilation chain? If yes do you know how to pass it options from the command line and how to use them in your source file to hide or not parts of your code?
Pass the right option to the compiler chain from your Makefile.
Let's assume you do have a preprocessor and it has an #ifdef - #endif macro. Let's also assume your compiler chain takes options -D MACRO=VALUE from the command line. And let's assume the syntax of your compiler command looks like:
<compiler-name> <options> <source-file> -o <binary-output-file>
Just edit your source file and add:
#ifdef WITH_GPU
use device_info
#endif
And then, edit your Makefile:
COMPILER := <whatever-compiler-you-use>
COMPILER_FLAGS := <whatever-compiler-options-you-need-by-default>
OTHER_DEPENDENCIES := <whatever-default-dependencies>
ifeq ($(strip $(WITH_GPU)),1)
COMPILER_FLAGS += -D WITH_GPU=1
OTHER_DEPENDENCIES += device_info.mod
endif
initprogram.exe: initprogram.f90 $(OTHER_DEPENDENCIES)
$(COMPILER) $(COMPILER_FLAGS) $< -o $#
(the $< and $# make automatic variables expand respectively to the first prerequisite (initprogram.f90) and the target (initprogram.exe) of the rule).

Export preprocessor macro in makefile

I want to export preprocessor macro to an internal makefile from the main makefile in a particular target.
example:
Main_Makefile
target1 :
CXXFLAGS+=-DNewFlag=NewFlag
cd some_directory; make
Here I want to use value of CXXFLAGS which is -DNewFlag=NewFlag and is only defined under target1 in some_directory/make
Please let me know how can I achieve this.
There is no way to append to a variable from the command line, unless you've made arrangements for it in the makefile of the subdirectory.
The simplest thing to do is use a different variable, like this:
target1:
cd some_directory && $(MAKE) EXTRA_CXXFLAGS=-DNewFlag=NewFlag
(note you should always use $(MAKE) or ${MAKE} when invoking a sub-make, never make directly.)
Then in the subdirectory makefile you do something like this:
CXXFLAGS += $(EXTRA_CXXFLAGS)

How can I add a directory to the search path of GNU Make?

I have a makefile that looks something like this:
include anotherFile.mk
all:
someStuff
The file anotherFile.mk is like this:
include yetAnotherFile.mk
export SOME_VAR = 93
The problem is that anotherFile.mk and yetAnotherFile.mk are in a different directory from my Makefile. So my makefile can't just be changed to this:
include $(OTHER_PROJECT_PATH)/anotherFile.mk
all:
someStuff
The problem with this approach is that the include statement in anotherFile.mk will fail because it will be searching in the current directory.
A partial solution that I found is to pass the --include-dir=$OTHER_PROJECT_PATH flag to the invocation of make, but that's a bit user-unfriendly.
So my question is: Is there something I can put inside my makefile that will add to the directories that make searches for when executing an include? Something like MAKE_INCLUDE_DIRS += $(OTHER_PROJECT_PATH)
Surprisingly there doesn't seem to be a good answer to that question. Forcing .INCLUDE_DIR doesn't help and there doesn't seem to be any way around invoking make with --include-dir=$OTHER_PROJECT_PATH.
It is however possible to put the appropriate recursive make invocation inside the makefile but, in order to get it to work for all reasonable cases it quickly becomes too complicated to be worth it. In summary it requires:
a top level condition to check if the OTHER_PROJECT_PATH is in .INCLUDE_DIR
the appropriate target with the recipe invoking make recursively
possibly additional targets if there are multiple command goals
the real make file enclosed in the else part of the conditional
You Makefile would look like this:
OTHER_PROJECT_PATH := other
ifeq (,$(filter $(OTHER_PROJECT_PATH), $(.INCLUDE_DIRS)))
# this is the mechanism to add the include dir in a recursive make
$(or $(firstword $(MAKECMDGOALS)),all):
$(MAKE) -I$(OTHER_PROJECT_PATH) $(MAKECMDGOALS)
# add empty targets for additional goals if needed
ifneq (,$(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)))
$(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)):
endif
else
# this is where the real makefile starts
all more:
echo $#: $< $^
include a.mak
endif
It still does not seem possible from a makefile, but if you have a script that sets up environment variables, you can use MAKEFLAGS (e.g. export MAKEFLAGS=I/your/path ordentlich on Linux, or SET on Windows)

CMake how to transfer shell command in CMakeLists.txt into Makefile

The problem: i want to echo some info when make makefile, the makefile is generated by CMakeLists.txt, and i don't want to echo the info when cmake CMakeLists.txt, what should i do?
In Makefile, the code is like this:
.build-pre:
#echo
#echo "###########################################################"
#echo "######## Welcome to Prosim Build System ###################"
What should i wirte in the CMakeLists.txt so that i can get like these in MakeFile?
You can use add_custom_target function to create a dummy target that has dependencies set to all other targets causing it to be built first.
You can use the ALL option to make it build every time. However, you will still need to use add_dependencies to make it build before every other target.
Finally, use the command-line tool mode of CMake to make it platform independent. (The COMMENT option of add_custom_target may be enough to show the message).
add_custom_target(display_intro ALL COMMAND cmake -E echo Foo)
# ....
add_executable(your_app ...)
add_dependencies(your_app display_intro)
add_library(your_lib ...)
add_dependencies(your_lib display_intro)
For convenience, you could probably wrap the add_executable and add_dependencies in a function or macro.

How to preprocess makefiles

How to show the makefile after it's been preprocessed? For example, if we have two makefiles:
# Makefile
include Makefile2
# Makefile2
a:a.c
gcc -o a a.c
Then <preprocessor> Makefile should give:
a:a.c
gcc -o a a.c
It's similar to what a C preprocessor does (gcc -E). Is there such a makefile preprocessor?
You didn't specify for which make tool you are writing makefile. Assuming that it is GNU make, you can try running makefile with -n (--just-print) option See Command-Line Options chapter here. That will show what make is going to execute without execution (however, the commands needed for evaluation of variables will be executed). This is probably the closest to what you want to see.
This causes make to read the makefile and print every command it would
normally execute to update the target but without executing them.
Apart from that there is $(warning ) function to debug makefiles. You can place it almost to any part in makefile and the following will show you the values of all defined variables in that place:
$(warning Variables HERE: .VARIABLES)

Resources