Re: builddir vs. srcdir
Hello, On Sat, Mar 12, 2005 at 06:56:20PM +0200, Paul Pogonyshev wrote: Everything seems to work just fine and as expected, your code, which is in whole cited below, doesn't actually know about the dependency foo.c foo.h: foo.list So if you change the .list file, the other files won't be rebuilt. This might be a dangerous bug. It doesn't know about the dependency, but the files will be rebuilt as a ``side-effect'' of the timestamp rule. I actually just tried this out. In general, stamps are always dangerous, so it's good to avoid them if possible. I'd try something like this: [file `aux/list.make'] SUFFIXES = .list .list.c: Makefile $(PARSE_LIST_COMMAND) $(PARSE_LIST_BUILD_RULE) .list.h: Makefile $(PARSE_LIST_COMMAND) $(PARSE_LIST_BUILD_RULE) PARSE_LIST_BUILD_RULE = \ $(PARSE_LIST_COMMAND) $(PARSE_LIST_FLAGS) \ `test -f '$' || echo '$(srcdir)/'`$ $*.h $*.c \ touch $*.h [usage] LIST_FILES = foo.list bar.list # Prevent problems with parallel make: foo.h: foo.c bar.h: bar.c PARSE_LIST_COMMAND = ... PARSE_LIST_FLAGS = ... noinst_LIBRARIES = libfoo.a libfoo_a_SOURCES = ... $(LIST_FILES) # This hint is needed only for included files; *.c files # are handled by normal target dependencies: BUILT_SOURCES = $(LIST_FILES:.list=.h) MOSTLYCLEANFILES = $(LIST_FILES:.list=.h) $(LIST_FILES:.list=.c) include $(top_srcdir)/aux/list.make Sorry, but I'll stick with my setup. My parser depends on my lowest- level library (`libutils') and almost the whole build-tree depends on the generated files. So, when I touched my `libutils' in any way, I would get a full-blown rebuild of the project. That's why I used `cmp' and only replaced the `.[ch]' files with the newly generated if they differed. And so I need timestamps to avoid unecessary commands run all the time (I want to see ``nothing to be done...'' when it is the case.) Let me add some comments: 1) The maintainer of Automake said that $(LIST_FILES:.list=.h) is safe, and I trust him. Oh, great, that is what I was looking for! 2) nodist_libfoo_a_SOURCES was redundant, especially the .c files. Automake knows how to transform .list to .o, and listing the intermediate files again could cause problems. With your setup, yes. Not with mine, unfortunately. 3) I try to have the BUILT_SOURCES hist as small as possible, so when the .c file is a prerequisite of the corresponding .o, there is no need to pre-build it using BUILT_SOURCES. 4) With parallel make, the PARSE_LIST_COMMAND cnnot be run twice in parallel, because of the foo.c: foo.h dependency. So we are safe. I need to add this rule in my setup too. Anyway, even if I don't accept your advice this time, thank you for the help. :) Paul
Re: builddir vs. srcdir
Stepan Kasal wrote: About the side topic of suffixes: [...] I finally decided that suffixes are good and ``are worth it'', mostly because I use generated files in 4 different directories (with two files in one of them), so rewriting the rule 5 times is kinda nasty. Based on your suggestions, study of GTK+ `Makefile.am' and own thoughts, I came up with this: [file `aux/list.make'] SUFFIXES = .list $(LIST_STAMP_FILES) : Makefile $(PARSE_LIST_COMMAND) # `PARSE_LIST_COMMAND' and `PARSE_LIST_FLAGS' should be set by the # includer. # PARSE_LIST = $(PARSE_LIST_COMMAND) $(PARSE_LIST_FLAGS) # We use `cmp' here to avoid unneeded recompilations of files that # depend on generated ones (only really useful for `.h' files.) # PARSE_LIST_BUILD_RULE = \ if $(PARSE_LIST) `test -f '$' || echo '$(srcdir)/'`$ \ $*.h.new $*.c.new; then\ if cmp -s $*.c.new $*.c; \ then rm -f $*.c.new; else mv -f $*.c.new $*.c; \ fi; \ if cmp -s $*.h.new $*.h; \ then rm -f $*.h.new; else mv -f $*.h.new $*.h; \ fi; \ echo timestamp $@; \ else\ (rm -f $*.c $*.c.new $*.h $*.h.new ; exit 1) \ fi .list.stamp: $(PARSE_LIST_BUILD_RULE) # Since $(LIST_GENERATED_FILES) defined by the includer don't (at # least shouldn't) have any dependencies, if this rule is being # executed, it probably means that one of the files was removed. # Then all we can do is to force rebuilding of corresponding stamp # file, which builds the required sources ``by side-effect.'' # $(LIST_GENERATED_FILES): rm -f $*.stamp; $(MAKE) $(AM_MAKEFLAGS) $*.stamp [usage] noinst_LIBRARIES = libfoo.a LIST_FILES = foo.list bar.list LIST_STAMP_FILES = foo.stamp bar.stamp LIST_GENERATED_FILES = foo.c bar.c foo.h bar.h PARSE_LIST_COMMAND = ... PARSE_LIST_FLAGS = ... include $(top_srcdir)/aux/list.make libfoo_a_SOURCES = ... $(LIST_FILES) nodist_libfoo_a_SOURCES = $(LIST_GENERATED_FILES) BUILT_SOURCES = $(LIST_STAMP_FILES) MOSTLYCLEANFILES = $(LIST_STAMP_FILES) $(LIST_GENERATED_FILES) Everything seems to work just fine and as expected, however I suspect that the ``rm -f $*.stamp; $(MAKE) $(AM_MAKEFLAGS) $*.stamp'' command will cause the problem with parallel make you mentioned. Is it so? Also, is there a way to automatically set `LIST_STAMP_FILES' and `LIST_GENERATED_FILES' from `LIST_FILES'? (I'm aware of GNU make's text manipulation functions, but they are GNU make specific...) Paul
Re: builddir vs. srcdir
Alexandre Duret-Lutz wrote: Paul == Paul Pogonyshev [EMAIL PROTECTED] writes: Paul Stepan Kasal wrote: Hello, On Tue, Mar 08, 2005 at 11:56:56PM +0200, Paul Pogonyshev wrote: because the generated sources are placed into the build directory, while `make' looks for them in the source directory. generally, make should look for them in both places. Paul Yes, and it does look in both places, but the dependencies make `foo.o' Paul depend on `$(srcdir)/foo.c', This could happen if this location was the right one in the past, and building foo.c in the build directory is a recent change. In that case the dependency file still have the old info. The way to erase dependency info is distclean: make -k distclean; ./configure; make Yup, you are right, thanks. Should have guessed myself... :[ Paul
Re: builddir vs. srcdir
Hi, On Wed, Mar 09, 2005 at 11:21:35PM +0200, Paul Pogonyshev wrote: And I'd like to suggest that you use SUFFIXES to handle the .list source. Please look at the following example: Well, my generator is even more non-standard, since I need to pass an additional command-line parameter sometimes. So, `SUFFIXES' are not an option, although I agree it would have been nicer to use them. well, in the example I cited, I had several .list sources, but only one in each directory. Thus I was able to have different rules in different directories. This is not usable for you, but you can make the .list.h rule general: $(PARSE) `case $* in *this.list) echo this options;; \ *that.list) echo that opt;; *) echo default opt;;esac` $ ($* is substituted by make) Well, I also need something like `echo $* | sed 's/\.h$/.c/'` (not tested), so using suffix rules seems like too much trouble. Besides, in one directory I have two `.list' files, one of which is processed by my parser, while the other---by `glib-genmarshal' (I chose my suffix before I even started with GTK+ GUI.) Or you can place the options at the first line of the .list source and grep for them. Then I could just make the parser read them as well. That might be a good idea, actually, since these options are more like modes that are absolutely necessary to be set correctly to parse anything. And if your generator creates *.c file after *.h file, you should define the dependency: foo.c: foo.h and vice versa if the generator creates .h after .c. That will make make happy and you won't observe repeated re-generation of the .c file. I'm not sure which one comes first. They are generated on-the-fly in parallel (i.e. fprintf's to both files are mixed.) I assume in this case I can just do foo.c : foo.h foo.c foo.h : ... if $(BUILD_THEM_FILES) foo.list foo.h foo.c; then \ touch foo.c; \ else\ (rm -f foo.c foo.h; exit 1) \ fi right? BTW, I have just built everything in a separate directory for the first time :) I need to sort out that parallel building stuff, but otherwise all works perfectly. Thanks for your help. Paul
builddir vs. srcdir
Hi. I'm currently massaging my `Makefile.am's to allow building in a separate directory. However, I have a problem which I cannot find how to solve. I have a few source (`.c' and `.h') files which are generated at build time from another source using a custom utility. When the build directory is the same as the source directory, everything is fine. However, with separate build directory things go hairy, because the generated sources are placed into the build directory, while `make' looks for them in the source directory. Automake pseudo-code looks like this: noinst_LIBRARIES = libfoo.a BUILT_SOURCES = \ foo.c \ \ foo.h PARSE_LIST = ./parse-list$(EXEEXT) foo.c foo.h : $(srcdir)/foo.list $(PARSE_LIST) $(PARSE_LIST) $(srcdir)/foo.list foo.h foo.c\ || (rm -f foo.c foo.h ; exit 1) libfoo_a_SOURCES = ... nodist_libfoo_a_SOURCES = $(BUILT_SOURCES) plus the lines to build the parser utility and other non-important stuff. Paul
Re: builddir vs. srcdir
Stepan Kasal wrote: Hello, On Tue, Mar 08, 2005 at 11:56:56PM +0200, Paul Pogonyshev wrote: because the generated sources are placed into the build directory, while `make' looks for them in the source directory. generally, make should look for them in both places. Yes, and it does look in both places, but the dependencies make `foo.o' depend on `$(srcdir)/foo.c', so `make' tells it has no rule to build the latter. How do I make dependencies tell `foo.o' depends on `$(builddir)/foo.c' instead? Let me point out several problems: BUILT_SOURCES = \ foo.c \ foo.h You probably need only the foo.h file here. Right. foo.c foo.h : $(srcdir)/foo.list $(PARSE_LIST) $(PARSE_LIST) $(srcdir)/foo.list foo.h foo.c\ || (rm -f foo.c foo.h ; exit 1) This rule can break with parallel make. For details about these two issues, see http://sources.redhat.com/automake/automake.html#Built-sources-example You can solve the second issue by adding the dependency: foo.c: foo.h Yet it might be more readable if you change your generator so that it would generate .c and .h in separate runs. I'd hate to hack the generator for such a goal. I'll better stick with the `foo.c: foo.h' solution. Maybe generating two files at once is non- standard, but it seems natural, since they are so closely related and are built from one source file, and that's the way it works already. And I'd like to suggest that you use SUFFIXES to handle the .list source. Please look at the following example: Well, my generator is even more non-standard, since I need to pass an additional command-line parameter sometimes. So, `SUFFIXES' are not an option, although I agree it would have been nicer to use them. Paul