Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Development Layout for BeOS Release 3


Development Layout for BeOS Release 3


Development Layout for BeOS Release 3

This document describes how the BeOS R3 development world is layed out. The following topics are discussed:

General File System Layout

  • PPC BFS vs. Intel BFS

Header Files

  • BeBuild.h
  • The _IMPEXP_LIB Keyword

Libraries

  • Building a Driver

Exporting Symbols

  • Add-ons


General File System Layout

At the highest level of the directory structure, nothing has changed. The /boot directory is at the root of the Be file system and contains the eight "real" (nonvirtual) subdirectories that you're already familiar with:

  • beos contains most of the operating system: the kernel, the Tracker, the loadable libraries, and so on. You never touch anything in beos, nor do you add anything to it.

  • develop contains header files and "linkable" libraries. You can add your own subdirectories to develop, just don't touch anything that's already there.

  • home is where you put your own work. Note that the BeOS isn't multi-user yet; thus, home isn't divided into individual subdirectory accounts.

  • apps and preferences contain the applications that are provided by Be. You shouldn't add anything to these directories.

  • optional and demos contain images, sounds, and demonstration apps.

  • var contains temporary system files.

You can create your own /boot subdirectories, although it's recommended that you put all your own work in subdirectories of /boot/home.


PPC BFS vs. Intel BFS

Currently, the Intel version of the Be file system (bfs) is not compatible with the PPC bfs (endian trouble). This means, as an annoying example, that your Intel machine will not be able to read a floppy that was initialized on a PPC machine (and vice versa). If you want to use a floppy to transfer data between Intel and PPC, use tar.

The bfs incompatibility doesn't affect ftp: Files that are transferred through ftp will be properly converted.


Header Files

The layout and use of the header files is similar to PR2; to wit:

  • /boot/develop/headers is the "master" header file directory. It contains four subdirectories:

    be contains the header files for Be's software kits.
    cpp
    contains headers for the Metrowerks Standard Library.
    gnu
    contains a couple of GNU headers.
    posix
    contains headers for Be's POSIX implementation.

  • Currently, we don't have a policy regarding where third-party headers should go. If you're developing a library that needs to install its own headers files, you may want to install them in your own subdirectory of /boot/develop/headers. Just don't put them in the Be-defined subdirectories listed above.

  • By default, the Metrowerks' BeIDE looks for system headers in the be, cpp, and posix subdirectories. If the BeIDE somehow loses these settings, visit the Project/Access Paths portion of the Settings window and either reset to Factory Settings or add the paths yourself.

BeBuild.h

There's an important new header file in R3:

  • /boot/develop/headers/be/BeBuild.h. This file throws a compiler switch that tells your apps to import the global symbols that are exported by the Be libraries. The file is included by default when you build your app: You don't need to explicitly include this file in your source code.

The _IMPEXP_LIB Keyword

You'll also notice that each global symbol that's defined in the Be headers is marked with a _IMPEXP_LIB keyword, where LIB is the Be library in which the symbol is defined. For example (from storage/FilePanel.h):

      /* These are defined in libtracker.so. */
      extern _IMPEXP_TRACKER void run_open_panel();
      extern _IMPEXP_TRACKER void run_save_panel();

These keywords work in conjunction with the switch that's thrown by BeBuild.h. We'll return to the _IMPEXP_LIB business when we describe how to build a shared library.


Libraries

In R3, you link against one set of libraries when building your app, and the loader uses another set when it's loading:

  • The "linkable" libraries are in /boot/develop/lib/ppc.
  • The "loadable" libraries are in /boot/beos/system/lib.

Distinguishing between linkable and loadable libraries makes build management easier. In theory, you could replace the develop libraries to create different versions of the same app (a PR2 version and an R3 version, for example). Note that by default the libraries in develop are symbolic links to the libraries in system.

As in PR2, the two fundamental libraries, libbe and libroot, are included by default (when you use the BeIDE). To link against additional libraries, you have to add the libraries to your project yourself. But remember, the linkable libraries are in /boot/develop/lib/ppc. For example, if you want to link against the Tracker library, you would add /boot/develop/lib/ppc/libtracker.so to your project.

Building a Driver

If you're building a driver, you should remove the libroot.so library from your project, and add _KERNEL_.LIB and kitruntime_sta.a. The (minimally) complete driver library suite looks like this:

  • glue-noinit.a
  • init_term_dyn.o
  • start_dyn.o
  • libbe.so
  • _KERNEL_
  • kitruntime_sta.a

Exporting Symbols

If you're building a normal application or a static library (a library against which apps can statically link), you don't have to export symbols. However, if you're developing a shared library you should explicitly export every global symbol in your library by using the __declspec() macro. To export a symbol, you declare it thus...

      __declspec(dllexport) type name

...where "_declspec(dllexport)" is literal, and type and name declare the symbol. Some examples:

      __declspec(dllexport) char *some_name;
      __declspec(dllexport) void some_func() {...} 
      __declspec(dllexport) class MyView {...}

To import these symbols, an app that wants to use your library must "reverse" the declaration by replacing dllexport with dllimport:

      __declspec(dllimport) char *some_name;
      __declspec(dllimport) void some_func();
      __declspec(dllimport) class MyView;

The trouble with this system is that it implies two sets of headers, one for exporting (for building your library) and another for importing (that the library client would use). The Be libraries use macros, defined in BeBuild.h, that throw the import/export switch so the header files can be unified. For example, here's the macro for libbe:

      #if _BUILDING_be
      #define _IMPEXP_BE     __declspec(dllexport)
      #else 
      #define _IMPEXP_BE __declspec(dllimport)
      #endif

When libbe is being built, a private compiler directive defines _BUILDING_be to be non-zero, and _IMPEXP_BE exports symbols. When a developer includes BeBuild.h, the _BUILDING_be variable is set to zero, so _IMPEXP_BE is set to import symbols.

You may want to emulate this system by defining your own library macros. This implies that you have to define a compiler switch (analogous to _BUILDING_be) yourself. Set the switch to non-zero when you're building your library, and then set it to zero when you publish your headers for use by library clients.

The use of #pragma to export symbols, while supported, is discouraged. The __declspec method may be clunky, but it's the standard in the PC world.

Add-ons

Add-ons are, in general, exactly like shared libraries. However, since the symbols in an add-on are imported programmatically (through get_image_symbol()), you don't have to use the __declspec() business when loading an add-on. But you do have to __declspec(dllexport) the symbols when you're building your add-on.






BeOS Release 3

Copyright © 1998 Be, Inc. All rights reserved.

Last modified April 6, 1998.

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026