1# -*-makefile-*- 2# application.make 3# 4# Instance Makefile rules to build GNUstep-based applications. 5# 6# Copyright (C) 1997 - 2010 Free Software Foundation, Inc. 7# 8# Author: Nicola Pero <nicola.pero@meta-innovation.com> 9# Author: Ovidiu Predescu <ovidiu@net-community.com> 10# Based on the original version by Scott Christley. 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# Applications usually link against a gui library (if available). 25ifeq ($(NEEDS_GUI),) 26 NEEDS_GUI = yes 27endif 28 29# 30# Include in the common makefile rules 31# 32ifeq ($(RULES_MAKE_LOADED),) 33 include $(GNUSTEP_MAKEFILES)/rules.make 34endif 35 36# 37# The name of the application is in the APP_NAME variable. 38# The list of application resource directories is in xxx_RESOURCE_DIRS 39# The list of application resource files is in xxx_RESOURCE_FILES 40# The list of localized resource files is in xxx_LOCALIZED_RESOURCE_FILES 41# The list of supported languages is in xxx_LANGUAGES 42# The name of the application icon (if any) is in xxx_APPLICATION_ICON 43# The name of the app class is xxx_PRINCIPAL_CLASS (defaults to NSApplication). 44# 45# If you want to insert your own entries into Info.plist (or 46# Info-gnustep.plist) you should create a xxxInfo.plist file (where 47# xxx is the application name) and gnustep-make will automatically 48# read it and merge it into Info-gnustep.plist. 49# 50 51.PHONY: internal-app-all_ \ 52 internal-app-install_ \ 53 internal-app-uninstall_ \ 54 internal-app-copy_into_dir \ 55 internal-application-build-template \ 56 internal-app-run-compile-submake \ 57 internal-app-compile 58 59# 60# Determine where to install. By default, install into GNUSTEP_APPS. 61# 62ifneq ($($(GNUSTEP_INSTANCE)_INSTALL_DIR),) 63 APP_INSTALL_DIR = $($(GNUSTEP_INSTANCE)_INSTALL_DIR) 64endif 65 66ifeq ($(APP_INSTALL_DIR),) 67 APP_INSTALL_DIR = $(GNUSTEP_APPS) 68endif 69 70APP_DIR_NAME = $(GNUSTEP_INSTANCE:=.$(APP_EXTENSION)) 71APP_DIR = $(GNUSTEP_BUILD_DIR)/$(APP_DIR_NAME) 72 73# 74# Now include the standard resource-bundle routines from Shared/bundle.make 75# 76 77ifneq ($(FOUNDATION_LIB), apple) 78 # GNUstep bundle 79 GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH = $(APP_DIR)/Resources 80 APP_INFO_PLIST_FILE = $(APP_DIR)/Resources/Info-gnustep.plist 81else 82 # OSX bundle 83 GNUSTEP_SHARED_BUNDLE_RESOURCE_PATH = $(APP_DIR)/Contents/Resources 84 APP_INFO_PLIST_FILE = $(APP_DIR)/Contents/Info.plist 85endif 86GNUSTEP_SHARED_BUNDLE_INSTALL_NAME = $(APP_DIR_NAME) 87GNUSTEP_SHARED_BUNDLE_INSTALL_LOCAL_PATH = . 88GNUSTEP_SHARED_BUNDLE_INSTALL_PATH = $(APP_INSTALL_DIR) 89include $(GNUSTEP_MAKEFILES)/Instance/Shared/bundle.make 90 91ifneq ($(FOUNDATION_LIB), apple) 92APP_FILE_NAME = $(APP_DIR_NAME)/$(GNUSTEP_TARGET_LDIR)/$(GNUSTEP_INSTANCE)$(EXEEXT) 93else 94APP_FILE_NAME = $(APP_DIR_NAME)/Contents/MacOS/$(GNUSTEP_INSTANCE)$(EXEEXT) 95endif 96 97APP_FILE = $(GNUSTEP_BUILD_DIR)/$(APP_FILE_NAME) 98 99 100# 101# Internal targets 102# 103 104# If building on Windows, also generate an import library which can be 105# used by loadable bundles to resolve symbols in the application. If 106# a loadable bundle/palette needs to use symbols in the application, 107# it just needs to link against this APP_NAME/APP_NAME.exe.a library. 108# We add .exe to the application name to account for Gorm which is 109# using the same name for the library (libGorm.dll.a) and for the 110# application (Gorm.exe). Using this terminology, just add 111# Gorm.app/Gorm.exe.a to the list of objects you link and you get it 112# working. TODO: Move this into target.make 113ifeq ($(BUILD_DLL), yes) 114 ALL_LDFLAGS += -Wl,--export-all-symbols -Wl,--out-implib,$(GNUSTEP_BUILD_DIR)/$(APP_DIR_NAME)/$(GNUSTEP_TARGET_LDIR)/$(GNUSTEP_INSTANCE).exe$(LIBEXT) 115endif 116 117# If building on MinGW, also mark the application as a 'GUI' 118# application. This prevents an ugly terminal window from being 119# automatically opened when you start your application directly by 120# double-clicking on the .exe icon in the Windows file manager. TODO: 121# Move this into target.make, but somehow make sure it is only used 122# when linking applications. 123ifeq ($(findstring mingw32, $(GNUSTEP_TARGET_OS)), mingw32) 124 ALL_LDFLAGS += -Wl,-subsystem,windows 125else ifeq ($(findstring mingw64, $(GNUSTEP_TARGET_OS)), mingw32) 126 ALL_LDFLAGS += -Wl,-subsystem,windows 127endif 128 129$(APP_FILE): $(OBJ_FILES_TO_LINK) 130ifeq ($(OBJ_FILES_TO_LINK),) 131 $(WARNING_EMPTY_LINKING) 132endif 133 $(ECHO_LINKING)$(LD) $(ALL_LDFLAGS) $(CC_LDFLAGS) -o $(LDOUT)$@ \ 134 $(OBJ_FILES_TO_LINK) $(ALL_LIB_DIRS) $(ALL_LIBS)$(END_ECHO) 135 136# 137# Compilation targets 138# 139ifeq ($(GNUSTEP_MAKE_PARALLEL_BUILDING), no) 140# Standard building 141internal-app-run-compile-submake: $(APP_FILE) 142else 143# Parallel building. The actual compilation is delegated to a 144# sub-make invocation where _GNUSTEP_MAKE_PARALLEL is set to yet. 145# That sub-make invocation will compile files in parallel. 146internal-app-run-compile-submake: 147 $(ECHO_NOTHING_RECURSIVE_MAKE)$(MAKE) -f $(MAKEFILE_NAME) --no-print-directory --no-keep-going \ 148 internal-app-compile \ 149 GNUSTEP_TYPE=$(GNUSTEP_TYPE) \ 150 GNUSTEP_INSTANCE=$(GNUSTEP_INSTANCE) \ 151 GNUSTEP_OPERATION=compile \ 152 GNUSTEP_BUILD_DIR="$(GNUSTEP_BUILD_DIR)" \ 153 _GNUSTEP_MAKE_PARALLEL=yes$(END_ECHO_RECURSIVE_MAKE) 154 155internal-app-compile: $(APP_FILE) 156endif 157 158ifeq ($(FOUNDATION_LIB), apple) 159internal-app-all_:: $(GNUSTEP_OBJ_INSTANCE_DIR) \ 160 $(OBJ_DIRS_TO_CREATE) \ 161 $(APP_DIR)/Contents/MacOS \ 162 internal-app-run-compile-submake \ 163 shared-instance-bundle-all \ 164 $(APP_INFO_PLIST_FILE) 165# If they specified Info.plist in the xxx_RESOURCE_FILES, print a 166# warning. They are supposed to provide a xxxInfo.plist which gets 167# merged with the automatically generated entries to generate 168# Info.plist. 169ifneq ($(filter Info.plist,$($(GNUSTEP_INSTANCE)_RESOURCE_FILES)),) 170 $(WARNING_INFO_PLIST) 171endif 172 173$(APP_DIR)/Contents/MacOS: 174 $(ECHO_CREATING)$(MKDIRS) $@$(END_ECHO) 175 176else 177 178internal-app-all_:: $(GNUSTEP_OBJ_INSTANCE_DIR) \ 179 $(OBJ_DIRS_TO_CREATE) \ 180 $(APP_DIR)/$(GNUSTEP_TARGET_LDIR) \ 181 internal-app-run-compile-submake \ 182 internal-application-build-template \ 183 $(APP_DIR)/Resources \ 184 $(APP_INFO_PLIST_FILE) \ 185 $(APP_DIR)/Resources/$(GNUSTEP_INSTANCE).desktop \ 186 shared-instance-bundle-all 187# If they specified Info-gnustep.plist in the xxx_RESOURCE_FILES, 188# print a warning. They are supposed to provide a xxxInfo.plist which 189# gets merged with the automatically generated entries to generate 190# Info-gnustep.plist. 191ifneq ($(filter Info-gnustep.plist,$($(GNUSTEP_INSTANCE)_RESOURCE_FILES)),) 192 $(WARNING_INFO_GNUSTEP_PLIST) 193endif 194 195$(APP_DIR)/$(GNUSTEP_TARGET_LDIR): 196 $(ECHO_CREATING)$(MKDIRS) $@$(END_ECHO) 197 198ifeq ($(GNUSTEP_IS_FLATTENED), no) 199internal-application-build-template: $(APP_DIR)/$(GNUSTEP_INSTANCE) 200 201$(APP_DIR)/$(GNUSTEP_INSTANCE): 202 $(ECHO_NOTHING)cp $(GNUSTEP_MAKEFILES)/executable.template \ 203 $(APP_DIR)/$(GNUSTEP_INSTANCE); \ 204 chmod a+x $(APP_DIR)/$(GNUSTEP_INSTANCE)$(END_ECHO) 205ifneq ($(CHOWN_TO),) 206 $(ECHO_CHOWNING)$(CHOWN) $(CHOWN_TO) $(APP_DIR)/$(GNUSTEP_INSTANCE)$(END_ECHO) 207endif 208else 209internal-application-build-template: 210 211endif 212endif 213 214PRINCIPAL_CLASS = $(strip $($(GNUSTEP_INSTANCE)_PRINCIPAL_CLASS)) 215 216ifeq ($(PRINCIPAL_CLASS),) 217 PRINCIPAL_CLASS = NSApplication 218endif 219 220APPLICATION_ICON = $($(GNUSTEP_INSTANCE)_APPLICATION_ICON) 221 222MAIN_MODEL_FILE = $(strip $(subst .gmodel,,$(subst .gorm,,$(subst .nib,,$($(GNUSTEP_INSTANCE)_MAIN_MODEL_FILE))))) 223 224MAIN_MARKUP_FILE = $(strip $(subst .gsmarkup,,$($(GNUSTEP_INSTANCE)_MAIN_MARKUP_FILE))) 225 226# We must recreate Info.plist if PRINCIPAL_CLASS and/or 227# APPLICATION_ICON and/or MAIN_MODEL_FILE and/or MAIN_MARKUP_FILE has 228# changed since last time we built Info.plist. We use 229# stamp-string.make, which will store the variables in a stamp file 230# inside GNUSTEP_STAMP_DIR, and rebuild Info.plist if 231# GNUSTEP_STAMP_STRING changes. We will also depend on xxxInfo.plist 232# if any. 233GNUSTEP_STAMP_STRING = $(PRINCIPAL_CLASS)-$(APPLICATION_ICON)-$(MAIN_MODEL_FILE)-$(MAIN_MARKUP_FILE) 234 235ifneq ($(FOUNDATION_LIB),apple) 236GNUSTEP_STAMP_DIR = $(APP_DIR) 237 238# Only for efficiency 239$(GNUSTEP_STAMP_DIR): $(APP_DIR)/$(GNUSTEP_TARGET_LDIR) 240else 241# Everything goes in $(APP_DIR)/Contents on Apple 242GNUSTEP_STAMP_DIR = $(APP_DIR)/Contents 243endif 244 245include $(GNUSTEP_MAKEFILES)/Instance/Shared/stamp-string.make 246 247# On Apple we assume that xxxInfo.plist has a '{' (and nothing else) 248# on the first line, and the rest of the file is a plain property list 249# dictionary. You must make sure your xxxInfo.plist is in this format 250# to use it on Apple. 251 252# The problem is, we need to add the automatically generated entries 253# to this custom dictionary on Apple - to do that, we generate '{' 254# followed by the custom entries, followed by xxxInfo.plist (with the 255# first line removed), or by '}'. NB: "sed '1d' filename" prints out 256# filename, except the first line. 257 258# On GNUstep we use plmerge which is much slower, but should probably 259# be safer, because as soon as xxxInfo.plist is in plist format, it 260# should always work (even if the first line is not just a '{' and 261# nothing else). 262 263ifeq ($(FOUNDATION_LIB), apple) 264$(APP_INFO_PLIST_FILE): $(GNUSTEP_STAMP_DEPEND) $(GNUSTEP_PLIST_DEPEND) 265 $(ECHO_CREATING)(echo "{"; echo ' NOTE = "Automatically generated, do not edit!";'; \ 266 echo " NSExecutable = \"$(GNUSTEP_INSTANCE)\";"; \ 267 echo " NSMainNibFile = \"$(MAIN_MODEL_FILE)\";"; \ 268 echo " GSMainMarkupFile = \"$(MAIN_MARKUP_FILE)\";"; \ 269 if [ "$(APPLICATION_ICON)" != "" ]; then \ 270 echo " CFBundleIconFile = \"$(APPLICATION_ICON)\";"; \ 271 fi; \ 272 echo " NSPrincipalClass = \"$(PRINCIPAL_CLASS)\";"; \ 273 if [ -r "$(GNUSTEP_PLIST_DEPEND)" ]; then \ 274 sed '1d' "$(GNUSTEP_PLIST_DEPEND)"; \ 275 else \ 276 echo "}"; \ 277 fi) > $@$(END_ECHO) 278else 279 280$(APP_INFO_PLIST_FILE): $(GNUSTEP_STAMP_DEPEND) $(GNUSTEP_PLIST_DEPEND) 281 $(ECHO_CREATING)(echo "{"; echo ' NOTE = "Automatically generated, do not edit!";'; \ 282 echo " NSExecutable = \"$(GNUSTEP_INSTANCE)\";"; \ 283 echo " NSMainNibFile = \"$(MAIN_MODEL_FILE)\";"; \ 284 echo " GSMainMarkupFile = \"$(MAIN_MARKUP_FILE)\";"; \ 285 if [ "$(APPLICATION_ICON)" != "" ]; then \ 286 echo " NSIcon = \"$(APPLICATION_ICON)\";"; \ 287 fi; \ 288 echo " NSPrincipalClass = \"$(PRINCIPAL_CLASS)\";"; \ 289 echo "}") >$@$(END_ECHO) 290 -$(ECHO_NOTHING)if [ -r "$(GNUSTEP_PLIST_DEPEND)" ]; then \ 291 plmerge $@ "$(GNUSTEP_PLIST_DEPEND)"; \ 292 fi$(END_ECHO) 293 294$(APP_DIR)/Resources/$(GNUSTEP_INSTANCE).desktop: $(APP_INFO_PLIST_FILE) 295 $(ECHO_CREATING)pl2link $^ $(APP_DIR)/Resources/$(GNUSTEP_INSTANCE).desktop; \ 296 chmod a+x $(APP_DIR)/Resources/$(GNUSTEP_INSTANCE).desktop$(END_ECHO) 297 298endif 299 300internal-app-copy_into_dir:: shared-instance-bundle-copy_into_dir 301 302# 303# install/uninstall targets 304# 305$(APP_INSTALL_DIR): 306 $(ECHO_CREATING)$(MKINSTALLDIRS) $@$(END_ECHO) 307 308internal-app-install_:: shared-instance-bundle-install internal-install-app-wrapper 309ifeq ($(strip),yes) 310 $(ECHO_STRIPPING)$(STRIP) $(APP_INSTALL_DIR)/$(APP_FILE_NAME)$(END_ECHO) 311endif 312 313internal-app-uninstall_:: shared-instance-bundle-uninstall internal-uninstall-app-wrapper 314 315# 316# Normally, to start up an application from the command-line you would 317# need to use something like 'openapp Gorm.app'. To make this easier 318# for end-users, we create a 'Gorm' executable inside GNUSTEP_TOOLS 319# that does just that. Your environment needs to be setup (PATH and 320# library path properly setup) to use this executable. But that's OK; 321# if your environment is not setup, then GNUSTEP_TOOLS wouldn't be 322# in your PATH and so typing 'openapp' or 'Gorm' at the command-line 323# would do nothing anyway because they wouldn't be found! ;-) 324# 325# If your environment is difficult (and you can't fix it), then you 326# should stick with 'openapp', and you may need to specify the whole 327# PATH to openapp so that it is found. Eg, 328# /usr/GNUstep/System/Tools/openapp Gorm.app. That will do a full 329# GNUstep environment setup and should work no matter what. 330# 331# If we have symlinks, we simply create a symlink from 332# GNUSTEP_TOOLS/GNUSTEP_TARGET_LDIR to APP_INSTALL_DIR/APP_FILE_NAME. 333# This is the fastest way to start up your application; it just jumps 334# to the executable file. In fact, it is much faster than openapp. 335# 336# If we don't have symlinks, we install an app-wrapper consisting of a 337# one-liner shell script that will start openapp. This will be 338# slower. 339# 340# These are the rules to create/delete this 'wrapper'. 341# 342$(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR): 343 $(ECHO_CREATING)$(MKINSTALLDIRS) $@$(END_ECHO) 344 345ifeq ($(HAS_LN_S), yes) 346# We generate a relative symlink. This makes it easier to use DESTDIR 347# and other packaging relocation tricks. 348internal-install-app-wrapper: $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR) 349 $(ECHO_NOTHING)\ 350 cd $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR); \ 351 $(RM_LN_S) $(GNUSTEP_INSTANCE); \ 352 $(LN_S_RECURSIVE) `$(REL_PATH_SCRIPT) $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR) $(APP_INSTALL_DIR)/$(APP_FILE_NAME) short` \ 353 $(GNUSTEP_INSTANCE)$(END_ECHO) 354else 355# Not sure that we can use relative paths with 'exec' in a portable 356# way. We want the stuff to work with DESTDIR, so in this case we use 357# openapp in the app wrapper. Much slower, but should work fine. 358internal-install-app-wrapper: $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR) 359 $(ECHO_NOTHING)cat $(GNUSTEP_MAKEFILES)/app-wrapper.template \ 360 | sed -e "s@GNUSTEP_INSTANCE@$(GNUSTEP_INSTANCE)@" > $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR)/$(GNUSTEP_INSTANCE); \ 361 chmod a+x $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR)/$(GNUSTEP_INSTANCE)$(END_ECHO) 362ifneq ($(CHOWN_TO),) 363 $(ECHO_CHOWNING)$(CHOWN) $(CHOWN_TO) $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR)/$(GNUSTEP_INSTANCE)$(END_ECHO) 364endif 365endif 366 367internal-uninstall-app-wrapper: 368 $(ECHO_NOTHING)$(RM) -f $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR)/$(GNUSTEP_INSTANCE)$(END_ECHO) 369 370include $(GNUSTEP_MAKEFILES)/Instance/Shared/strings.make 371