Makefile to compile Fortran source files in different directories - makefile

Here is my problem: I have been using Java for many years and enjoy having many directories separating different areas of the code. For my current project I am writing Fortran code, which should compile under Windows and Unix/Linux. For Windows, I am using Eclipse/Photran with MinGW/gfortran tools to set up Makefiles.
Here is the desired project structure (deep nesting tree-like Java-like would be even nicer)
dir1/src/*.f95
dir1/make/Makefile_lib1.any
dir1/make/Makefile_lib1.win
dir1/make/Makefile_lib1.unix
dir2/src/*.f
dir2/make/Makefile_lib2.any
dir2/make/Makefile_lib2.win
dir2/make/Makefile_lib2.unix
...
dir_main/src/*.f or *.f95
dir_main/make/Makefile_main.any
dir_main/make/Makefile_main.win
dir_main/make/Makefile_main.unix
I would like to call make Makefile_main.unix, which would set up any Unix-specific variables and then include Makefile_main.any, Makefile_lib1.any, ...
(similar for making on Windows)
I got to the stage where I can see all source files in a given directory, e.g.
SRCS := $(wildcard $(SRC_DIR)/*.$(SRC_EXT))
Now I am struggling with how to make all dependencies as in Fortran 95 each source generates *.o and *.mod.
Is there a way to switch between directories when compiling so that all targets/dependencies do not have dir-path in their names? Note that I am calling make from some other service directory where the Eclipse project lives. Any suggestions how to proceed?
I really do not want to do the usual Fortran style of having just one directory with
all the mess together with the code.

There are two major strategies you can take.
You can place a makefile in each subdirectory and have it support targets like all, clean etc, then use recursive make invocations from the top-level makefile to make the same target (e.g. all) in every subdirectory.
Alternatively, you can handle it all in one make invocation, without recursing, but then you'll have to work with relative paths containing subdirectory names. Personally I don't see a problem with it, and I've maintained a system of makefiles based on this approach.
Here is what you can do in your case, assuming that SRC is set correctly to the list of relative paths to every source you need to compile.
# This replaces the SRC_EXT suffix with .o in each filename
OBJ = $(SRC:%.$(SRC_EXT)=%.o)
$(BINARY_NAME): $(OBJ)
...link command...
%.o: %.$(SRC_EXT)
...compile command...

Related

Include a third makefile with a path relative to second, when second isn't in directory of first

I have a Makefile with only project-level definitions: which source files to use, what binary or library to make, etc..
It includes ../../Make.Arch for architecture-specific definitions (such as compiler command).
In turn, Make.Arch is meant to include ../etc/Makefile.Standard for all the boilerplate of actually allowing the make system to work .
But include requires a path relative to where the makefile is actually being run (or maybe where the first Makefile is), not relative to the second... What to do?
Make interprets relative paths from the working directory, the directory in which Make is being run. You haven't specified how you're running Make, so I'll assume your running it in the directory with Makefile.
If you are allowed to modify the makefiles, you can change the paths.
You could change Make.Arch from this:
include ../etc/Makefile.Standard
to this:
include ../../../etc/Makefile.Standard
but that would require that any makefile that uses Make.Arch be two directories down from it. That's clearly not a good idea. But we can use a variable:
include $(ARCH_DIR)/../etc/Makefile.Standard
which is provided by Makefile (or any other makefile that uses Make.Arch):
ARCH_DIR := ../..
include $(ARCH_DIR)/Make.Arch
If you are not allowed to modify the makefiles, then you must cheat. One way is to create a symbolic link to Makefile.Standard.
mkdir ../etc
ln -s ../../../etc/Makefile.Standard ../etc
Now Makefile will work. (It ought to be possible to make a link to etc/, but for some reason I can't get that to work right now.)

Including an automatically generated makefile as a trick to enforce execution of a recipe

I'm slowly losing my mind here. First, let me describe what it is I'm trying to do. We have a compiler that spews out weirdly formatted dependency files. To get these makefiles into a format GNU Make can understand, they need to be processed by a Perl script first. Technically, the Perl script doesn't convert the input dependency files it gets passed; instead it creates a new, properly formatted dependency file for each input dependency file.
Now, in order for GNU Make to know which translation units need recompiling and which don't, it obviously must have seen those dependency files before trying to make the translation unit targets, so we have the following line in our master makefile:
include $(PROCESSED_EXISTING_DEPENDENCY_FILES)
where $(PROCESSED_EXISTING_DEPENDENCY_FILES) is a list of all converted dependency files. My idea was to (ab-)use an automatically generated makefile whose recipe not only builds that makefile but also triggers the creation of all dependency files mentioned in the $(PROCESSED_EXISTING_DEPENDENCY_FILES) list and include that makefile just before including the converted dependency files. To ensure that the conversion takes place, the parent process of our Make process will delete the automatically created makefile first (we have a Perl wrapper process controlling GNU Make). The relevant part in the master makefile would look like this:
# Phony target that creates processed dependency files.
CONVERTED_EXISTING_DEPENDENCY_FILES :
<recipe here>
$(PRE_CONVERTED_DEPENDENCY_FILE_INCLUSION_HOOK) : CONVERTED_EXISTING_DEPENDENCY_FILES
$(info $(TARGET_BUILD_MESSAGE_PREFIX) Building $(notdir $#) ...)
$(file >$#,# Automatically generated makefile that gets included before including the existing, converted dependency files.)
$(file >>$#,$(DOLLAR)(info Including pre-converted-dependency-files-inclusion hook file ...))
$(file >>$#,)
include $(PRE_CONVERTED_DEPENDENCY_FILE_INCLUSION_HOOK)
include $(PROCESSED_EXISTING_DEPENDENCY_FILES)
We're already using the same basic principle in several other cases, and so far this has worked perfectly fine, but for some reason when I try this, GNU Make gets lost in an infinite loop where it will continuously re-revaluate the master makefile, include all other makefiles and then go back to re-revaluating the master makefile again.
The $(PRE_CONVERTED_DEPENDENCY_FILE_INCLUSION_HOOK) does get created, and if there are any dependency files to be converted, they are processed, too, but I'm still at a loss as to what causes this infinite loop in Make. We are using GNU Make 4.2.1 for Windows on a Windows 10 (64 bit) system.
I recommend you rework your model completely to avoid any recipes that know how to build included files, and instead follow the model for auto-dependency generation described in this post (based on how automake handles dependency generation).
Then add in the postprocessing step directly into the same recipe that generates the dependency files, rather than having a separate rule that does it. I don't think it's necessary to have two separate rules because you really don't want the intermediate step here: you just want to generate the make prerequisites definitions... similar to how normally we wouldn't have separate rules for preprocessing, compiling, assembling object files: one rule does that even though there are multiple steps involved.

Out of tree kernel modules: Multiple module, single Makefile, same source file, different build options

I am building a set of Linux kernel modules using shared source code. From what I understand, the Makefile has to be named "Makefile" so I have to use the same Makefile to build two different modules. How can I build two different modules, within the same Makefile, with the same source code, but with two different build options?
For example, my modules are called module1 and module2. So I have the following line to define them:
obj-m := module1.o module2.o
Among other files, both module1 and module2 need to use the same source file code.c, but built with different build options. So say for example, the Makefile contains the following lines:
module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o
I want module1_code.o and module2_code.o to be built from code.c, but with different options. Specifically, I want one module1_code.o with a macro defined -DPREPROCEFFOR_FLAG=1, and module2_code.o built without the macro.
From what I understand, the system of Makefiles used in Linux implicitly infers that for an object file called "code.o", the source file is called "code.c", so how would I achieve this? Is is possible? Is there a better way to do this?
You have a problem here, because you obviously have code.c being compiled differently when -DPREPROCEFFOR_FLAG=1 is defined, but once it's compiled into code.o, make won't care about preprocessor flags or whatever because code.o will be already up to date.
You need a way to build code.c to different object files with different C flags. There's probably a clean way to do this (had no chance with O= for out of tree modules), but here's my innelegant yet effective solution for the moment:
my_modules:
cp code.c code_noflags.c
cp code.c code_withflags.c
make -C $$KDIR M=$$PWD modules
rm code_noflags.c code_withflags.c
# module objects
obj-m := module1.o module2.o
# module1 specifics
module1-y := code_withflags.o
CFLAGS_code_withflags.o := -DPREPROCEFFOR_FLAG=1
# module2 specifics
module2-y := code_noflags.o
Just call:
$ make KDIR=/path/to/kernel
You can verify the preprocessor flag is passed to the source file for the right object with:
$ make KDIR=/path/to/kernel V=1 | grep PREPRO
You could also have two separate directories for each module, if this is possible, and have a symbolic link code.c in each one pointing to the common real code.c. However, this is still hackish and doesn't feel right.
One simple solution is, continuing from your Makefile
obj-m := module1.o module2.o
module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o
to add two more source files, module1_code.c and module2_code.c.
Then module1_code.c just looks like:
#define PREPROCEFFOR_FLAG 1
#include "code.c"
and module2_code.c is:
#include "code.c"
Or if you like, change the names in the Makefile and source files so that the second include without a define isn't necessary. Also you could make the two source files nothing but an include and use the CFLAGS_module1_code.o variable to add the -D... option to the compiler if you prefer.
This is similar to what happens in the upstream kernel with arch/x86/boot/video-vesa.c and arch/x86/realmode/rm/video-vesa.c etc., where the realmode file just contains:
#include "../../boot/video-vesa.c"
and the video-vesa.c code ends up getting compiled twice with different compiler flags.
This seems preferable to copying the source files, since you end up with a mess there if you want to use the O=... option to the kernel build to keep a clean source tree and build in a separate object tree.

moving from make to cmake: how to use build target with wildcards

I'm trying to convert an makefile-build to cmake (to avoid the current state of being forced to take care for the windows-build env based on make/msdev and the linux based on make/gcc).
In this project, I've found a directory full of sourcecode files that get, based on a naming convention, compiled to libraries. (e.g. c1223.c => c1223.dll (or .sl) )
The current makefile consists of some directives using wildcards, e.g.:
LIB_NO = $(basename $(subst s,,$#))
OBJ = $(OBJ_PATH)/s$(LIB_NO).o $(OBJ_PATH)/c$(LIB_NO).o\
$(OBJ_PATH)/b$(LIB_NO).o
$(OBJ_PATH)/%.o : %.c
-$(CC) $(CFLAGS) -I$(PWD) -c $< -o $#
-(chmod a+w $#;true)
I've searched for a while but can't find anything that seems to work. Is it even possible with cmake to let it generate a wildcard based build?
Any comments, hints and suggestions are very welcome :)
cheers
Markus
You can use fairly primitive globbing (there's no regular expression syntax that I can see).
file(GLOB TESTSRCS "test/src/*.cpp")
# Compile the test sources.
add_executable(Tests ${TESTSRCS})
target_link_libraries(Tests ${LIB} gtest gtest_main)
The actual makefiles do not seem to contain wildcard searches inside them. If you add new files you will need to re-run cmake.
What I don't know is how you would manage to wrap up the library creation in a single macro if you have many different library files to generate.
You might be able to do something like this if there's only one c file per library:
file(GLOB libfiles "path/to/libs/c*.c")
foreach(libfile ${libfiles})
GET_FILENAME_COMPONENT(libname ${libfile} NAME) # remove the '.c' part (untested, hopefully this will work)
add_library(${libname} ${libfile})
endforeach(libfile)
If anybody else has a better solution, I would also like to learn it.
CMake does not generate makefiles that have wildcard-based rules in them. It generates specific rules for the files that it knows about.
In your example, you are explicitly listing the .o files that comprise your library. In CMake, you would instead explicitly list the source files that contribute to your library, and then let CMake take care of the rest.
Do you need makefiles that have wildcard-based rules in them for some reason?
Couldn't you simply construct a list of the source files, and then, for each element in the list, do an "add_library" call with the source file and a library name constructed from the source file name?

Using make to add m4 preprocessing to an arbitrary language

We have an ActionScript (Flex) project that we build using GNU make. We would like to add an M4 preprocessing step to the build process (e.g., so that we can create an ASSERT() macro that includes file and line numbers).
We are having remarkable difficulty.
Our current strategy is:
Create a directory "src/build" (assuming source code is in src/ and subdirectories).
Within src/build, create a Makefile.
Run make inside src/build.
The desired behavior is, make would then use the rules we write to send the *.as files src/ and its subdirs, creating new *.as files under build. For example:
src/bar.as -> m4 -> src/build/bar.as
src/a/foo.as -> m4 -> src/build/a/foo.as
The obvious make rule would be:
%.as : ../%.as
echo "m4 --args < $< > $#"
This works for bar.as but not a/foo.as, apparently because make is being "smart" about splitting and re-packing directories. make -d reveals:
Trying implicit prerequisite `a/../foo.as'.
Looking for a rule with intermediate file `a/../foo.as'.
but we want the prerequisite to be "../a/foo.as". This (what we don't want) is apparently documented behavior (http://www.gnu.org/software/make/manual/make.html#Pattern-Match).
Any suggestions? Is it possible to write a pattern rule that does what we want?
We've tried VPATH also and it does not work because the generated .as files are erroneously satisfying the dependency (because . is searched before the contents of VPATH).
Any help would be greatly appreciated.
One option is to use a different extension for files that haven't been preprocessed. Then you can have them in the same directory without conflict.
As Anon also said, your source code is no longer Flex - it is 'to be preprocessed Flex'. So, use an extension such as '.eas' (for Extended ActionScript) for the source code, and create a 'compiler' script that converts '.eas' into '.as' files, which can then be processed as before.
You may prefer to have the Extended ActionScript compiler do the whole compilation job - taking the '.eas' direct to the compiled form.
The main thing to be wary of is ensuring that '.eas' files are considered before the derived '.as' files. Otherwise, your changes in the '.eas' files will not be picked up, leading to hair-tearing and other undesirable behaviours (head banging, as in 'banging head against wall', for example) as you try to debug code that hasn't changed even though the source has.

Resources