New System Directory Layout
Mac OS X Server and Yellow Box for Windows
Copyright (c) 1998, Apple Computer, Inc.
All rights reserved.

OpenStep and Rhapsody DR1 had a number of directories whose path started with /Next.  The system directory layout has been changed to eliminate references to Next and to be more consistent and uniform.  See the section New System Directory Layout below.  Also refer to the on-line help information accessible in ProjectBuilder.

This directory contains tools to help find references to the old directory layout and convert project files appropriately.

Before you can build an old OpenStep or Rhapsody DR1 project on this system, the project must be converted to the new directory layout.  This involves the following steps:

1)  Copy the old project to this system.

2)  Find references to the old directory layout throughout your project.  See the section Finding Old Directory References In a Project Hierarchy below.

3)  Convert your project Makefiles and PB.project files to the new layout.  See the section Converting Project Files to the New Directory Layout below.

4)  Eliminate any source code references to the new locations using the new Foundation directory API.  See the section Foundation's System Directory Access API's below.

5)  Compile and test your program.

New System Directory Layout

Mac OS X Server:

New Directory	Old Directory
/Network -- (typical "sitewide" mount points)
	/Administration	was /LocalAdmin
	/Applications	was /LocalApps
	/Developer	
	/Documentation	was /LocalLibrary/Documentation
	/Library	was /LocalLibrary
	/Users

/Local -- (Local hard disk storage)
	/Administration
	/Applications			
	/Developer	was /LocalDeveloper
	/Documentation
	/Library
	/Public	fully readable and writable by all users
	/Users
		/Administrator	was /root
	
/System -- (Shipped with the system, read-only for most users)
	/Administration	was /NextAdmin
	/Applications	was /NextApps
	/Demos	was /NextDeveloper/Demos
	/Developer	was /NextDeveloper
	/Documentation	was /NextLibrary/Documentation
	/Installation	was /NextCD
	/Library	was /NextLibrary
	     /Printers	(hidden by default), was /usr/lib/NextPrinter
	     /CoreServices	(hidden by default), was /usr/lib/NextStep

Windows:

$(NEXT_ROOT)/Demos	was $(NEXT_ROOT)/NextDemos
$(NEXT_ROOT)/Developer	was $(NEXT_ROOT)/NextDeveloper
$(NEXT_ROOT)/Documentation 	was $(NEXT_ROOT)/NextLibrary/Documentation
$(NEXT_ROOT)/Library	was $(NEXT_ROOT)/NextLibrary
$(NEXT_ROOT)/Local/Developer	was $(NEXT_ROOT)/LocalDeveloper

PDO Platforms:

The new directory layout on PDO platforms is the same as on Windows platforms.

Finding Old Directory References In a Project Hierarchy

SearchForOldDirs is a script to look for hardcoded references to the old directory structure in your project.  To use it, do the following.

On Mac OS X Server:

1)  Open a Terminal window, by choosing the Terminal menu item from the Apple menu at the left of the menu bar.  Since long command strings are given in this document, you may find it convenient to copy those strings from this document and paste them into the Terminal window.

2)  cd to the top-level directory of the project hierarchy you want to search.

3)  Run the following command:

  /System/Developer/Makefiles/Conversion/DirectoryLayout/SearchForOldDirs -v

or on Windows:

1)  Open a Bourne Shell window, by invoking the Programs -> Apple YellowBox -> Bourne Shell (or Programs -> WebObjects -> Bourne Shell) menu item from the Windows Start menu.  The Bourne Shell runs sh.exe by default, so it understands forward slashes as separators in path names, and forward slashes are used in this document.  Since long command strings are given in this document, you may find it convenient to copy those strings from this document and paste them into the Bourne Shell.  To paste in the Bourne Shell, click in the icon at the left of the Bourne Shell window title bar, and select the Edit -> Paste menu item.

2)  cd to the top-level directory of the project hierarchy you want to search.

3)  Run the following command:

  $NEXT_ROOT/Developer/Makefiles/Conversion/DirectoryLayout/SearchForOldDirs -v

With the "-v" argument, this script shows all the matching lines in all files in the project hierarchy that might refer to the old directory layout.  Note that you will get garbage for executables.  To show just the names of files whose contents may refer to old directory names, omit the "-v".

Converting Project Makefiles to the New Directory Layout

In OpenStep and Rhapsody DR1, every project and subproject had references to the old directory layout hard-coded in at least two files ± PB.project and Makefile (which ProjectBuilder generates from info in PB.project).  All of these files will need to be changed for a project to successfully build on later releases.

This section describes:

	± the conversion tool for changing your Makefiles and PB.project
	± the process of using that conversion tool
	± new variables defined in ProjectBuilder's global makefiles for referencing system directories
	± changes to gnumake to define where to find the global makefiles

