I have the following code in a makefile:
TEMP="VBU538ForBootloader"
# build
build: .build-post
.build-pre:
# Add your pre 'build' code here...
.build-post: .build-impl
#echo "Current config:" $(CONF)
#echo "Compare to:" $(TEMP)
ifeq ($(CONF),$(TEMP))
#echo "Making production files for VBU538 .... "
else
#echo "Skipping production files."
endif
Somehow the ifeq does not do what I expected, although it looks to me that my code is similar to other examples. The code produces the following output:
Current config: VBU538ForBootloader
Compare to: VBU538ForBootloader
Skipping production files.
I am always getting Skipping production files. although I expected that the output should have been Making production files for VBU538 ....
Does anyone know the reason why its not behaving as expected?
Your code is not an MCVE so it is difficult to help. It could be that your COMP and TEMP variables look identical but they are not (spaces, other invisible characters...) You could try to check this by using:
#echo 'Current config: X$(CONF)X'
#echo 'Compare to: X$(TEMP)X'
instead of
#echo "Current config:" $(CONF)
#echo "Compare to:" $(TEMP)
I eventually found the problem. Thanks for everybody's effort. Eventually I got a hunch that when I was calling make, the wrong make utility was being used. It turned out that I have to use the same make utility as the one that came with the IDE for the microcontroller. I am not sure why that would be needed, but using the make utility that came with the IDE solved the problem.
Related
Here is a sample makefile that demonstrates what I'm trying to accomplish:
PLATFORM=wrongName
debug:
#echo debug $(PLATFORM)
debug-android: android debug
android:PLATFORM=android
android:
#echo set PLATFORM to $(PLATFORM)
here is the terminal output:
user:~/Project/maketest$ make debug-android
set PLATFORM to android
debug wrongName
when calling the target make debug-android my intention is to set the PLATFORM variable to "android", and that works in the android: command, however the "PLATFORM" var reverts to "wrongName" default value set at the top of the makefile. I'm trying to replace the value here so that any subsequent dependencies for the target will also see the value of "PLATFORM" as "android".
so my question is: how do i make "PLATFORM" variable assignment persist between commands/targets?
There are a couple of different ways to do this, but you still haven't made clear exactly what you want these rules to do, conceptually.
Here is one way:
debug-android:PLATFORM=android
debug-android: android debug
android:
#echo set PLATFORM to $(PLATFORM)
EDIT:
Ah, so the idea is to avoid repetition of PLATFORM=android. Try this:
PLATFORM=wrongName
all: debug-android prod-android test-android
debug:
#echo Debug $(PLATFORM)
prod:
#echo Prod $(PLATFORM)
test:
#echo Test $(PLATFORM)
%-android: PLATFORM=android
debug-android: debug
test-android: test
prod-android: prod
If this is on the right track, we can go farther, removing the redundancy of those last three lines.
In general, it's a bad idea to do this. Most of the time if you want to do it, it probably means that you should be thinking about the problem differently.
However, it is possible to do this (in GNU make only) using eval. Usually when I see eval used in a recipe it's a code smell but it does work:
android:
$(eval PLATFORM := $(PLATFORM))
#echo set PLATFORM to $(PLATFORM)
I want to make automatically the documentation of my project with my makefile.
I also create a target doc (and a variable DOC_DIRECTORY = ../doc) to specify the directory of the documentation. In my doxygen file, I added a log file name "doxyLog.log" in the ../doc/ directory.
Here is my target definition :
#Creation of the Doxygen documentation
doc: $(DOC_DIRECTORY)/path_finder_doc
doxygen $(DOC_DIRECTORY)/path_finder_doc
#echo $(shell test -s ../doc/doxyLog.log; echo $$?)
ifeq ($(shell test -s ../doc/doxyLog.log; echo $$?),1)
#echo "Generation of the doxygen documentation done"
else
#echo "Error during the creation of the documentation, please check $(DOC_DIRECTORY)/doxyLog.log"
endif
To test if my check is working, I manually introduce an error in my documentation (a bad command like \retufjdkshrn instead of \return). But, when I launch the make doc, this error appears after the second time :
First make doc (with an error in the doc ) --> Generation of the doxygen documentation done
Second make doc (always the error in the doc) --> Error during the creation of the documentation, please check ../doc/doxyLog.log
I don't understand why, can someone help me please?
There appear to be two things wrong here, so parts of this answer must be guesswork.
First:
ifeq ($(shell test -s ../doc/doxyLog.log; echo $$?),1)
#echo "Generation of the doxygen documentation done"
As I understand test, it will return 0 if the file exists and 1 if the file does not exist. I suspect that you didn't test this before putting it into your makefile.
Second, you are confusing shell commands with Make commands. This:
ifeq ($(shell test -s ../doc/doxyLog.log; echo $$?),1)
#echo "Generation of the doxygen documentation done"
else
#echo "Error..."
endif
is a Make conditional. Make will evaluate it before running any rule. Since the log file does not yet exist, the shell command will return 1 (see First), the conditional will evaluate to true and the entire if-then-else statement will become
#echo "Generation of the doxygen documentation done"
This will become part of the rule before the rule is executed. On the next pass, the file already exists, the shell command returns 0 and the the statement becomes
#echo "Error..."
This explains why you're getting strange results.
If you want Make to report on the results of the attempt it's just made, you must put a shell conditional in a command in the rule:
doc: $(DOC_DIRECTORY)/path_finder_doc
doxygen $(DOC_DIRECTORY)/path_finder_doc
#if [ -s ../doc/doxyLog.log ]; then echo Log done; else echo error...; fi
I'm working on a project with the Dialogic DivaSDK to be able to analyze telephone calls. Since the DivaSDK supports Java via JNI, I wanted to give the samples a try. Unfortunately: the whole Java documentation is not as complete as the C# one is. So it seems to be like fishing in murky waters.
In my first step I wanted to look into the sample ( Link to DivaSDK with Sample Files )files and try them out. Each sample has a makefile which has to be run. The only part within the manual which scratches my problem sounds like this:
For details how to compile and link your application please have a look at any of the samples provided with the Diva SDK. In every sample subdirectory you will find a makefile, that describes the compilation and link process of that application. The evaluation of the makefile requires some knowledge of shell scripting and makefile syntax and is beyond the scope of this document.
My problem right now is that the given makefile doesn't work the way it is supposed to be. I get the error "No Targets" Since I have not that much knowledge of makefiles, I can't figure out what is wrong with that file.
#-------------------------------------------------------------------------------
#
# makefile to geenrate the Diva SDK Java sample "SimpleApp". This makefile
# generate the class files for teh framework and the sample and creates
# a SimpleApp.jar that can be executed via jav -jar SimpleApp
#
# The makefile assumes that the java development enmvironment is installed and
# the java tools are accessable from the command prompt.
#
#-------------------------------------------------------------------------------
FRAMEWORK_PATH=..\..\Framework
FRAMEWORK=$(FRAMEWORK_PATH)\DivaAPI.java $(FRAMEWORK_PATH)\DivaCallBase.java
BIN_DIR=.\bin
SRC_DIR=.\src
TRAGET=SimpleApp
#edited with hint from #Aaron Digulla
all : $(BIN_DIR)\$(TRAGET).jar
SRC=$(SRC_DIR)\SimpleApp.java \
$(SRC_DIR)\AppCall.java
$(BIN_DIR)\$(TRAGET).jar: $(SRC)
#echo #-----------------------------------------------
#echo # Generate class files
#echo #-----------------------------------------------
javac -d $(BIN_DIR) -sourcepath $(FRAMEWORK_PATH) $(FRAMEWORK) $(SRC)
#echo #-----------------------------------------------
#echo # Generate jar files and clean class and manifest
#echo #-----------------------------------------------
copy $(SRC_DIR)\manifest.txt $(BIN_DIR)
cd $(BIN_DIR)
jar -cvfm $(TRAGET).jar manifest.txt *.class > nul
del *.class
del manifest.txt
cd ..
#echo #-----------------------------------------------
#echo # $(BIN_DIR)\$(TARGET).jar successfully created
#echo #-----------------------------------------------
It seems, that the target definition is wrong, but I don't know in which way. Any tips would be very much appreciated.
edit1: With the hint from #Aaron Digulla it works a little bit better. At least the target is recognized. But now there is an error which tells me, that there are no rules to create the jar.
edit2: Well... It seems that the filepaths are wrong. If I replace some of the backslashes ( "\" ) with normal slashes ( "/" ), the compiling starts. It stops at copy though...
The error means there is no target all in the Makefile and make cowardly refuses to continue.
My guess is that this Makefile is supposed to be called from another Makefile.
Add this line to the Makefile:
all : $(BIN_DIR)\$(TRAGET).jar
and it should work. If the error persist, make sure you use GNU make or try make all
There is a Makefile that I am using, which I got from somewhere, and which is quite big. I have also found some things that I'd like changed occasionally in the makefile - and the easiest way to do that for me is to define (or not) a (switch) variable (say, OVWRCHOICE) at the start of the makefile; and then later on in the makefile code, do something like:
ifdef OVWRCHOICE
MYOPT = override
....
endif
... which is all dandy and fine.
The thing is, eventually I also need to change parts in the "override" part as well, so I'd like to have it at the start of the file. So, as this "override" part contains several make commands -- I tried to use define, to have a variable which will contain the commands (which would be executed at the ifdef OVWRCHOICE... part).
So I arrived at this simple example:
# uncomment as needed;
OVWRCHOICE = YES
define SET_OVWRCHOICE
MYOPT = override
endef
export SET_OVWRCHOICE
# ... many lines of code ...
MYOPT = default
# ... many lines of code...
# without indent: Makefile:18: *** missing separator. Stop.
# with tab indent: Makefile:18: *** commands commence before first target. Stop.
ifdef OVWRCHOICE
$(SET_OVWRCHOICE)
endif
all:
#echo $(MYOPT)
... which fails with the errors noted. Of course, if I use the first snippet in the post instead, all runs fine, and make prints out the expected result: "override".
How would I go about in achieving something like this? Not sure if "inclusion" or "execution" of "Makefile commands" are even the right terms in this context; so I have a hard time in finding a starting point for a search :)
Got it - it is described in Eval Function - GNU `make'; the right construct is:
ifdef OVWRCHOICE
$(eval $(call SET_OVWRCHOICE))
endif
Hope this helps someone,
Cheers!
Oh well, didn't really know where to archive this snippet, so back to this old question of mine :) this is off topic for OP; but here goes:
To test how environment variables are processed by a makefile, here is a simple example:
Foo=something
all :
ifdef DEBUG
#echo "Debug defined"
else
#echo "Debug NOT defined"
endif
... and here is the test for it:
$ make
Debug NOT defined
$ make DEBUG
make: *** No rule to make target `DEBUG'. Stop.
$ DEBUG make
DEBUG: command not found
$ DEBUG= make
Debug NOT defined
$ DEBUG=1 make
Debug defined
... so obviously, the right syntax to set that variable inside the makefile from the command line is: "DEBUG=1 make"
With make on linux, we can do things like:
foo=$(shell /bin/bar)
which runs the command bar and assigns the output to foo. This can later be used in the makefile by referencing $(foo).
But now I have a Microsoft project on my hands that is compiled and linked with the Microsoft nmake.exe. Is there an equivalent thing for nmake that would allow me to run a command and assign the output to a variable?
Although this is an old question, there is a method of doing what is asked; its just convoluted, like everything in batch files!
One has to use the combined mechanisms of the fact that make imports environmental variables and that the preprocessor can invoke commands, and then call the Makefile recursively. It assume the Makefile is called Makefile (with no extension, which is the default).
!IFNDEF MAKE
MAKE=NMAKE
!ENDIF
!IFNDEF SHELLVALUE
! IF [echo off && FOR /F "usebackq" %i IN (`hostname`) DO SET SHELLVALUE=%i && $(MAKE) /$(MAKEFLAGS) /nologo /f $(MAKEDIR)\Makefile && exit /b ] == 0
! MESSAGE Make completed
! ELSE
! ERROR Error in nmake
! ENDIF
!ELSE
# $(SHELLVALUE) now contains the string returned from the command USERNAME
!MESSAGE Shellvalue is $(SHELLVALUE)
# Put the parts of the makefile that depend on SHELLVALUE here
!ENDIF
#
# To be a valid makefile it must have some rules to perform
all:
#echo;$(SHELLVALUE)
Yes, I know its horrible, but it does demonstrate how to do the technique, which can be done with any shell command and not just hostname.
I think the answer is "no." There is no equivalent.
I'd recommend that you convert to MSBuild if possible.