What's the difference between these 2 pieces of Makefile.am code? - makefile

I am completely new to using autotools so it might be a dumb question but I'll try anyway. I have two pieces of Makefile.am. Except one is working fine and the other is not.
This works fine.
sbin_PROGRAMS = kernel
kernel_SOURCES = \
src/arch/$(host_cpu)/arch_sysdefs.h \
src/arch/$(host_cpu)/boot.asm \
src/arch/$(host_cpu)/cpu.asm \
src/arch/$(host_cpu)/isr.asm \
src/kmain.cpp
But this doesn't. .asm files are completely ignored by generated Makefile.
if HOST_CPU_X86
ASM_EXT = .asm
else
ASM_EXT = .S
endif
sbin_PROGRAMS = kernel
kernel_SOURCES = \
src/arch/$(host_cpu)/arch_sysdefs.h \
src/arch/$(host_cpu)/boot$(ASM_EXT) \
src/arch/$(host_cpu)/cpu$(ASM_EXT) \
src/arch/$(host_cpu)/isr$(ASM_EXT) \
src/kmain.cpp
What I am trying to do is that I want to use different suffixes for assembly files for some CPUs my project is going to support.
I've also added necessary rule to transform .asm to object files.
.asm.o:
yasm -f $(YASM_OUT_FMT) $< -o $#
EDIT: Temporarily overriding .cpp.o rule with echo $(kernel_SOURCES) reveals that $(ASM_EXT) in kernel_SOURCES is substituted correctly. For example src/arch/$(host_cpu)/boot$(ASM_EXT) becomes src/arch/x86_64/boot.asm for x86-64 CPU and src/arch/arm/boot.S for ARM, etc. Also, setting ASM_EXT variable from autoconf.ac doesn't make any difference.

Related

make: *** No rule to make target '.obj', needed by '.exe'. Stop

I want to recompile an old Fortran 77 code (having a lot of subroutines) via gfortran in MingW bash platform in windows 10. There is a makefile among the old code files which is attached here:
Version = 2.10
FOR = df
FFLAGS = /optimize:5
INSTALL = move
DELETE = del
COPY = copy
# these libraries must already exist somewhere
# where ld can find them
LIBS = \rfem\lib\GAF77.lib \rfem\lib\VFEM.lib DFPORT.lib
# where the final program is to be placed
BINDIR = \rfem\bin
# where the cat man pages are to go
CATDIR = \rfem\doc
# here are the files needed to construct Rslope2D
FILES = mrslope2d.f \
chknxe.f dismsh.f echosd.f fem2det.f fem2rf.f \
fem2sd.f feminit.f mesh.f openin.f opensd.f \
pltfld.f readsd.f rect.f setsd2.f sim2sd.f \
statsd.f szchk.f vecmsh.f
OBJS = mrslope2d.obj \
chknxe.obj dismsh.obj echosd.obj fem2det.obj fem2rf.obj \
fem2sd.obj feminit.obj mesh.obj openin.obj opensd.obj \
pltfld.obj readsd.obj rect.obj setsd2.obj sim2sd.obj \
statsd.obj szchk.obj vecmsh.obj
rslope2d.exe: $(OBJS)
link /out:rslope2d.exe $(OBJS) $(LIBS)
$(DELETE) $(BINDIR)\rslope2d.exe
$(INSTALL) rslope2d.exe $(BINDIR)
$(COPY) rslope2d.1 $(CATDIR)
clean:
$(DELETE) *.obj
After navigating to the directory where this makefile is located and typing make in the MingW window (to recompile the main code),
I encounter the following error:
No rule to make target 'mrslope2d.obj', needed by 'rslope2d.exe'. Stop.
I am a beginner in Fortran, so apologies if the question is simple.
Looking forward to your suggestions and guidance as I do not know how to resolve this.
Thanks

How do I read target dependencies from a file?