ConvertMakefilesToNewDirs ± The Makefile Conversion Script

ConvertMakefilesToNewDirs is a script to automate the process of changing project files to remove hard-coded references to system directories and replace them with references to new variables now defined by ProjectBuilder's global makefiles.  This script can be found in:

Mac OS X Server:  /System/Developer/Makefiles/Conversion/DirectoryLayout/ConvertMakefilesToNewDirs
Windows:  $NEXT_ROOT/Developer/Makefiles/Conversion/DirectoryLayout/ConvertMakefilesToNewDirs

Usage:  ConvertMakefilesToNewDirs [-n] [-r] [--help] file ...
	-r, --recursive		Find and fix all makefiles and PB.project files, recursing through subdirectories.	-n, --just-print	Don't actually run any commands; just print them.
	--help				Print usage message.

The only files this script will change are Makefile, Makefile.preamble, Makefile.postamble, PB.project, and Info.table.  (Info.table is a file used in custom project type definitions.)  You can give it other file names as well, but they will be ignored.

To change all Makefiles and PB.project files in a project and its subprojects, run the following:

On Mac OS X Server, in a Terminal window, run:

	cd <project top-level directory>
	/System/Developer/Makefiles/Conversion/DirectoryLayout/ConvertMakefilesToNewDirs -r

or on Windows, in a Bourne Shell window, run:

	cd <project top-level directory>
	$NEXT_ROOT/Developer/Makefiles/Conversion/DirectoryLayout/ConvertMakefilesToNewDirs -r

Steps Involved in Converting a Project's Makefiles and PB.project

To convert an old project to fix problems in Makefile, Makefile.preamble, Makefile.postamble, and PB.project in the top-level directory and all subprojects, do the following:

1)  cd <project top-level directory>

2)  First verify that a valid list of files will be converted, by running (use $NEXT_ROOT instead of /System in a Bourne Shell window on Windows):

	/System/Developer/Makefiles/Conversion/DirectoryLayout/ConvertMakefilesToNewDirs -n -r

3)  To actually convert the Makefiles and PB.project files, remove the -n flag as follows:

	/System/Developer/Makefiles/Conversion/DirectoryLayout/ConvertMakefilesToNewDirs -r

4)  Verify that the results are valid by examining the files.  The original version of any changed files will be retained as <file>~  (twiddle appended).  You can compare them in FileMerge as follows in each directory and subdirectory:

		opendiff Makefile~ Makefile
		opendiff Makefile.preamble~ Makefile.preamble
		opendiff Makefile.postamble~ Makefile.postamble
		opendiff PB.project~ PB.project

5)  Open the project in ProjectBuilder to ensure that the PB.project file can be parsed properly.

6)  Fix any other references the project makes to the old directory layout.  Use the new API in Foundation to find system directories, rather than hard-coding them.  See the section Foundation's System Directory Access API below.

7)  Build the project and test it.

Makefile Variables for Refering to the System Directories

The global pb_makefiles and project makefiles now set the variables listed below for you to use in your Makefile.preamble and Makefile.postamble files as necessary.  The ConvertMakefilesToNewDirs script finds references to old hard-coded paths, and changes them to appropriate references to these make variables.  In PB.project files (which are ASCII-encoded plists), the conversion script quotes these variable references appropriately so the PB.project files can still be parsed by ProjectBuilder and other tools.  

VARIABLE					Mac OS X Server SETTING	WINDOWS SETTING
SYSTEM_APPS_DIR				/System/Applications		/Demos
SYSTEM_ADMIN_APPS_DIR			/System/Administration	/Demos
SYSTEM_DEMOS_DIR				/System/Demos			/Demos
SYSTEM_DEVELOPER_DIR			/System/Developer		/Developer
SYSTEM_DEVELOPER_APPS_DIR		/System/Developer/Applications	/Developer/Applications
SYSTEM_LIBRARY_DIR				/System/Library			/Library
SYSTEM_CORE_SERVICES_DIR		/System/Library/CoreServices	/Library/CoreServices
SYSTEM_DOCUMENTATION_DIR		/System/Documentation		/Documentation
SYSTEM_LIBRARY_EXECUTABLES_DIR	 no value				/Library/Executables
SYSTEM_DEVELOPER_EXECUTABLES_DIR	 no value				/Developer/Executables
LOCAL_DEVELOPER_DIR			/Local/Developer			/Local/Developer
LOCAL_DEVELOPER_EXECUTABLES_DIR	 no value				/Local/Developer/Executables
USER_APPS_DIR					$(HOME)/Applications		$(HOME)/Applications
USER_LIBRARY_DIR				$(HOME)/Library			$(HOME)/Library

