Skip to contentSkip to conversation

tools top level makefile cleanup

PATCH In review Jerone Young 5 participants 14 messages Mar 22, 2005 – Mar 24, 2005 Kbuild

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 tools top level makefile cleanup

I cleaned up the top level makefile in the tools directory. No major changes. Except I have it so that ioemmu is compiled only with x86_32.

Makefile renamed from Makefile.orig +30 -34
@@ -1,37 +1,33 @@
+XEN_ROOT = ../
+include $(XEN_ROOT)/tools/Rules.mk
 
-all:	
-	$(MAKE) -C check
-	$(MAKE) -C libxutil
-	$(MAKE) -C libxc
-	$(MAKE) -C misc
-	$(MAKE) -C examples
-	$(MAKE) -C xentrace
-	$(MAKE) -C python
-	$(MAKE) -C xfrd
-	$(MAKE) -C xcs
-	$(MAKE) -C ioemu
+SUBDIRS :=
+SUBDIRS += check
+SUBDIRS += libxutil
+SUBDIRS += libxc
+SUBDIRS += misc
+SUBDIRS += examples
+SUBDIRS += xentrace
+SUBDIRS += python
+SUBDIRS += xfrd
+SUBDIRS += xcs
+ifeq ($(XEN_TARGET_ARCH),x86_32)
+SUBDIRS += ioemu
+endif
 
-install: 
-	$(MAKE) -C check
-	$(MAKE) -C libxutil install
-	$(MAKE) -C libxc install
-	$(MAKE) -C misc install
-	$(MAKE) -C examples install
-	$(MAKE) -C xentrace install
-	$(MAKE) -C python install
-	$(MAKE) -C xfrd install
-	$(MAKE) -C sv install
-	$(MAKE) -C xcs install
-	$(MAKE) -C ioemu install
+.PHONY: all clean install
 
-clean build:
-	$(MAKE) -C check $@
-	$(MAKE) -C libxutil $@
-	$(MAKE) -C libxc $@
-	$(MAKE) -C misc $@
-	$(MAKE) -C examples $@
-	$(MAKE) -C xentrace $@
-	$(MAKE) -C python $@
-	$(MAKE) -C xfrd $@
-	$(MAKE) -C xcs clean
-	$(MAKE) -C ioemu clean
+all:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done
+
+clean:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done
+
+install:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done
Signature · 12 lines
Jerone Young
IBM Linux Technology Center
[email protected]
512-838-1157 (T/L: 678-1157)



-------------------------------------------------------
This SF.net email is sponsored by: 2005 Windows Mobile Application Contest
Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones
for the chance to win $25,000 and application distribution. Enter today at
http://ads.osdn.com/?ad_id=6882&alloc_id=15148&op=click
#1 lore raw
Quoted 9 lines · Jerone Young

I cleaned up the top level makefile in the tools directory. No major changes. Except I have it so that ioemmu is compiled only with x86_32.

Makefile renamed from Makefile.orig +4 -0
+all:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done

Makefile line 33

Quoted 10 lines
Makefile renamed from Makefile.orig +10 -0
+
+clean:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done
+
+install:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done

Don't do it like this. make -j won't work.

Besides, don't use || exit. Instead, use set -e.

-------------------------------------------------------
This SF.net email is sponsored by: 2005 Windows Mobile Application Contest Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones for the chance to win $25,000 and application distribution. Enter today at
http://ads.osdn.com/?ad_id=6882&alloc_id=15148&op=click

#2 lore raw
Quoted 7 lines · Adam Heath
Quoted 5 lines · Jerone Young

I cleaned up the top level makefile in the tools directory. No major changes. Except I have it so that ioemmu is compiled only with x86_32.

Quoted 16 lines
Quoted 4 lines
Makefile renamed from Makefile.orig +4 -0
+all:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done

Makefile line 33

Quoted 10 lines
Makefile renamed from Makefile.orig +10 -0
+
+clean:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done
+
+install:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done

Don't do it like this. make -j won't work.

Hmm...I mainly did this to clean up things for development purposes. I don't know if everyone cares all that much about the using the -j option with building the tools (maybe..someone speakup!). It really does not take anytime now to build them without it. Also you have to build libxutil & libxc first so your not going to get a huge performance increase because everything is dependent on these getting built first.

Quoted 2 lines

Besides, don't use || exit. Instead, use set -e.

We want the build to die (with extreme prejudice :-) ) if something does not go right.

Quoted 1 line
Signature · 12 lines
Jerone Young
IBM Linux Technology Center
[email protected]
512-838-1157 (T/L: 678-1157)



