I would like to use a preprocessor macro defined in one of my source files as a variable in my Makefile. The simplest way to do so would be to use sed like program to find the macro. However the macro is defined based on a condition (other macros), so a simple search for that macro can yield multiple results. This snippet may illustrate it:
#ifdef FOO
#define BAR 10
#else
#ifdef BAZ
#define BAR 50
#else
#define BAR 100
#endif
#endif
How can the Makefile know if FOO or BAZ are defined in the source files to eventually get the correct value of BAR during compilation?
A different take on that issue is to question oneself why a C constant has to play a role outside of the compilation process. One then often finds that this constant (and many others) are truly not a constant part of the C program but a configuration item. As such it is worth to consider if such configuration items should really be hidden inside a C source file or if it is cleaner to generate C source out of a better suited configuration format. In my experience every project sligthly larger than HelloWorld starts to profit very soon from a clean&controlled separation of concerns (source editing vs. config editing).
You may use cpp (or cc -E) for that. The easiest way to use it is to put all macro definitions into a header file, say macros.h. You need also a special C file (say macros.c), where you only use your macros. Choose a prefix which is easy to filter, like:
#include "macros.h"
valueOf_FOO = FOO
valueOf_BAR = BAR
Now, you can extract your macro values with
$(CC) -E $(CFLAGS) $(OTHER_CFLAGS) macros.c | grep '^valueOf_' | sed 's/valueOf_//'
This will print
FOO = FOO
BAR = 50
to the terminal.
Related
I am trying to build a framework which is supposed to apply similar operations to different designs/projects. Therefore, I have a general Makefile which defines general targets used for most of the operations. The idea is then that each design has its own main Makefile. This main Makefile includes the general Makefile for the general functionality, defines some variables for some basic configuration of the general Makefile, but can also extend or override variables from the general Makefile or define new targets or override targets when they are not applicable.
So the simplified directory structure looks something like this:
<Root Dir>
| -- targets.mk
| -- design1
| -- Makefile
| -- design2
| -- Makefile
The simplified general Makefile targets.mk looks something like this
${FF_LIST}: ${SRC_FILES}
#echo "Extract FF List for ${DESIGN_NAME}"
.PHONY: get_ff_list
get_ff_list: ${FF_LIST}
#echo "Get FF list for ${DESIGN_NAME} from ${FF_LIST}"
And the simplified design specific Makefile looks something like this:
include ../targets.mk
DESIGN_NAME = design1
FF_LIST = ./misc/ff_list.csv
With this implementation, I have the problem now, when calling the target get_ff_list within the design1 directory, that the recipe for the get_ff_list target is executed but the prerequisites are not, although the echo prints the right file.
user:/tmp/make_test/design1$ make get_ff_list
Get FF list for design1 from ./misc/ff_list.csv
It seems like that the target ${FF_LIST} is not expanded correctly. I can understand that during the time I am including the targets.mk Makefile this variable does not exist. However, my understanding of Makefile's recursive variable declaration with = should expand the variable every time the variable is used (as it is done and seems to work within the recipe itself).
I could include the targets.mk Makefile at the end after the configuration/setting the variables, like:
DESIGN_NAME = design1
FF_LIST = ./misc/ff_list.csv
include ../targets.mk
This seems to work and solve this particular issue. However, when I also want to extend or override variables/targets from the general Makefile, then it becomes a bit less obvious where to include it. Especially, if I am not the only one using the framework and other users create there own new designs.
Maybe this is even not a good way to use Makefiles to begin with. I would also be happy to get suggestions of better ways to implement this.
However, my understanding of Makefile's recursive variable declaration with = should expand the variable every time the variable is used (as it is done and seems to work within the recipe itself).
No. Read the section of the manual on How make Reads a Makefile to understand when variables are expanded immediately, and when the expansion is deferred.
The simplest way to do what you want is for the include targets.mk to come at the end of the Makefile, not at the beginning. If that's not feasible then you'll have to split the main makefile into two parts, one that sets variables and is included first, and the other that defines rules and is included last.
I'd like to "link" a C source #define to a makefile variable - to be able to define or undefine via make.
For example,
// my C source file
#ifdef SOMETHING
// do something
#else
// do something else
#endif
Then SOMETHING would be triggered from the make command line:
make something=true
This works for my makefile:
ifeq ($(something),true)
COMPILER_FLAGS += -DSOMETHING
endif
I am wandering, is this the proper way?
Is there an easier or better solution?
The following is not an ad-hoc solution but it requires you to use a make library: gmtt is the GNUmake table toolkit and was designed more or less with such a use case in mind. You can specify tables which you access with a (modest) form of the select statement known from a relational database. This way you escape convoluted ifeq hierarchies and can introduce build parameters rather easily. Of course one can argue that in my example three very simple ifeq paragraphs would have done also, without introducing a make library, but the advantage of the below solution is that tables force you to a separation of concerns and you don't need to worry that someone has sneaked in an addtional functionality in one of the ifeq's aside from generating #define's.
include gmtt/gmtt.mk
#define a 3-column table; there must be no empty cells (put in a comment)!
define project-defs =
3
type-1 APPLES 15
type-1 ORANGES 0
type-1 PEARS /*empty*/
type-2 APPLES 0
type-2 ORANGES 15
type-2 PEARS /*empty*/
type-3 APPLES 15
type-3 ORANGES 15
endef
#select column 2 and 3 of the above table and create a C-source line with '#define' from them
define project-defines :=
$(call map-select,2 3,$(project-defs),$$(call str-eq,$$1,$(project-type)),\#define $$1 $$2$$(newline))
endef
$(info Building with the following defines: $(project-defines))
$(file > project_def.h,$(project-defines))
With this makefile you now can invoke make project-type=type-1 and so on and the makefile will generate for you project_def.h which will serve as a normal header file instead of invisible defines in the command line.
Is it possible in Fortran to query the name of the function or subroutine that I am in? I.e., what do I put in place of '???' to get it to print 'my_subroutine' on the screen?
subroutine my_subroutine()
write(*,*) ???
end subroutine my_subroutine
I am trying to find a way to implement a custom debugger/profiler using nothing but a text editor's search and replace mechanism. Programmatically querying my position in the code would be helpful.
No, you can't. What you want to achieve is called reflection and it is not available in Fortran (nor in C or C++ for what matters).
You can use the preprocessor to print out the file name and line number. You might want take advantage of the predefined preprocessor symbols __LINE__ and __FILE__. Here's an example:
A preprocessor macro is defined in header file (so that it can be used in multiple locations), call it errormsg.h:
#define ERRORMSG(msg) write(0,'("There was an error at ",I4," in file ",/,A,/,"Error message: ",A)') __LINE__,__FILE__,msg
Then you can include this header file in your program, library or module files, for example:
#include "errormsg.h"
program main
ERRORMSG("not really an error...")
call foo()
end program
subroutine foo()
ERRORMSG("not an error too!")
end subroutine
The ERRORMSG("not really an error...") seems like weird syntax for fortran code, but it get's replaced by the c-preprocessor using the macro definition. So when this is compiled, it looks like:
write(0,'("There was an error at ",I4," in file ",/,A,/,"Error message: ",A)') __LINE__,__FILE__,"not really an error"
For my ERRORMSG macro, I chose to use the 0 file unit to print to stderr. You obviously have the freedom to write the message how ever you like, as long as it results in syntactical correct FORTRAN code.
Getting this to compile requires you to pass flags to the compiler, and they differ slightly from compiler to compiler. This worked for me, for example:
gfortran -cpp -o errorTest errorTest.f90
That is, for gfortran, -cpp invokes the c-preprocessor before compiling. The output from the above program looks like this:
There was an error at 5 in file
errorTest.f90
Error message: not really an error...
There was an error at 13 in file
errorTest.f90
Error message: not an error too!
This might have the effect you are looking for, especially if you write only one subroutine per file.
I found an easy semi-automated way out of this situation: use regex to add a hardcoded definition of __FUNCTION__ right after the SUBROUTINE declaration. Done from within the makefile will take care that every compilation refreshes the __FUNCTION__ macro.
Suppose we have a F77 listing that looks like this
file 'my-file.F'
SUBROUTINE my_sub(var1, var2, var3)
INCLUDE 'some-include.PRM'
INTEGER var1
INTEGER var2
! the rest of my code here
WRITE(*,*)__FUNCTION__
END SUBROUTINE
I want to convert it to
file 'my_file.F.F'
SUBROUTINE my_sub(var1, var2, var3)
#undef __FUNCTION__
#define __FUNCTION__ "my_sub"
INCLUDE 'some-include.PRM'
INTEGER var1
INTEGER var2
! the rest of my code here
WRITE(*,*)__FUNCTION__
END SUBROUTINE
Note the amended code is now located in another source file: my-file.F.F
To do this I added the following lines to 'Makefile'
my-file.o: my-file.F
perl -pne 's/^(\s+SUBROUTINE\s*)([^(]+)(\(.*\))/$$1$$2$$3\n#undef __FUNCTION__\n#define __FUNCTION__ _S($$2)/ixms' $< > $<.F; \
$(FC) $(CPPFLAGS) $(FCFLAGS) -c $<.F -o $#
Assuming FC is defined as the fortran compiler executable, this should perform the following procedure on all the subroutines in the file:
undefine a __FUNCTION__ macro that was possibly defined earlier.
Add a __FUNCTION__ directive two lines below the SUBROUTINE definition, containing the subroutine's name.
save the file under another name.
compile the new source into the required object file.
The result should be my-file.o in this case.
You may have noticed that I'm using the macro _S() as well. This is a 'stringify' macro. You just need to add it to the top of your fortran file (I place it inside a config.h that I include everywhere)
There is a different implementation for GNU and intel:
#ifdef __INTEL_COMPILER
#define _S(x) #x
#else
#define _S(x) "x"
#endif
There are sometimes non-standard features in compilers to help you to print where you currently are. These are highly compiler specific and should be used only for debugging.
In gfortran you can use subroutine BACKTRACE. From the manual:
BACKTRACE shows a backtrace at an arbitrary place in user code.
Program execution continues normally afterwards.
The output will look like an error message, but it may be helpful.
Why don't you just hard write the name of the subroutine you're in, in the WRITE statement?
You cannot programmatically (dynamically) give or change the name of the subroutine, therefore I see no reason to try to access it either that way (about that: while I'm not sure that it is impossible to access it somehow, I'm quite sure that it is the wrong way to go ... you will cause yourself more trouble going that way, than just hard coding it).
Btw, why are you trying to print it out anyway? Wouldn't a well phrased diagnostic message be more informative?
I am trying to read some code that has a lot of macros in it. And often the macros are chained. Is there any way to see a version of the file where all the macros have been expanded -- without doing a full run of the preprocessor (which would also do stuff like expand #imports)? This would really help me read the code.
EDIT: Often the macros are defined in other files.
Not sure if there's a way to do this in Xcode, but you can use the compiler, specifically the -E option, which stops processing right after preprocessing.
cc -E foo.c
will print all the preprocessed results on stdout. And
cc -E foo.c -o foo.preproc
will dump the preprocessed output into foo.preproc.
As best I can tell, the answer to my question is that there is no way to do it. The best I can do is do a full precompile, then search for the part of the file that starts after all the #include statements.
How do I at compile time undefine a compiler macro using gcc. I tried some compile args to gcc like -D but I can't get to see the "not defined" message.
Thanks
#include <iostream>
#define MYDEF
int main(){
#ifdef MYDEF
std::cout<<"defined\n";
#else
std::cout<<"not defined\n";
#endif
}
You can use the -U option with gcc, but it won't undefine a macro defined in your source code. As far as I know, there's no way to do that.
You should wrap the MYDEF definition in a preprocessor macro, the presence of which (defined on the command line) would then prevent MYDEF from being defined. A bit convoluted to be sure but you can then control the build in the way you want from the command line (or Makefile). Example:
#ifndef DONT_DEFINE_MYDEF
#define MYDEF
#endif
Then from the command line when you don't want MYDEF:
gcc -DDONT_DEFINE_MYDEF ...
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Preprocessor-Options.html#Preprocessor-Options
The -U options seemed like what you could have needed... but then again you can't override a definition contained in your source code without resorting to more preprocessor directives.
You can resort to filtering source code and give this back to gcc for compilation, like this pseudo code:
grep -v "define MYDEF" yourFile.c | gcc -o yourFile.o -xc -
Hope it helps.
The code use case is not right. As I see, you have hard coded #define in the file. If compiler initially assumes MYDEF undefined, it will define it once it start processing the file.
You should remove the line #define MYDEF. And I hope your test case will work, if you pass MYDEF to -D and -U.
Here is one possibility that doesn't completely cover your use case but which I found to be helpful in my case.
If your MYDEF were #defined in a separate header file #included from the .c file you could force the definition of the #include guard macro with the -D option (thus preventing the MYDEF #definition) then either actively #define (still with the -D option) MYDEF to something else or just leave it undefined.
It is clear that anything else defined in the header file would also be missing but this was for me a solution to forcedly undefine a macro without changing the third-party code.