Changes to gnumake to Find the Global Makefiles at Build Time

ProjectBuilder generates and maintains the Makefile for each project, based on information in PB.project, unless it is a Legacy project.  ProjectBuilder currently generates a line of the following form into the PB.project file and the Makefile, saying where to find the global makefiles:

	MAKEFILEDIR = $(NEXT_ROOT)/NextDeveloper/Makefiles/pb_makefiles

With the new directory layout, ProjectBuilder's global Makefiles are at a different path on Windows than on Mac OS X Server.  So, it isn't possible to have each project's Makefile use a single path to reference the global makefiles.  To keep each project's Makefile simple, gnumake has been changed to resolve this issue.

/bin/gnumake now internally defines a new default variable, MAKEFILEPATH.  This gets set as follows:

Mac OS X Server:	MAKEFILEPATH = /System/Developer/Makefiles
Windows:			MAKEFILEPATH = $(NEXT_ROOT)/Developer/Makefiles

Both NEXT_ROOT and MAKEFILEPATH itself can be overridden with environment variables, command line arguments to make, or defines in makefiles.

The ConvertMakefilesToNewDirs script will automatically change the MAKEFILEDIR setting in your PB.project and Makefile.  For non-Legacy projects, you'll should get one of the following lines, depending on which set of global makefiles you use.

	MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles	(preferred)
	MAKEFILEDIR = $(MAKEFILEPATH)/project		(old ± please migrate to pb_makefiles)

Foundation's System Directory Access API

Once you have converted your PB.project files and your Makefiles, you may also need to convert any hard-coded directory path references in your code.  To get an ordered list of directories where certain type of items can be found or installed, call the following Foundation function declared in <Foundation/NSPathUtilities.h>:

NSArray *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, 
                                             NSSearchPathDomainMask domainMask, 
                                             BOOL expandTilde);

The directory argument specifies what type of items to be looking for; values are one of the following:

    NSApplicationDirectory = 1,	// supported applications (Applications)
    NSDemoApplicationDirectory,	// unsupported applications, demonstration versions (Demos)
    NSDeveloperApplicationDirectory,	// developer applications (Developer/Applications)
    NSAdminApplicationDirectory,	// system and network administration applications (Administration)
    NSLibraryDirectory, 	// various user-visible documentation, support, and configuration files, resources (Library)
    NSDeveloperDirectory,	// developer resources (Developer)
    NSUserDirectory,	// user home directories (Users)
    NSDocumentationDirectory,	// documentation (Documentation)
    NSAllApplicationsDirectory = 100,	// all directories where applications can occur
    NSAllLibrariesDirectory = 101	// all directories where resources can occur

The domain argument specifies the domains to look in. To get back a search path that contains directories from different domains (but ordered from first to look in to last), simply OR together multiple domains; or use NSAllDomainsMask:

    NSUserDomainMask = 1,	// user's home directory --- place to install user's personal items (~)
    NSLocalDomainMask = 2,	// local to the current machine --- place to install items available to everyone on this machine (/Local)
    NSNetworkDomainMask = 4, 	// publically available location in the local area network --- place to install items available on the network (/Network)
    NSSystemDomainMask = 8,	// provided by Apple, unmodifiable (/System)
    NSAllDomainsMask = 0x0ffff	// all domains: all of the above and future items

The expandTilde argument specifies whether the user's home directory should be denoted as "~" or expanded. 

NOTE:  $NEXT_ROOT is prepended to the return values where needed. This is interesting on Windows and PDO, where NEXT_ROOT is defined.

NOTE: On some platforms, some combinations of arguments might return empty arrays. For instance, we currently do not deal with the "network" domain on Windows. Callers should always check to make sure there is at least one item in the array before accessing the item. Also note that it's sometimes possible to get multiple values even when you expected only one.  In that case the first one is the best one to use.

Examples:

  NSSearchPathForDirectoriesInDomains(
		NSLibraryDirectory, NSAllDomainsMask, YES) 
gives:
		(/Local/Users/user/Library,
		 /Local/Library,
		 /Network/Library,
		 /System/Library)

  NSSearchPathForDirectoriesInDomains(
		NSApplicationDirectory, NSUserDomainsMask, NO)
gives:
		(~/Applications)

  NSSearchPathForDirectoriesInDomains(
		NSAllApplicationsDirectory,NSSystemDomainsMask, NO)
gives:
		(/System/Applications,
		 /System/Administration,
		 /System/Developer/Applications,
		 /System/Demos)

On Windows:

  NSSearchPathForDirectoriesInDomains(
		NSLibraryDirectory, NSAllDomainsMask, YES) 
gives:
		(D:/user/Library,
		 C:/Apple/Local/Library,
		 C:/Apple/Library)