-------------------------------------------------------
This SF.net email is sponsored by: 2005 Windows Mobile Application Contest
Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones
for the chance to win $25,000 and application distribution. Enter today at
http://ads.osdn.com/?ad_id=6882&alloc_id=15148&op=click
#3 lore raw
Quoted 24 lines · Jerone Young
Quoted 7 lines · Adam Heath
Quoted 5 lines · Jerone Young

I cleaned up the top level makefile in the tools directory. No major changes. Except I have it so that ioemmu is compiled only with x86_32.

Quoted 16 lines
Quoted 4 lines
Makefile renamed from Makefile.orig +4 -0
+all:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done

Makefile line 33

Quoted 10 lines
Makefile renamed from Makefile.orig +10 -0
+
+clean:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done
+
+install:
+	@for subdir in $(SUBDIRS); do \
+		$(MAKE) -C $$subdir $@ || exit -1; \
+	done

Don't do it like this. make -j won't work.

Quoted 6 lines

Hmm...I mainly did this to clean up things for development purposes. I don't know if everyone cares all that much about the using the -j option with building the tools (maybe..someone speakup!). It really does not take anytime now to build them without it. Also you have to build libxutil & libxc first so your not going to get a huge performance increase because everything is dependent on these getting built first.

==
install: $(patsubst %,install.%,$(SUBDIRS)) $(patsubst %,install.%,$(SUBDIRS)): install.%: CMD := install

all: $(patsubst %,all.%,$(SUBDIRS))
$(patsubst %,all.%,$(SUBDIRS)): all.%: CMD := all

$(foreach cmd,all install,$(patsubst %,$(cmd).%,$(SUBDIRS))):

	$(MAKE) -C $* $(CMD)

==

Adding more commands is left as an exercise, as is converting the first 2 lines into a multi-line variable(ie, define).

Quoted 3 lines
Quoted 1 line

Besides, don't use || exit. Instead, use set -e.

We want the build to die (with extreme prejudice :-) ) if something does not go right.

Yes, of course. But if you have an error in the definition of SUBDIRS(empty, or bad quote char), then your shell line may not error out.

Using set -e is the preferred approach.

Generally, like:

	@set -e; for .... \
		....; \
	done

Or:

SHELL += -e

-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005 Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows Embedded(r) & Windows Mobile(tm) platforms, applications & content. Register by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click

#4 lore raw
Quoted 8 lines · Adam Heath

install: $(patsubst %,install.%,$(SUBDIRS)) $(patsubst %,install.%,$(SUBDIRS)): install.%: CMD := install

all: $(patsubst %,all.%,$(SUBDIRS))
$(patsubst %,all.%,$(SUBDIRS)): all.%: CMD := all

$(foreach cmd,all install,$(patsubst %,$(cmd).%,$(SUBDIRS))):
$(MAKE) -C $* $(CMD)

The following is working for me and I think easier to read than the above:
==
CLEANDIRS := $(addprefix _clean_,$(SUBDIRS))

.PHONY: all clean $(SUBDIRS) $(CLEANDIRS)

all: $(SUBDIRS)
clean: $(CLEANDIRS)

$(CLEANDIRS):
$(MAKE) -C $(patsubst _clean_%,%,$@) clean

$(SUBDIRS):
$(MAKE) -C $@
==

Well, I guess it's not very dissimilar after all.

But I really don't like that for every command to recurse with (e.g. clean), you must add more hackery to the Makefile. Your snippet has the same problem (let's add "clean"...), and it seems all the Makefiles have all the issues discussed in different places.

Is there really no better way to solve this problem?

Signature · 9 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005
Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows
Embedded(r) & Windows Mobile(tm) platforms, applications & content.  Register
by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click
#5 lore raw
Quoted 7 lines · Hollis Blanchard

Well, I guess it's not very dissimilar after all.

But I really don't like that for every command to recurse with (e.g. clean), you must add more hackery to the Makefile. Your snippet has the same problem (let's add "clean"...), and it seems all the Makefiles have all the issues discussed in different places.

Is there really no better way to solve this problem?

The following works for me. You need a default rule or else make gets really confused but the wildcard rule will catch everything else.

SUBDIRS=sub sub1

all:

   @for i in $(SUBDIRS); do \
      $(MAKE) -C $$i $@; \

done

%:

   @for i in $(SUBDIRS); do \
      $(MAKE) -C $$i $@; \

done

-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005 Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows Embedded(r) & Windows Mobile(tm) platforms, applications & content. Register by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click

#6 lore raw
Quoted 15 lines · Anthony Liguori
Quoted 7 lines · Hollis Blanchard

