[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
make features request
From: |
Maxim Yegorushkin |
Subject: |
make features request |
Date: |
Sat, 27 Mar 2010 12:13:56 +0000 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100301 Fedora/3.0.3-1.fc12 Thunderbird/3.0.3 |
Currently, pattern rules allow only for one % character. This works well
when the target file name is a simple transformation of its dependency,
like:
%.o : %.cc
There are times though, when more advanced filename transformation is
required. For example, in Qt world they generate ui .h files from
corresponding .ui files using the following naming conventions (don't
ask me why):
ui_%.h : %.ui
This works for makefile systems which require target files to be
generated in the same source folder (relative filename method), like
recursive make.
For non-recursive makefile systems which always use a complete
dependency tree using explicit path method, when targets and
dependencies are in different folders, something like the following is
required:
${gen_src_dir}/%/ui_%.h : ${src_dir}/%/%.ui
An expansion, for example:
/home/max/works/builds/Linux-x86_64-64.g++-release/gen_src/gui/monitor/ui_monitor.h
: /home/max/works/src/gui/monitor/monitor.ui
What would solve this issue nicely is regex pattern rules, something
like the following:
.REGEX-RULES-BEGIN
${gen_src_dir}/(.+)/ui_(\w+).h : ${src_dir}/\1/\2.ui
.REGEX-RULES-END
***
Anther issue with building into a separate build directory is that
target directories need to be created on demand. This leads to having to
manually establish directory dependencies:
${obj_dir}/project/main.o : ${src_dir}/project/main.cc
${obj_dir}/project/main.o : | ${obj_dir}/project
${obj_dir}/project : mkdir -p $@
There are two issues with these rules.
First, is that for every object file has to have an order-only
dependency on its directory, so that make creates the directory before
any targets are put there.
Second, is that `mkdir -p` does not work for parallel builds. This
occurs when make tries to invoke, for example, `mkdir -p /a/b` and
`mkdir -p /a/c` in parallel, with directory /a being non-existent. What
`mkdir -p` does is that first it stats /a directory and if it does not
exist it tries to create that. There is a race condition between
stat'ing the directory and creating it, during which another parallel
invocation of mkdir creates this same directory, which causes creating
/a directory in the former mkdir to return EEXIST and fail. It must be
mkdir bug (both gnu and Solaris), but I not sure if it can be fixed in
mkdir, since if creating a directory returns EEXIST, that directory
needs to be stat'ed again, to make sure it is a directory and not a
file, leading to a race condition again. (no POSIX interface to create a
directory and if that name already exists in the filesystem return its
type).
So, it would be very useful if make could create directories for targets
on demand. Something like the following:
.CREATE-TARGET-DIRECTORIES-BEGIN
${obj_dir}/project/main.o : ${src_dir}/project/main.cc
.CREATE-TARGET-DIRECTORIES-END
Or, along with the first feature request:
.REGEX-RULES-BEGIN
.CREATE-TARGET-DIRECTORIES-BEGIN
${obj_dir}/(.+)/(\w+).o : ${src_dir}/\1/\2.cc
.CREATE-TARGET-DIRECTORIES-END
.REGEX-RULES-END
To work around these two issues I currently have to do macro expansion
in make:
$(eval $(call O_TARGET,project,main.o other.o))
Which expands to something like that:
${obj_dir}/project/main.o : ${src_dir}/project/main.cc
${obj_dir}/project/other.o : ${src_dir}/project/other.cc
${obj_dir}/project/main.o ${obj_dir}/project/other.o : |
${obj_dir}/project
${obj_dir}/project : | ${obj_dir}
${obj_dir} ${obj_dir}/project : mkdir $@
With the features I mentioned above I would not need make macro
expansion at all.
Any thoughts?
Max
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- make features request,
Maxim Yegorushkin <=