1#  -*-makefile-*-
2#   Instance/library.make
3#
4#   Instance Makefile rules to build GNUstep-based libraries.
5#
6#   Copyright (C) 1997, 2001 Free Software Foundation, Inc.
7#
8#   Author:  Scott Christley <scottc@net-community.com>
9#	     Ovidiu Predescu <ovidiu@net-community.com>
10#            Nicola Pero     <nicola@brainstorm.co.uk>
11#
12#   This file is part of the GNUstep Makefile Package.
13#
14#   This library is free software; you can redistribute it and/or
15#   modify it under the terms of the GNU General Public License
16#   as published by the Free Software Foundation; either version 3
17#   of the License, or (at your option) any later version.
18#
19#   You should have received a copy of the GNU General Public
20#   License along with this library; see the file COPYING.
21#   If not, write to the Free Software Foundation,
22#   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
24# Libraries usually link against a gui library (if available).  If you
25# don't need a gui library, use xxx_NEEDS_GUI = no.
26ifeq ($(NEEDS_GUI),)
27  NEEDS_GUI = yes
28endif
29
30ifeq ($(RULES_MAKE_LOADED),)
31include $(GNUSTEP_MAKEFILES)/rules.make
32endif
33
34include $(GNUSTEP_MAKEFILES)/Instance/Shared/headers.make
35include $(GNUSTEP_MAKEFILES)/Instance/Shared/pkgconfig.make
36
37#
38# The name of the library (including the 'lib' prefix) is
39# in the LIBRARY_NAME variable.
40# The Objective-C files that gets included in the library are in xxx_OBJC_FILES
41# The C files are in xxx_C_FILES
42# The pswrap files are in xxx_PSWRAP_FILES
43# The header files are in xxx_HEADER_FILES
44# The directory where the header files are located is xxx_HEADER_FILES_DIR
45# The directory where to install the header files inside the library
46# installation directory is xxx_HEADER_FILES_INSTALL_DIR
47# The directory in which 'make check' will cause tests to be run using
48# gnustep-tests is xxx_TEST_DIR
49#
50#	Where xxx is the name of the library
51#
52
53.PHONY: internal-library-all_ \
54        internal-library-install_ \
55        internal-library-uninstall_ \
56        internal-install-lib \
57        internal-install-dirs \
58	internal-library-compile
59
60# This is the directory where the libs get installed.  This should *not*
61# include the target arch, os directory or library_combo.
62ifneq ($($(GNUSTEP_INSTANCE)_INSTALL_DIR),)
63  LIBRARY_INSTALL_DIR = $($(GNUSTEP_INSTANCE)_INSTALL_DIR)
64endif
65
66ifeq ($(LIBRARY_INSTALL_DIR),)
67  LIBRARY_INSTALL_DIR = $(GNUSTEP_LIBRARIES)
68endif
69
70# And this is used internally - it is the final directory where we put the
71# library - it includes target arch, os dir and library_combo - this variable
72# is PRIVATE to gnustep-make
73#
74# Do not set this variable if it is already set ... this allows other
75# makefiles (Instance/clibrary.make) to use the code in this file with
76# a different FINAL_LIBRARY_INSTALL_DIR !
77#
78ifeq ($(FINAL_LIBRARY_INSTALL_DIR),)
79  FINAL_LIBRARY_INSTALL_DIR = $(LIBRARY_INSTALL_DIR)/$(GNUSTEP_TARGET_LDIR)
80endif
81
82# Set VERSION from xxx_VERSION
83ifneq ($($(GNUSTEP_INSTANCE)_VERSION),)
84  VERSION = $($(GNUSTEP_INSTANCE)_VERSION)
85endif
86
87ifeq ($(VERSION),)
88  # Check if we can guess VERSION from one of the other version variables
89  ifneq ($($(GNUSTEP_INSTANCE)_INTERFACE_VERSION),)
90    VERSION = $($(GNUSTEP_INSTANCE)_INTERFACE_VERSION).0
91  else
92    # For backwards compatibility we also check xxx_SOVERSION, which
93    # is the old name for xxx_INTERFACE_VERSION
94    ifneq ($($(GNUSTEP_INSTANCE)_SOVERSION),)
95      VERSION = $($(GNUSTEP_INSTANCE)_SOVERSION).0
96    else
97      # No luck with those.  Use the default.
98      VERSION = 0.0.1
99    endif
100  endif
101endif
102
103#
104# Manage the case that LIBRARY_NAME starts with 'lib', and the case
105# that it doesn't start with 'lib'.  In both cases, we need to create
106# a .so file whose name starts with 'lib'.
107#
108ifneq ($(filter lib%,$(GNUSTEP_INSTANCE)),)
109  LIBRARY_NAME_WITH_LIB = $(GNUSTEP_INSTANCE)
110  LIBRARY_NAME_WITHOUT_LIB = $(patsubst lib%,%,$(GNUSTEP_INSTANCE))
111else
112  LIBRARY_NAME_WITH_LIB = lib$(GNUSTEP_INSTANCE)
113  LIBRARY_NAME_WITHOUT_LIB = $(GNUSTEP_INSTANCE)
114endif
115
116# On windows, this is unfortunately required.
117ifeq ($(BUILD_DLL), yes)
118  LINK_AGAINST_ALL_LIBS = yes
119endif
120
121ifeq ($(LINK_AGAINST_ALL_LIBS), yes)
122  # Link against all libs ... but not the one we're compiling! (this can
123  # happen, for example, with gnustep-gui)
124  LIBRARIES_DEPEND_UPON += $(filter-out -l$(LIBRARY_NAME_WITHOUT_LIB), $(ALL_LIBS))
125endif
126
127INTERNAL_LIBRARIES_DEPEND_UPON =				\
128   $(ALL_LIB_DIRS)						\
129   $(LIBRARIES_DEPEND_UPON)
130
131ifeq ($(shared), yes)
132
133# Allow the user GNUmakefile to define xxx_INTERFACE_VERSION to
134# replace the default INTERFACE_VERSION for this library.
135
136# Effect of the value of xxx_INTERFACE_VERSION -
137
138#  suppose your library is libgnustep-base.1.0.0 - if you do nothing,
139#  INTERFACE_VERSION=1, and we prepare the symlink
140#  libgnustep-base.so.1 --> libgnustep-base.so.1.0.0 and tell the
141#  linker that it should remember that any application compiled
142#  against this library need to use version .1 of the library.  So at
143#  runtime, the dynamical linker will search for libgnustep-base.so.1.
144#  This is important if you install multiple versions of the same
145#  library.  The default is that if you install a new version of a
146#  library with the same major number, the new version replaces the
147#  old one, and all applications which were using the old one now use
148#  the new one.  If you install a library with a different major
149#  number, the old apps will still use the old library, while newly
150#  compiled apps will use the new one.
151
152#  If you redefine xxx_INTERFACE_VERSION to be for example 1.0, then
153#  we prepare the symlink libgnustep-base.so.1.0 -->
154#  libgnustep-base.so.1.0.0 instead, and tell the linker to remember
155#  1.0.  So at runtime, the dynamic linker will search for
156#  libgnustep-base.so.1.0.  The effect of changing
157#  xxx_INTERFACE_VERSION to major.minor as in this example is that if
158#  you install a new version with the same major.minor version, that
159#  replaces the old one also for old applications, but if you install
160#  a new library with the same major version but a *different* minor
161#  version, that is used in new apps, but old apps still use the old
162#  version.
163
164ifeq ($($(GNUSTEP_INSTANCE)_INTERFACE_VERSION),)
165
166  # Backwards compatibility: xxx_SOVERSION was the old name for
167  # xxx_INTERFACE_VERSION.  There was no support for setting SOVERSION
168  # (without xxx_), like there is no support for setting
169  # INTERFACE_VERSION (without xxx_) now.
170
171  # TODO: Remove xxx_SOVERSION at some point in the next few
172  # years.  NB: Likely the only user of this is Helge Hess, so once he's
173  # upgraded, let's remove the backwards compatibility code. :-)
174  ifneq ($($(GNUSTEP_INSTANCE)_SOVERSION),)
175    INTERFACE_VERSION = $($(GNUSTEP_INSTANCE)_SOVERSION)
176  else
177
178    # This is the current code - by default, if VERSION is
179    # 1.0.0, INTERFACE_VERSION is 1
180    INTERFACE_VERSION = $(word 1,$(subst ., ,$(VERSION)))
181
182  endif
183else
184  INTERFACE_VERSION = $($(GNUSTEP_INSTANCE)_INTERFACE_VERSION)
185endif
186
187ifneq ($(BUILD_DLL),yes)
188
189LIBRARY_FILE = $(LIBRARY_NAME_WITH_LIB)$(SHARED_LIBEXT)
190ifeq ($(findstring darwin, $(GNUSTEP_TARGET_OS)), darwin)
191# On Mac OS X the version number conventionally precedes the shared
192# library suffix, e.g., libgnustep-base.1.16.1.dylib.
193VERSION_LIBRARY_FILE = $(LIBRARY_NAME_WITH_LIB).$(VERSION)$(SHARED_LIBEXT)
194SONAME_LIBRARY_FILE  = $(LIBRARY_NAME_WITH_LIB).$(INTERFACE_VERSION)$(SHARED_LIBEXT)
195else
196VERSION_LIBRARY_FILE = $(LIBRARY_FILE).$(VERSION)
197SONAME_LIBRARY_FILE  = $(LIBRARY_FILE).$(INTERFACE_VERSION)
198endif
199
200else # BUILD_DLL
201
202# When you build a DLL, you have to install it in a directory which is
203# in your PATH.
204ifeq ($(DLL_INSTALLATION_DIR),)
205  DLL_INSTALLATION_DIR = $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR)
206endif
207
208# When we build a DLL, we also pass -DBUILD_lib{library_name}_DLL=1 to
209# the preprocessor.  With the new DLL support, this is usually not
210# needed; but in some cases some symbols are difficult and have to be
211# exported/imported manually.  For these cases, the library header
212# files can use this preprocessor define to know that they are
213# included during compilation of the library itself, or are being
214# imported by external code.  Typically with the new DLL support if a
215# symbol can't be imported you have to mark it with
216# __declspec(dllimport) when the library is not being compiled.
217# __declspec(dllexport) is not particularly useful instead.
218
219CLEAN_library_NAME = $(subst -,_,$(LIBRARY_NAME_WITH_LIB))
220SHARED_CFLAGS += -DBUILD_$(CLEAN_library_NAME)_DLL=1
221
222# LIBRARY_FILE is the import library, libgnustep-base.dll.a
223LIBRARY_FILE         = $(LIBRARY_NAME_WITH_LIB)$(DLL_LIBEXT)$(LIBEXT)
224VERSION_LIBRARY_FILE = $(LIBRARY_FILE)
225SONAME_LIBRARY_FILE  = $(LIBRARY_FILE)
226
227# LIB_LINK_DLL_FILE is the DLL library, gnustep-base-1.dll
228# (cyggnustep-base-1.dll on Cygwin).  Include the INTERFACE_VERSION in
229# the DLL library name.  Applications are linked explicitly to this
230# INTERFACE_VERSION of the library; this works exactly in the same way
231# as under Unix.
232LIB_LINK_DLL_FILE    = $(DLL_PREFIX)$(LIBRARY_NAME_WITHOUT_LIB)-$(subst .,_,$(INTERFACE_VERSION))$(DLL_LIBEXT)
233endif # BUILD_DLL
234
235else # following code for static libs
236
237LIBRARY_FILE         = $(LIBRARY_NAME_WITH_LIB)$(LIBEXT)
238VERSION_LIBRARY_FILE = $(LIBRARY_FILE)
239SONAME_LIBRARY_FILE  = $(LIBRARY_FILE)
240
241endif # shared
242
243#
244# Now prepare the variables which are used by target-dependent commands
245# defined in target.make
246#
247LIB_LINK_OBJ_DIR = $(GNUSTEP_OBJ_DIR)
248LIB_LINK_VERSION_FILE = $(VERSION_LIBRARY_FILE)
249LIB_LINK_SONAME_FILE = $(SONAME_LIBRARY_FILE)
250LIB_LINK_FILE = $(LIBRARY_FILE)
251LIB_LINK_INSTALL_NAME = $(SONAME_LIBRARY_FILE)
252LIB_LINK_INSTALL_DIR = $(FINAL_LIBRARY_INSTALL_DIR)
253
254# On Mac OS X, set absolute install_name if requested
255ifeq ($(findstring darwin, $(GNUSTEP_TARGET_OS)), darwin)
256  ifeq ($(GNUSTEP_ABSOLUTE_INSTALL_PATHS), yes)
257    LIB_LINK_INSTALL_NAME = $(LIB_LINK_INSTALL_DIR)/$(SONAME_LIBRARY_FILE)
258  endif
259endif
260
261#
262# Internal targets
263#
264
265#
266# Compilation targets
267#
268ifeq ($(GNUSTEP_MAKE_PARALLEL_BUILDING), no)
269# Standard building
270internal-library-all_:: $(GNUSTEP_OBJ_INSTANCE_DIR) \
271                        $(OBJ_DIRS_TO_CREATE) \
272			$(GNUSTEP_OBJ_DIR)/$(VERSION_LIBRARY_FILE)
273else
274# Parallel building.  The actual compilation is delegated to a
275# sub-make invocation where _GNUSTEP_MAKE_PARALLEL is set to yet.
276# That sub-make invocation will compile files in parallel.
277internal-library-all_:: $(GNUSTEP_OBJ_INSTANCE_DIR) $(OBJ_DIRS_TO_CREATE)
278	$(ECHO_NOTHING_RECURSIVE_MAKE)$(MAKE) -f $(MAKEFILE_NAME) --no-print-directory --no-keep-going \
279	internal-library-compile \
280	GNUSTEP_TYPE=$(GNUSTEP_TYPE) \
281	GNUSTEP_INSTANCE=$(GNUSTEP_INSTANCE) \
282	GNUSTEP_OPERATION=compile \
283	GNUSTEP_BUILD_DIR="$(GNUSTEP_BUILD_DIR)" \
284	_GNUSTEP_MAKE_PARALLEL=yes$(END_ECHO_RECURSIVE_MAKE)
285
286internal-library-compile: $(GNUSTEP_OBJ_DIR)/$(VERSION_LIBRARY_FILE)
287endif
288
289$(GNUSTEP_OBJ_DIR)/$(VERSION_LIBRARY_FILE): $(OBJ_FILES_TO_LINK)
290ifeq ($(OBJ_FILES_TO_LINK),)
291	$(WARNING_EMPTY_LINKING)
292endif
293	$(ECHO_LINKING)$(LIB_LINK_CMD)$(END_ECHO)
294
295#
296# Install and uninstall targets
297#
298internal-library-install_:: internal-install-dirs \
299                            internal-install-lib \
300                            shared-instance-headers-install \
301                            shared-instance-pkgconfig-install
302
303# Depend on creating all the dirs
304internal-install-dirs:: $(FINAL_LIBRARY_INSTALL_DIR) \
305                          $(DLL_INSTALLATION_DIR)
306
307# Now the rule to create each dir.  NB: Nothing gets executed if the dir
308# already exists
309$(FINAL_LIBRARY_INSTALL_DIR):
310	$(ECHO_CREATING)$(MKINSTALLDIRS) $@$(END_ECHO)
311
312$(DLL_INSTALLATION_DIR):
313	$(ECHO_CREATING)$(MKINSTALLDIRS) $@$(END_ECHO)
314
315internal-install-lib::
316	$(ECHO_INSTALLING)if [ -f $(GNUSTEP_OBJ_DIR)/$(VERSION_LIBRARY_FILE) ]; then \
317	  $(INSTALL_PROGRAM) $(GNUSTEP_OBJ_DIR)/$(VERSION_LIBRARY_FILE) \
318	                     $(FINAL_LIBRARY_INSTALL_DIR) ; \
319	  $(AFTER_INSTALL_LIBRARY_CMD) \
320	fi$(END_ECHO)
321
322ifeq ($(BUILD_DLL),yes)
323# For DLLs, also install the DLL file.
324internal-install-lib::
325	$(ECHO_INSTALLING)if [ -f $(GNUSTEP_OBJ_DIR)/$(LIB_LINK_DLL_FILE) ]; then \
326	  $(INSTALL_PROGRAM) $(GNUSTEP_OBJ_DIR)/$(LIB_LINK_DLL_FILE) \
327	                     $(DLL_INSTALLATION_DIR) ; \
328	fi$(END_ECHO)
329endif
330
331internal-library-uninstall_:: shared-instance-headers-uninstall shared-instance-pkgconfig-uninstall
332	$(ECHO_UNINSTALLING)rm -f $(FINAL_LIBRARY_INSTALL_DIR)/$(VERSION_LIBRARY_FILE) \
333	      $(FINAL_LIBRARY_INSTALL_DIR)/$(LIBRARY_FILE) \
334	      $(FINAL_LIBRARY_INSTALL_DIR)/$(SONAME_LIBRARY_FILE)$(END_ECHO)
335
336ifeq ($(BUILD_DLL),yes)
337# For DLLs, also remove the DLL file.
338internal-library-uninstall_::
339	$(ECHO_UNINSTALLING)rm -f $(DLL_INSTALLATION_DIR)/$(LIB_LINK_DLL_FILE)$(END_ECHO)
340endif
341
342#
343# Testing targets
344#
345# Put the path to the directory containing the library to be tested in
346# LD_LIBRARY_PATH for running the tests and then invoke gnustep-tests
347internal-library-check::
348ifneq ($($(GNUSTEP_INSTANCE)_TEST_DIR),)
349	@(\
350        touch $($(GNUSTEP_INSTANCE)_TEST_DIR)/TestInfo; \
351	echo "# Generated by 'make check'" \
352	  > $($(GNUSTEP_INSTANCE)_TEST_DIR)/make-check.env; \
353	echo "export LD_LIBRARY_PATH=\"$$(pwd)/$(GNUSTEP_OBJ_DIR):$(LD_LIBRARY_PATH)\"" >> $($(GNUSTEP_INSTANCE)_TEST_DIR)/make-check.env; \
354	echo "# Generated by 'make check'" \
355	  > $($(GNUSTEP_INSTANCE)_TEST_DIR)/make-check.mak; \
356	echo "ADDITIONAL_INCLUDE_DIRS += \"-I$(GNUSTEP_MAKEFILES)/TestFramework\" \"-I$$(pwd)\"" \
357	  >> $($(GNUSTEP_INSTANCE)_TEST_DIR)/make-check.mak; \
358	echo "ADDITIONAL_LDFLAGS += \"-Wl,-rpath,$$(pwd)/$(GNUSTEP_OBJ_DIR)\"" \
359	  >> $($(GNUSTEP_INSTANCE)_TEST_DIR)/make-check.mak; \
360	echo "ADDITIONAL_LIB_DIRS += \"-L$$(pwd)/$(GNUSTEP_OBJ_DIR)\"" \
361	  >> $($(GNUSTEP_INSTANCE)_TEST_DIR)/make-check.mak; \
362	echo "ADDITIONAL_TOOL_LIBS += \"-l$(LIBRARY_NAME_WITHOUT_LIB)\"" \
363	  >> $($(GNUSTEP_INSTANCE)_TEST_DIR)/make-check.mak; \
364        unset MAKEFLAGS; \
365	if [ "$(DEBUG)" = "" ]; then \
366	  gnustep-tests --verbose $($(GNUSTEP_INSTANCE)_TEST_DIR);\
367	else \
368	  gnustep-tests --debug $($(GNUSTEP_INSTANCE)_TEST_DIR);\
369	fi;\
370	)
371endif
372
373#
374# If the user makefile contains the command
375# xxx_HAS_RESOURCE_BUNDLE = yes
376# then we need to build a resource bundle for the library, and install it.
377# You can then add resources to the library, any sort of, with the usual
378# xxx_RESOURCE_FILES, xxx_LOCALIZED_RESOURCE_FILES, xxx_LANGUAGES, etc.
379# The library resource bundle (and all resources inside it) can be
380# accessed at runtime very comfortably, by using gnustep-base's
381# [NSBundle +bundleForLibrary:version:].
382#
383ifeq ($($(GNUSTEP_INSTANCE)_HAS_RESOURCE_BUNDLE),yes)
384
385# Include the rules to build resource bundles
386GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH = $(GNUSTEP_BUILD_DIR)/$(LIBRARY_NAME_WITHOUT_LIB)/Versions/$(INTERFACE_VERSION)/Resources/
387
388# We want to install gnustep-base resources into
389# GNUSTEP_LIBRARY/Libraries/gnustep-base/Versions/1.14/Resources/
390# This is similar to a framework resource directory, which might be
391# helpful in the future.
392GNUSTEP_SHARED_BUNDLE_INSTALL_NAME = Resources
393GNUSTEP_SHARED_BUNDLE_INSTALL_LOCAL_PATH = $(LIBRARY_NAME_WITHOUT_LIB)/Versions/$(INTERFACE_VERSION)
394GNUSTEP_SHARED_BUNDLE_INSTALL_PATH = $(GNUSTEP_LIBRARY)/Libraries/$(LIBRARY_NAME_WITHOUT_LIB)/Versions/$(INTERFACE_VERSION)
395
396include $(GNUSTEP_MAKEFILES)/Instance/Shared/bundle.make
397
398internal-library-all_:: shared-instance-bundle-all
399internal-library-copy_into_dir:: shared-instance-bundle-copy_into_dir
400
401$(GNUSTEP_LIBRARY)/Libraries/$(LIBRARY_NAME_WITHOUT_LIB)/Versions/$(INTERFACE_VERSION):
402	$(ECHO_CREATING)$(MKINSTALLDIRS) $@$(END_ECHO)
403
404internal-library-install_:: $(GNUSTEP_LIBRARY)/Libraries/$(LIBRARY_NAME_WITHOUT_LIB)/Versions/$(INTERFACE_VERSION) \
405                            shared-instance-bundle-install
406
407internal-library-uninstall:: shared-instance-bundle-uninstall
408
409endif
410
411include $(GNUSTEP_MAKEFILES)/Instance/Shared/strings.make
412