But I really don't like that for every command to recurse with (e.g. clean), you must add more hackery to the Makefile. Your snippet has the same problem (let's add "clean"...), and it seems all the Makefiles have all the issues discussed in different places.

Is there really no better way to solve this problem?

The following works for me. You need a default rule or else make gets really confused but the wildcard rule will catch everything else.

SUBDIRS=sub sub1

all:

Quoted 8 lines
    @for i in $(SUBDIRS); do \
       $(MAKE) -C $$i $@; \
    done

%:

    @for i in $(SUBDIRS); do \
       $(MAKE) -C $$i $@; \
    done

But the for loop was the original approach, and Adam described two problems with it:
1. errors in a sub-make will be ignored
2. the sub-makes cannot be parallelized

Signature · 9 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005
Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows
Embedded(r) & Windows Mobile(tm) platforms, applications & content.  Register
by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click
#7 lore raw
Quoted 25 lines · Hollis Blanchard
Quoted 15 lines · Anthony Liguori
Quoted 7 lines · Hollis Blanchard

But I really don't like that for every command to recurse with (e.g. clean), you must add more hackery to the Makefile. Your snippet has the same problem (let's add "clean"...), and it seems all the Makefiles have all the issues discussed in different places.

Is there really no better way to solve this problem?

The following works for me. You need a default rule or else make gets really confused but the wildcard rule will catch everything else.

SUBDIRS=sub sub1

all:

Quoted 8 lines
    @for i in $(SUBDIRS); do \
       $(MAKE) -C $$i $@; \
    done

%:

    @for i in $(SUBDIRS); do \
       $(MAKE) -C $$i $@; \
    done
Quoted 4 lines

But the for loop was the original approach, and Adam described two problems with it:
1. errors in a sub-make will be ignored
2. the sub-makes cannot be parallelized

I've done fancy make stuff for years. It's what eventually made me write jmake(pure java implementation of most of gnu-make; just need to resolve the dependency tree). Hand-written parser, function/expression, implicit rules. It can currently parse the entire 2.6 kernel build system.

I need to release it.

-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click

#8 lore raw
In reply to Anthony Liguori
Quoted 6 lines · Anthony Liguori

The following works for me. You need a default rule or else make gets really confused but the wildcard rule will catch everything else.

SUBDIRS=sub sub1

all:

Quoted 8 lines
    @for i in $(SUBDIRS); do \
       $(MAKE) -C $$i $@; \
    done

%:

    @for i in $(SUBDIRS); do \
       $(MAKE) -C $$i $@; \
    done

No, that won't work, as if the sub-makes fail, the shell loop doesn't stop(hint, use set -e). Also, it breaks -j.

Please go back and reread the previous mails.

-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click

#9 lore raw
In reply to Hollis Blanchard
Quoted 26 lines · Hollis Blanchard
Quoted 8 lines · Adam Heath

install: $(patsubst %,install.%,$(SUBDIRS)) $(patsubst %,install.%,$(SUBDIRS)): install.%: CMD := install

all: $(patsubst %,all.%,$(SUBDIRS))
$(patsubst %,all.%,$(SUBDIRS)): all.%: CMD := all

$(foreach cmd,all install,$(patsubst %,$(cmd).%,$(SUBDIRS))):
$(MAKE) -C $* $(CMD)

The following is working for me and I think easier to read than the above:
==
CLEANDIRS := $(addprefix _clean_,$(SUBDIRS))

.PHONY: all clean $(SUBDIRS) $(CLEANDIRS)

all: $(SUBDIRS)
clean: $(CLEANDIRS)

$(CLEANDIRS):
$(MAKE) -C $(patsubst _clean_%,%,$@) clean

$(SUBDIRS):
$(MAKE) -C $@
==

Quoted 8 lines

Well, I guess it's not very dissimilar after all.

But I really don't like that for every command to recurse with (e.g. clean), you must add more hackery to the Makefile. Your snippet has the same problem (let's add "clean"...), and it seems all the Makefiles have all the issues discussed in different places.

Is there really no better way to solve this problem?

==
define subdir.command
$(1)_targets := $$(addprefix $(1).,$$(SUBDIRS))
$(1): $$($(1)_targets)
$$($(1)_targets): $(1).%: CMD := $(1)

	$(MAKE) -C $* $(CMD)

endef

$(eval subdir.command,install)
$(eval subdir.command,clean)
==

I've not verified if the above works; ie, the quoting of $ in the multi-line variable. eval is a gnumake extension, so may not work elsewhere.

-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click

#10 lore raw
In reply to Jerone Young
Quoted 2 lines · Jerone Young

I cleaned up the top level makefile in the tools directory. No major changes. Except I have it so that ioemmu is compiled only with x86_32.