So, I've got that makefile project that has a huge list of object files that need to be compiled.
I already ran into problems on Win32 because the input string is too large. I figured out that instead of passing the files 1-by-1 to the linker, I could read the object files to be linked from a file by passing #filename to the linker.
In my makefile: Is there a method how the dependencies could be read out of a file? Something like that:
main.lib: #dependency_file_name
where dependency_file_name holds the list of needed .obj files needed to create the lib.
Please keep in mind, that putting the contents of the file into a variable also doesn't work since I've got that problem with a too long input string also when using the list of dependencies as a variable.
In addition: the method shall be portable (Linux, Win32)
Edit: currently, the structure of my makefiles is as follows:
# slurp in some global settings
include /path/to/global/settings
all: prepare_target mylib cleanup_target
prepare_target:
# do preparing work (setup temp files etc)
cleanup_target:
# do cleanup work (delete temp files etc)
mylib: \
file1.obj \
file2.obj \
... \
file215.obj
# this file holds the dependencies for each .obj file
include file_with_obj_file_dependencies
There are really 215 C files to be compiled into this lib. As I said: when feeding this list to the linker, I need to do it via a file because the string is too large for the command line.
I'm free to change whatever is needed in the makefile: it's generated from a VisualStudio vcxproj and I own the generation templates.
file_with_obj_dependencies looks as this:
file1.obj: \
file1.c \
file1.h \
file2.obj: \
file2.c \
file2.h \
... \
file215.obj \
file215.c \
file215.h \
On Windows I tend to use cygwin. It's the closest environment I've found to unix. This makes your Makefiles portable. I haven't come across any limiting command-line length limits. Here is an example with over ¾ of a million command-line arguments:
a := 1 2 3 4 5 6 7 8 9 a b c d e f
.PHONY: test
test:
#echo $(foreach A,$a,$(foreach B,$a,$(foreach C,$a,$(foreach D,$a,$(foreach E,$a,$A$B$C$D$E))))) | wc -wc
(the wc is so that you don't have to wait for the 5,000,000 or so characters to scroll by.)
So, for the limited win32 tools, use bash to write the intermediate command-line-parameters file, then pass that to link.exe (say) prefixed with an #.
Something like:
mylib.lib:
echo $^ >$#-tmp
link -o $# #$#-tmp
(Are you sure you need the intermediate file? 215 source files doesn't seem too onerous.)

Makefile - compiling back and forth

Following is the directory structure of my project:
expt-main
---------
Makefile_main
/ \
subdir-1 subdir-2
-------- --------
Makefile_1 Makefile_2
mod_codeA.f90 mod_code1.f90
mod_codeB.f90 mod_code2.f90
mod_codeC.f90 mod_code3.f90
Makefile_main:
export
SHELL = /bin/sh
F90 = mpxlf95
SRCDIRS = $(subdir-1) $(subdir-2)
all:
#for DIR in ${SRCDIRS} ;
do \
back=`pwd`; \
cd $$DIR ;\
$(MAKE) ; status=$$? ; \
if [ $$status != 0 ] ; then \
echo "Exit status fro make was $$status" ; exit $$status ; \
fi ; \
cd $$back ; \
done
-------------------------------------------------------------------------------
Makefile-1:
%.o: %.f90
$(F90) $(F90FLAGS) -I$(subdir-2) -c $<
mod_codeA.o: mod_codeC.o $(subdir-2)/mod_code2.o
-------------------------------------------------------------------------------
Makefile-2:
PROG = $(exec)
subdir-1_objs = $(subdir-1)/mod_codeA.o mod_codeB.o mod_codeC.o
all: $(PROG)
$(PROG): $(subdir-2_objs) $(subdir-1_objs) -o $# $(subdir-2_objs) $(subdir-1_objs)
---------------------------------------------------------------------------------
-
I've written the Makefile_main such that it compiles the codes (modules) in subdir-1 first and then the ones in subdir-2 and finally makes the executable. The issue: modules in subdir-1 uses modules from subdir-2 and in similar fashion, modules in subdir-2 uses those in subdir-1. My make is getting failed because the modules being used is in other directory. How to write a makefile which will take care of this issue that is, while compiling modules in subdir-1, whenever it encounters the need for an object file from subdir-2, it should switch to subdir-2 compile the necessary modules and return back to subdir-1 for further action?
If modules in different subdirectories need each other as you say, then this is not a good use of recursive Make.
Do away with Makefile-1 and Makefile-2, and let Makefile_main do all the work. (I can't tell you specifically how to change Makefile-main, since I don't do Fortran, I don't understand Makefile-2, and I don't see any dependency of modules in subdir-2 upon those in subdir-1).
If you want to stick to this directory layout and still keep three separated Makefiles, then you can use compiler flags to instruct the FORTRAN compiler to put module files into a common directory of your choice.
For instance using:
$ gfortran --version
GNU Fortran (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
you can use -I and -J flags to instruct the compiler on:
where to search for module files (.mod)
where to put generated module files
That said I think that the suggestion given by Beta to join the Makefiles makes a lot of sense. To know some of the reasons why you should do that you can read this paper.
Finally, as your project seems not to be very large at this stage, I also suggest to take into consideration CMake as a build system, as it possibly provides a more convenient way of specifying dependencies between targets (as well as many other things).

How to remove subdirectories from path

I don't really know anything about make or makefile scripts, so I'm hoping someone can tell me what I need to change. There is a common makefile script included in all of the others, and this specific piece of the code seems to be responsible for processing the list of source files (DLL_OBJS) and setting up the target to compile them:
ifdef DLL_TARGET
DLL_REAL_OBJS=$(addprefix $(OBJDIR)/, $(DLL_OBJS:=.$(OBJ))) $(DLL_VERSION_OBJS)
DLL_OUTPUT_FILE=$(OBJDIR)/$(LIBPREFIX)$(DLL_TARGET).$(DYNAMIC_LIB_SUFFIX)
$(DLL_OUTPUT_FILE): $(DLL_REAL_OBJS) $(DLL_NONPARSED_OBJS)
$(CC) $(CC_SHARED_LIB_FLAGS) $(LD_DYNAMIC) \
\
$(LD_DASH_O)$(DLL_OUTPUT_FILE) \
\
$(DLL_REAL_OBJS) $(DLL_NONPARSED_OBJS) \
$(DLL_EXTRA) $(PRELIB) $(LD_FLAGS) \
$(DLL_REAL_LIBS) $(DLL_NONPARSED_LIBS) $(LD_LIBS) $(DLL_OPTION)
ifdef EMBED_MANIFEST
ifndef SUPPRESS_MANIFEST_DLL
$(PREMANIFEST) $(MT) \
\
$(MANIFESTFLAGS) /outputresource:"$(DLL_OUTPUT_FILE);#2" /manifest $(DLL_OUTPUT_FILE).manifest
endif
endif
endif # DLL_TARGET
The problem is if I do this:
DLL_OBJS=subdir/main
Then it will try to write the main.obj file to WINNT5.0_DBG.OBJ/subdir/main.obj, whereas I want it to go to WINNT5.0_DBG.OBJ/main.obj. How can I modify the code above to exclude the subdirectory portion of the source file from the object file output path? I suspect the changes will need to happen to the DLL_REAL_OBJS variable.
Note that DLL_OBJS could be a list of items, like:
DLL_OBJS=\
subdir/main\
subdir/foo\
bar\
another_source
Let me know if any important information is missing and I will do my best to update my question with it.
If you're using GNUMake, just modify the second line:
DLL_REAL_OBJS=$(addprefix $(OBJDIR)/, $(notdir $(DLL_OBJS:=.$(OBJ)))) $(DLL_VERSION_OBJS)

How to substitute a pattern in Makefile.am

I have an application with several subdirectories, which I want to compile non-recursive. For this I have seperated all sorucefiles from the subdirectories into several variables, which I then use in the final collection of sources. Something like this:
GUI_SOURCEFILES = Gui/MainWindow.cc \
Gui/StatusBar.cc
...
foo_SOURCES = $(GUI_SOURCEFILES) \
$(DATABASE_SOURCEFILES) \
main.cc
Now however this forces me to write Gui/ for all gui sourcefiles and Db\ in front of all database files. I think it should be possible to create this prefix automaticall, but I cannot find a way to do this correctly. I tried the usual make way:
GUI_SOURCEFILES = MainWindow.cc \
StatusBar.cc
...
foo_SOURCES = $(GUI_SOURCEFILES) \
$(patsubst %,Gui/%,$(DATABASE_SOURCEFILES)) \
main.cc
But autotools will not compile this Makefile.am at all.
Is there a way to get autotools to do this for me?
There is no way here, all filenames must be available at automake time, and that precludes certain make-time like functions (non-portable at that).

Resources