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).
Related
i have a list of input*.in files, and for each of them i want to generate an output*.out file using make.
target1.out : input1.in
{external program} < input1.in > target1.out
I have 0 experience with gnu make, so would much appreciate help
How should i do it best using makefile?
Are you looking for this?
target%.out: input%.in
{external program} < $< >$#
Now make knows how to generate targetXX.out from inputXX.in. You still have to add an actual target, either on the command line (like make targetShirley.out assuming you have inputShirley.in) or in a separate recipe. A common arrangement is to have
sources := $(wildcard input*.in)
targets := $(patsubst input%.in,target%.out,$(sources))
.PHONY: all
all: $(targets)
(typically at the top of the Makefile) and then make all will produce all the files it can.
A common antipattern is to write a single recipe with a loop, like
everything:
for file in input*.in; do \
t=$${file%.in}; \
t=target$${t#input}.out; \
{external program} >"$$t"; \
done
(notice also how the shell's dollar signs have to be doubled to prevent make from attempting to interpret them). Besides being clumsy, this disables the single crucial reason to use make in the first place, namely to avoid creating files which are already up to date.
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.
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.)
I have a following directory structure in my project:
bin/
dist/
include/
├── module_a/
└── module_b/
Makefile
src/
├── module_a/
└── module_b/
Folder include/ contains *.hpp's while *.cpp's are in src/. I would like to compile all sources to bin/ and then link them up together to dist/. Seems a pretty reasonable wish for me.
I would like to know the best practices for a Makefile for this case. All I can find is %.o: %.cpp target, but that doesn't really work, because of different source and binary folder.
I was trying to use something like this:
D_SRC = src
D_BIN=bin
F_CPP := $(shell find $(D_SRC) -iname '*.cpp' -type f)
F_OBJ := $(shell echo $(F_CPP) | sed s:\ :\\n:g | sed s:$(D_SRC):$(D_BIN): | sed 's:^\(.*\)\.cpp$$:\1\.o:')
$(F_OBJ): $(F_SRC)
$(foreach file, $(F_SRC), \
$(GXX) $(CXXFLAGS) -c $(file)\
)
This target doesn't work, because $(F_OBJ) paths start with bin/, while foreach compiles sources to current working dir. I could make it compile to bin/, but that would happen only with a few more sed expressions and it's ugly enough as it is.
It's probably so difficult for me, because I don't know make all that well, but I cannot be the only one with this project setup. In my opinion, it must be a pretty common one. I know I can write a Makefile for each module separately, but is that really the best choice here?
EDIT: I was now wondering what would I achieve with several Makefiles. If one was at root and another one in src/module_a, how would the latter know about the bin/? If you'd execute it with make -f src/module_a/Makefile, it would be the same as executing it from root directory, 'cause it's working directory would be root. Another way, I guess, would be to change directory before executing it, like so: make -C include/module_a, but in that case, how would it find bin/? I wouldn't want to have something like D_BIN = ../../bin in a Makefile.
What I normally do is have a Makefile in the src directory (which can be invoked from the top level Makefile if you like) and then use rules like this:
D_BIN = ../bin
$(D_BIN)/%.o: %.cpp
You could also experiment with just a makefile in the top level dir, and use rules that look like this:
D_BIN = bin
D_SRC = src
$(D_BIN)/%.o: $(D_SRC)/%.cpp
but I have not used such rules, so I don't know the pros/cons vs the way I normally do it. The way I normally do it works fine, I even have rules that build depends like so:
$(D_BIN)/%.d: %.cpp
and the link rule would be like:
../dist/outexe: $(F_OBJ)
Using a foreach is usually frowned upon because it does not make use of all the features built into normal makefile rules (i.e. there is no depends check on a per file basis, either you build everything or nothing), and as such foreach should only be used as a last resort, but in this case you will be able to get it to work without the foreach.
In addition to this there are much easier ways to build your file lists, you don't need to use the shell or sed.
F_CPP = $(wildcard *.cpp)
F_OBJ = $(F_CPP:.cpp=.o)
Update: This is how I normally issue recursive makes:
SUBDIRS = src
.PHONY: $(SUBDIRS)
all: $(SUBDIRS)
$(SUBDIRS):
#echo "Building $#..."
$(MAKE) -C $# $(MFLAGS)
Then indeed in your submake, you would need to use ../bin for example.
However with a project as simple as yours, you might be better off just having one makefile at the root level and using rules like this:
D_BIN = bin
D_SRC = src
$(D_BIN)/%.o: $(D_SRC)/%.cpp
recursive makefiles are ok (ok but not great) if you have a really complex directory structure, where you will be adding/removing/modifying new dir trees as time goes on. But for a simple project where you just want to have separate directories for code and objs, it is probably overkill.
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)