I think the change below changes the behaviour:

Quoted 2 lines
Makefile renamed from Makefile.orig +2 -0
+SUBDIRS :=
+SUBDIRS += check

...

Quoted 3 lines
Makefile renamed from Makefile.orig +0 -3
-install:
-       $(MAKE) -C check
-       $(MAKE) -C libxutil install

...

Makefile line 33

Quoted 4 lines
Makefile renamed from Makefile.orig +4 -0
+install:
+       @for subdir in $(SUBDIRS); do \
+               $(MAKE) -C $$subdir $@ || exit -1; \
+       done

You're calling ``make -C check install'' while we want to call ``make -C check''. See the comments in tools/check/Makefile why we want this...
# Check this machine is OK for installing on.
# DO NOT use this check from 'make install' in the parent # directory, as that target can be used to make an installable

# copy rather than actually installing.

At least you didn't try to go down the insane "try to make everything build in parallel" road, it might work for the tools but you need to be careful to make sure that targets which other targets depend on get built first. None of the fancy Makefile tricks which other people have posted seem to take this into account :-(

christian

-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005 Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows Embedded(r) & Windows Mobile(tm) platforms, applications & content. Register by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click

#11 lore raw
Quoted 5 lines · Christian Limpach

At least you didn't try to go down the insane "try to make everything build in parallel" road, it might work for the tools but you need to be careful to make sure that targets which other targets depend on get built first. None of the fancy Makefile tricks which other people have posted seem to take this into account :-(

That is explicitly described in the GNU make manual; see the "foo: baz" line here:
http://www.gnu.org/software/make/manual/html_chapter/make_4.html#SEC41

So that seems to be a very small problem...

Signature · 9 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005
Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows
Embedded(r) & Windows Mobile(tm) platforms, applications & content.  Register
by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click
#12 lore raw
Quoted 7 lines · Hollis Blanchard
Quoted 5 lines · Christian Limpach

At least you didn't try to go down the insane "try to make everything build in parallel" road, it might work for the tools but you need to be careful to make sure that targets which other targets depend on get built first. None of the fancy Makefile tricks which other people have posted seem to take this into account :-(

Quoted 5 lines

That is explicitly described in the GNU make manual; see the "foo: baz" line here:
http://www.gnu.org/software/make/manual/html_chapter/make_4.html#SEC41

So that seems to be a very small problem...

I know how Makefile dependencies work, thank you. The point I was trying to make was that all the sophisticated Makefile solutions to support parallel builds are nice, but they are useless to us unless someone provides a complete patch which includes correct dependency handling.

I like the original patch (except for the small check install oversight), since it's simple and I can convince myself that it is correct. I'm not sure it is needed right now though. One example would be that it has the potential to break patches applied when building packages.

christian

-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005 Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows Embedded(r) & Windows Mobile(tm) platforms, applications & content. Register by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click

#13 lore raw
In reply to Christian Limpach
Quoted 24 lines · Christian Limpach
Quoted 2 lines · Jerone Young

I cleaned up the top level makefile in the tools directory. No major changes. Except I have it so that ioemmu is compiled only with x86_32.

I think the change below changes the behaviour:

Quoted 2 lines
Makefile renamed from Makefile.orig +2 -0
+SUBDIRS :=
+SUBDIRS += check

...

Quoted 3 lines
Makefile renamed from Makefile.orig +0 -3
-install:
-       $(MAKE) -C check
-       $(MAKE) -C libxutil install

...

Makefile line 33

Quoted 4 lines
Makefile renamed from Makefile.orig +4 -0
+install:
+       @for subdir in $(SUBDIRS); do \
+               $(MAKE) -C $$subdir $@ || exit -1; \
+       done

You're calling ``make -C check install'' while we want to call ``make -C check''. See the comments in tools/check/Makefile why we want this...
# Check this machine is OK for installing on.
# DO NOT use this check from 'make install' in the parent # directory, as that target can be used to make an installable

Quoted 7 lines
# copy rather than actually installing.

At least you didn't try to go down the insane "try to make everything build in parallel" road, it might work for the tools but you need to be careful to make sure that targets which other targets depend on get built first. None of the fancy Makefile tricks which other people have posted seem to take this into account :-(

==
install: check
@whatever way people want to recurse

check:

	$(MAKE) -C check
# check is a real subdir, so we need to make it PHONY; otherwise, make assumes
# it's uptodate, and the command won't be run.
.PHONY: check
==

I originally didn't comment on this, as it wasn't my focus. But yes, if you are going to replace a set of rules, make certain they do the same thing after as they did before.

-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click