1#   -*-makefile-*-
2#   Shared/bundle.make
3#
4#   Makefile fragment with rules to copy resource files
5#   into a local bundle
6#
7#   Copyright (C) 2002 Free Software Foundation, Inc.
8#
9#   Author:  Nicola Pero <nicola@brainstorm.co.uk>
10#
11#   This file is part of the GNUstep Makefile Package.
12#
13#   This library is free software; you can redistribute it and/or
14#   modify it under the terms of the GNU General Public License
15#   as published by the Free Software Foundation; either version 3
16#   of the License, or (at your option) any later version.
17#
18#   You should have received a copy of the GNU General Public
19#   License along with this library; see the file COPYING.
20#   If not, write to the Free Software Foundation,
21#   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
23#
24# input variables:
25#
26
27#
28#  GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH : this is used when copying
29# resource files into the bundle.  It's the path to the local resource
30# bundle where all resources will be put (this might be a subdirectory
31# of the actual bundle directory).  This path must include
32# GNUSTEP_BUILD_DIR.  Resource files will be copied into this path.
33# For example, for a normal bundle it would be
34# $(BUNDLE_DIR)/Resources; for an application it would be
35# $(APP_DIR)/Resources; for a library or a tool,
36# $(GNUSTEP_BUILD_DIR)/Resources/$(GNUSTEP_INSTANCE).  This variable
37# is used during build, to copy the resources in place.
38#
39#  GNUSTEP_BUILD_DIR : Implicitly used to find the bundle.
40#
41#  GNUSTEP_SHARED_BUNDLE_INSTALL_NAME : this is used when installing.
42# It's the name of the directory that is installed.  For example, for
43# a normal bundle it would be $(BUNDLE_DIR_NAME); for an application
44# it would be $(APP_DIR_NAME); for a tool $(GNUSTEP_INSTANCE); for a
45# library, $(INTERFACE_VERSION).
46#
47#  GNUSTEP_SHARED_BUNDLE_INSTALL_LOCAL_PATH : this is used when
48# installing.  It's the path to the directory that contains
49# GNUSTEP_SHARED_BUNDLE_INSTALL_NAME, but relative to
50# GNUSTEP_BUILD_DIR.  For example, for a normal bundle or an
51# application this is simply ./; for a tool this is ./Resources; for a
52# library this is ./Resources/$(GNUSTEP_INSTANCE).  This is relative
53# to GNUSTEP_BUILD_DIR so that it can be used by COPY_INTO_DIR as
54# well.  When we are asked to COPY_INTO_DIR (instead of the standard
55# installation) then we copy the stuff from
56# GNUSTEP_BUILD_DIR/GNUSTEP_SHARED_BUNDLE_INSTALL_LOCAL_PATH into
57# COPY_INTO_DIR/GNUSTEP_SHARED_BUNDLE_INSTALL_LOCAL_PATH.  This works
58# well for tool resources, for example, so that when you copy a tool
59# with resources into a framework, the tool resources and the tool
60# executable remain in the same relative relationship and tool
61# resources can be found.
62#
63#  GNUSTEP_SHARED_BUNDLE_INSTALL_PATH : this is used when installing.
64# It's the path where we install the bundle; that is, we will take
65# GNUSTEP_SHARED_BUNDLE_INSTALL_NAME from
66# GNUSTEP_SHARED_BUNDLE_INSTALL_LOCAL_PATH and install it into
67# GNUSTEP_SHARED_BUNDLE_INSTALL_PATH.  For example, for a normal
68# bundle it would be $(BUNDLE_INSTALL_DIR); for an application it
69# would be $(APP_INSTALL_DIR); for a tool, $(GNUSTEP_TOOL_RESOURCES);
70# for a library $(GNUSTEP_RESOURCES)/$(GNUSTEP_INSTANCE).
71#
72# Please note that the main constraint when installing is that your
73# local bundle should have the same name that it has when installed.
74# Paths can be changed arbitrarily though.
75#
76#  $(GNUSTEP_INSTANCE)_RESOURCE_FILES : a list of resource files to install.
77#  They are recursively copied (/symlinked), so it might also include dirs.
78#
79#  $(GNUSTEP_INSTANCE)_RESOURCE_DIRS : a list of additional resource dirs
80#  to create.
81#
82#  $(GNUSTEP_INSTANCE)_RESOURCE_FILES_DIR : the directory in which the
83#  resource files and localized resource files are to be found
84#  (defaults to ./ if omitted).
85#
86#  $(GNUSTEP_INSTANCE)_LANGUAGES : the list of languages of localized resource
87#  files (processed in rules.make, and converted into a LANGUAGES list)
88#
89#  $(GNUSTEP_INSTANCE)_LOCALIZED_RESOURCE_FILES : a list of localized
90#  resource files to install.
91#
92#  $(GNUSTEP_INSTANCE)_LOCALIZED_RESOURCE_DIRS : a list of additional localized
93#  resource dirs to create.
94#
95#  $(GNUSTEP_INSTANCE)_COMPONENTS : a list of directories which are
96#  recursively copied (/locally symlinked if symlinks are available)
97#  into the resource bundle.  Basically, they are currently added to
98#  $(GNUSTEP_INSTANCE)_RESOURCE_FILES.
99#
100#  $(GNUSTEP_INSTANCE)_LOCALIZED_COMPONENTS : a list of localized
101#  directories which are recursively copied (/locally symlinked if
102#  symlinks are available) into the resource bundle.  Currently, they
103#  are simply added to $(GNUSTEP_INSTANCE)_LOCALIZED_RESOURCE_FILES.
104#
105#  $(GNUSTEP_INSTANCE)_SUBPROJECTS : the list of subprojects is used
106#  because the resources from each subproject are merged into the bundle
107#  resources (by recursively copying from LLL/Resources/Subproject into
108#  the GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH, where $(LLL) is the
109#  subproject name.
110#
111#  GNUSTEP_TYPE : used when printing the message 'Copying resources into
112#  the $(GNUSTEP_TYPE) wrapper...'
113#
114# GSWeb related variables -
115#
116# $(GNUSTEP_INSTANCE)_WEBSERVER_RESOURCE_FILES : a list of resource files to
117# copy from the WebServerResources directory into the WebServer
118# subdirectory of the resource bundle
119#
120# $(GNUSTEP_INSTANCE)_WEBSERVER_LOCALIZED_RESOURCE_FILES : a list of
121# localized resource files to copy from the yyy.lproj subdir of the
122# WebServerResources directory into the yyy.lproj subdir of the
123# WebServer subdirectory of the resource bundle - this for each
124# language yyy.
125#
126# $(GNUSTEP_INSTANCE)_WEBSERVER_COMPONENTS:
127# $(GNUSTEP_INSTANCE)_WEBSERVER_LOCALIZED_COMPONENTS:
128# $(GNUSTEP_INSTANCE)_WEBSERVER_RESOURCE_DIRS:
129# $(GNUSTEP_INSTANCE)_WEBSERVER_LOCALIZED_RESOURCE_DIRS:
130#
131
132#
133# public targets:
134#
135#  shared-instance-bundle-all
136#
137#  $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH): Creates the bundle
138#  resource path (invoked automatically)
139#
140#  shared-instance-bundle-install
141#  shared-instance-bundle-uninstall
142#  shared-instance-bundle-copy_into_dir
143#
144
145#
146# Warning - the bundle install rules depend on the rule to create
147# $(GNUSTEP_SHARED_BUNDLE_INSTALL_PATH) - the rule to build it has to be
148# provided by the caller {we can't provide two rules to build the same
149# target; the caller might need to provide the rule for cases when we
150# are not included, so we let the caller always provide it}
151#
152
153# Determine the dir to take the resources from
154RESOURCE_FILES_DIR = $($(GNUSTEP_INSTANCE)_RESOURCE_FILES_DIR)
155ifeq ($(RESOURCE_FILES_DIR),)
156RESOURCE_FILES_DIR = ./
157endif
158
159RESOURCE_FILES = $(strip $($(GNUSTEP_INSTANCE)_RESOURCE_FILES) \
160                        $($(GNUSTEP_INSTANCE)_COMPONENTS))
161RESOURCE_DIRS = $(strip $($(GNUSTEP_INSTANCE)_RESOURCE_DIRS))
162LOCALIZED_RESOURCE_FILES = \
163  $(strip $($(GNUSTEP_INSTANCE)_LOCALIZED_RESOURCE_FILES) \
164         $($(GNUSTEP_INSTANCE)_LOCALIZED_COMPONENTS))
165LOCALIZED_RESOURCE_DIRS = \
166  $(strip $($(GNUSTEP_INSTANCE)_LOCALIZED_RESOURCE_DIRS))
167
168# NB: Use _SUBPROJECTS, not SUBPROJECTS here as that might conflict
169# with what is used in aggregate.make.
170_SUBPROJECTS = $(strip $($(GNUSTEP_INSTANCE)_SUBPROJECTS))
171
172.PHONY: \
173shared-instance-bundle-all \
174shared-instance-bundle-all-resources \
175shared-instance-bundle-all-gsweb \
176shared-instance-bundle-install \
177shared-instance-bundle-uninstall \
178shared-instance-bundle-copy_into_dir
179
180ifneq ($(RESOURCE_DIRS),)
181
182FULL_RESOURCE_DIRS = \
183$(foreach d, $(RESOURCE_DIRS), $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/$(d))
184
185endif
186
187$(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH):
188	$(ECHO_CREATING)$(MKDIRS) $@$(END_ECHO)
189
190$(FULL_RESOURCE_DIRS):
191	$(ECHO_CREATING)$(MKDIRS) $@$(END_ECHO)
192
193
194#
195# We provide two different ways of building bundles, suited to
196# different usages - normal user and developer.
197#
198# `Normal user` builds the bundle once.  We optimize for single-build
199# in this case.
200#
201# `Developer` builds and rebuilds the bundle a lot of times with minor
202# changes each time.  We optimize for efficient rebuilding in this
203# case.
204#
205# The default behaviour is 'Normal user'.  To switch to 'Developer'
206# mode, set GNUSTEP_DEVELOPER=yes in the environment.
207#
208# TODO - implement the `Developer` mode :-)
209#
210
211# Please note the trick when copying subproject resources - if there
212# is nothing inside $$subproject/Resources/Subproject/, in
213# $$subproject/Resources/Subproject/* the * expands to itself.  So we
214# check if that is true before trying to copy.
215
216# Please note that if xxx/yyy is specified in RESOURCE_FILES, we
217# create the file {bundle}/yyy (not {bundle}/xxx/yyy), because people
218# usually can put resource files in subdirs, and want to copy them
219# just top-level.  That is what currently happens, but often enough
220# you might want the other behaviour ({bundle}/xxx/yyy to be created),
221# and TODO: devise a way to support it.
222#
223# If instead xxx/yyy is specified in LOCALIZED_RESOURCE_FILES, we
224# create the file {bundle}/Language.lproj/xxx/yyy, because we want to
225# mirror the Language.lproj directory faithfully.  There is no
226# possible confusion here.
227#
228# Important: we pass the '-f' argument to 'cp' to make sure that you
229# can write and overwrite RESOURCE_FILES which are -r--r--r--.
230#
231shared-instance-bundle-all: $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH) \
232                      $(FULL_RESOURCE_DIRS) \
233                      shared-instance-bundle-all-gsweb
234ifneq ($(RESOURCE_FILES),)
235	$(ECHO_COPYING_RESOURCES)for f in $(RESOURCE_FILES); do \
236	  if [ -f $(RESOURCE_FILES_DIR)/$$f -o -d $(RESOURCE_FILES_DIR)/$$f ]; then \
237	    cp -fr $(RESOURCE_FILES_DIR)/$$f $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/; \
238	  else \
239	    echo "Warning: $(RESOURCE_FILES_DIR)/$$f not found - ignoring"; \
240	  fi; \
241	done$(END_ECHO)
242endif
243ifneq ($(LOCALIZED_RESOURCE_DIRS),)
244	$(ECHO_CREATING_LOC_RESOURCE_DIRS)for l in $(LANGUAGES); do \
245	  if [ -d $(RESOURCE_FILES_DIR)/$$l.lproj ]; then \
246	    $(MKDIRS) $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/$$l.lproj; \
247	    for f in $(LOCALIZED_RESOURCE_DIRS); do \
248	      $(MKDIRS) $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/$$l.lproj/$$f; \
249	    done; \
250	  else \
251	    echo "Warning: $(RESOURCE_FILES_DIR)/$$l.lproj not found - ignoring"; \
252	  fi; \
253	done$(END_ECHO)
254endif
255ifneq ($(LOCALIZED_RESOURCE_FILES),)
256	$(ECHO_COPYING_LOC_RESOURCES)for l in $(LANGUAGES); do \
257	  if [ -d $(RESOURCE_FILES_DIR)/$$l.lproj ]; then \
258	    $(MKDIRS) $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/$$l.lproj; \
259	    for f in $(LOCALIZED_RESOURCE_FILES); do \
260	      if [ -f $(RESOURCE_FILES_DIR)/$$l.lproj/$$f -o -d $(RESOURCE_FILES_DIR)/$$l.lproj/$$f ]; then \
261	        cp -fr $(RESOURCE_FILES_DIR)/$$l.lproj/$$f \
262	              $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/$$l.lproj/; \
263	      else \
264	        echo "Warning: $(RESOURCE_FILES_DIR)/$$l.lproj/$$f not found - ignoring"; \
265	      fi; \
266	    done; \
267	  else \
268	    echo "Warning: $(RESOURCE_FILES_DIR)/$$l.lproj not found - ignoring"; \
269	  fi; \
270	done$(END_ECHO)
271endif
272ifneq ($(_SUBPROJECTS),)
273	$(ECHO_COPYING_RESOURCES_FROM_SUBPROJS)for subproject in $(_SUBPROJECTS); do \
274	  if [ -d $$subproject/Resources/Subproject ]; then \
275	    for f in $$subproject/Resources/Subproject/*; do \
276	      if [ $$f != $$subproject'/Resources/Subproject/*' ]; then \
277	        cp -fr $$f $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/; \
278	      fi; \
279	    done; \
280	  fi; \
281	done$(END_ECHO)
282endif
283
284##
285##
286## GSWeb code
287## A main issue here is - executing *nothing* if gsweb is not used :-)
288##
289##
290
291WEBSERVER_RESOURCE_FILES = \
292  $(strip $($(GNUSTEP_INSTANCE)_WEBSERVER_RESOURCE_FILES) \
293         $($(GNUSTEP_INSTANCE)_WEBSERVER_COMPONENTS))
294# For historical reasons, we recognized the old variant
295# xxx_LOCALIZED_WEBSERVER_RESOURCE_FILES - but we recommend to use
296# xxx_WEBSERVER_LOCALIZED_RESOURCE_FILES instead.
297WEBSERVER_LOCALIZED_RESOURCE_FILES = \
298  $(strip $($(GNUSTEP_INSTANCE)_LOCALIZED_WEBSERVER_RESOURCE_FILES) \
299         $($(GNUSTEP_INSTANCE)_WEBSERVER_LOCALIZED_RESOURCE_FILES) \
300         $($(GNUSTEP_INSTANCE)_WEBSERVER_LOCALIZED_COMPONENTS))
301WEBSERVER_RESOURCE_DIRS = \
302  $(strip $($(GNUSTEP_INSTANCE)_WEBSERVER_RESOURCE_DIRS))
303WEBSERVER_LOCALIZED_RESOURCE_DIRS = \
304  $(strip $($(GNUSTEP_INSTANCE)_WEBSERVER_LOCALIZED_RESOURCE_DIRS))
305
306
307ifneq ($(WEBSERVER_RESOURCE_DIRS),)
308
309WEBSERVER_FULL_RESOURCE_DIRS = \
310$(foreach d, $(WEBSERVER_RESOURCE_DIRS), $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/WebServer/$(d))
311
312$(WEBSERVER_FULL_RESOURCE_DIRS):
313	$(ECHO_CREATING)$(MKDIRS) $@$(END_ECHO)
314
315endif
316
317
318.PHONY: shared-instance-bundle-all-webresources \
319       shared-instance-bundle-all-localized-webresources
320
321shared-instance-bundle-all-gsweb: shared-instance-bundle-all-webresources \
322                           shared-instance-bundle-all-localized-webresources
323
324ifneq ($(WEBSERVER_RESOURCE_FILES),)
325
326$(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/WebServer:
327	$(ECHO_CREATING)$(MKDIRS) $@$(END_ECHO)
328
329shared-instance-bundle-all-webresources: \
330  $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/WebServer \
331  $(WEBSERVER_FULL_RESOURCE_DIRS)
332	$(ECHO_COPYING_WEBSERVER_RESOURCES)for f in $(WEBSERVER_RESOURCE_FILES); do \
333	  if [ -f ./WebServerResources/$$f \
334	       -o -d ./WebServerResources/$$f ]; then \
335	    cp -fr ./WebServerResources/$$f \
336	       $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/WebServer/$$f; \
337	  else \
338	    echo "Warning: WebServerResources/$$f not found - ignoring"; \
339	  fi; \
340	done$(END_ECHO)
341else
342
343shared-instance-bundle-all-webresources:
344
345endif
346
347ifneq ($(WEBSERVER_LOCALIZED_RESOURCE_FILES)$(WEBSERVER_LOCALIZED_RESOURCE_DIRS),)
348shared-instance-bundle-all-localized-webresources: \
349  $(WEBSERVER_FULL_RESOURCE_DIRS)
350ifneq ($(WEBSERVER_LOCALIZED_RESOURCE_DIRS),)
351	$(ECHO_CREATING_WEBSERVER_LOC_RESOURCE_DIRS)for l in $(LANGUAGES); do \
352	 if [ -d ./WebServerResources/$$l.lproj ]; then \
353	  $(MKDIRS) \
354	   $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/WebServer/$$l.lproj; \
355	  for f in $(WEBSERVER_LOCALIZED_RESOURCE_DIRS); do \
356	   $(MKDIRS) \
357	     $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/WebServer/$$l.lproj/$$f; \
358	    done; \
359	  else \
360	    echo "Warning: WebServer/$$l.lproj not found - ignoring"; \
361	  fi; \
362	done$(END_ECHO)
363endif
364ifneq ($(WEBSERVER_LOCALIZED_RESOURCE_FILES),)
365	$(ECHO_COPYING_WEBSERVER_LOC_RESOURCES)for l in $(LANGUAGES); do \
366	 if [ -d ./WebServerResources/$$l.lproj ]; then \
367	  $(MKDIRS) \
368	  $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/WebServer/$$l.lproj;\
369	  for f in $(WEBSERVER_LOCALIZED_RESOURCE_FILES); do \
370	   if [ -f ./WebServerResources/$$l.lproj/$$f \
371	        -o -d ./WebServerResources/$$l.lproj/$$f ]; then \
372	    cp -fr ./WebServerResources/$$l.lproj/$$f \
373	          $(GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH)/WebServer/$$l.lproj/$$f; \
374	      else \
375	        echo "Warning: WebServerResources/$$l.lproj/$$f not found - ignoring"; \
376	      fi; \
377	    done; \
378	  else \
379	    echo "Warning: WebServerResources/$$l.lproj not found - ignoring"; \
380	  fi; \
381	done$(END_ECHO)
382endif
383
384else
385
386shared-instance-bundle-all-localized-webresources:
387
388endif
389
390# In the following rule, tar has the 'h' option, which dereferences
391# symbolic links.  The idea is that you could specify symbolic links
392# to some templates as some of the resource files; then building the
393# bundle is quick, because you only copy the symlinks - not the actual
394# files; and the symlinks are dereferenced when the bundle is
395# installed (which is why the 'h' option is there).  I've never used
396# this feature, but it was requested by some of our users.
397#
398
399# Another common request is to ignore/drop CVS and .svn
400# directories/files from the bundle when installing.  You don't really
401# want to install those in case they ended up in the bundle when you
402# recursively copied some resources in it from your source code.
403# This is obtained by using the 'X' flag.
404#
405# Because of compatibility issues with older versions of GNU tar (not
406# to speak of non-GNU tars), we use the X option rather than the
407# --exclude= option.  The X option requires as argument a file listing
408# files to exclude.  We use a standard exclude file list which we store
409# in GNUSTEP_MAKEFILES.
410#
411shared-instance-bundle-install:: $(GNUSTEP_SHARED_BUNDLE_INSTALL_PATH)
412	$(ECHO_INSTALLING_BUNDLE)rm -rf $(GNUSTEP_SHARED_BUNDLE_INSTALL_PATH)/$(GNUSTEP_SHARED_BUNDLE_INSTALL_NAME); \
413        $(MKINSTALLDIRS) $(GNUSTEP_SHARED_BUNDLE_INSTALL_PATH); \
414	(cd $(GNUSTEP_BUILD_DIR)/$(GNUSTEP_SHARED_BUNDLE_INSTALL_LOCAL_PATH); \
415	    $(TAR) chfX - $(GNUSTEP_MAKEFILES)/tar-exclude-list $(GNUSTEP_SHARED_BUNDLE_INSTALL_NAME)) \
416	 | (cd $(GNUSTEP_SHARED_BUNDLE_INSTALL_PATH); $(TAR) xf -)$(END_ECHO)
417ifneq ($(CHOWN_TO),)
418	$(ECHO_CHOWNING)$(CHOWN) -R $(CHOWN_TO) \
419	  $(GNUSTEP_SHARED_BUNDLE_INSTALL_PATH)/$(GNUSTEP_SHARED_BUNDLE_INSTALL_NAME)$(END_ECHO)
420endif
421
422shared-instance-bundle-copy_into_dir::
423	$(ECHO_COPYING_BUNDLE_INTO_DIR)rm -rf $(COPY_INTO_DIR)/$(GNUSTEP_SHARED_BUNDLE_INSTALL_LOCAL_PATH)/$(GNUSTEP_SHARED_BUNDLE_INSTALL_NAME); \
424	(cd $(GNUSTEP_BUILD_DIR); \
425	    $(TAR) chfX - $(GNUSTEP_MAKEFILES)/tar-exclude-list $(GNUSTEP_SHARED_BUNDLE_INSTALL_LOCAL_PATH)/$(GNUSTEP_SHARED_BUNDLE_INSTALL_NAME)) \
426	 | (cd $(COPY_INTO_DIR); $(TAR) xf -)$(END_ECHO)
427
428shared-instance-bundle-uninstall::
429	$(ECHO_NOTHING)cd $(GNUSTEP_SHARED_BUNDLE_INSTALL_PATH); rm -rf $(GNUSTEP_SHARED_BUNDLE_INSTALL_NAME)$(END_ECHO)
430