Skip to content

Commit

Permalink
Readme Note For Packages using Prebuilt Libs (o3de#237)
Browse files Browse the repository at this point in the history
Add documentation to help devs properly set up 3rdParty packages using
prebuilt libs
Fixes o3de#236
  • Loading branch information
AMZN-Gene authored Dec 20, 2023
2 parents 56d007c + e504d7c commit 9c1758b
Showing 1 changed file with 34 additions and 1 deletion.
35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,37 @@ Some notable examples
* Lua - this one uses a script called pull_and_build_from_git.py (in Scripts/extras) to build the package image.

See the documentation (README.md in 3p-package-scripts repo for a full description of how to author packages.)


## Setup Packages Using Prebuilt Libraries
3rdParty packages depend on prebuilt libraries. This allows 3rdParty authors to ship their libraries (.dll, .lib, .so, .a, etc) so customers do not need source code. This section covers how to author packages that depend on prebuilt libraries who also have dependencies of their own.

### The Problem
There was problems early on with O3DE 3rdParty libraries. Many 3rdParties used [CMake interface libraries](https://cmake.org/cmake/help/latest/command/add_library.html#interface-libraries). The problem is that interfaces can only control their dependencies, not the hierarchy. For example, the O3DE LibTIFF 3rdParty depends on a prebuilt libtiff.a, and libtiff.a depends on ZLib. As an interface, the old LibTIFF used `target_link_libraries` to link in libtiff.a and ZLib.

```
add_library(3rdParty::TIFF INTERFACE IMPORTED GLOBAL)
target_link_libraries(3rdParty::TIFF INTERFACE ZLIB::ZLIB "${TIFF_LIBRARY}") # No actual dependency between ZLib and TIFF and thus has undefined link order.
```

This is a flat dependency list, and so there was no way to tell that libtiff.a depends on ZLib. When CMake generates a Makefile it is free to list those libraries in any order. Depending on the order, LibTIFF could fail find ZLib definitions. As a result, a program using the LibTIFF 3rdParty would fail to link.

### The Proper Way to Declare a Prebuilt Library Dependency
Instead of using INTERFACE, use whatever library target type has been prebuilt.

- `add_library(<libname> STATIC IMPORTED)` for a static library

- `add_library(<libname> SHARED IMPORTED)` for a shared library

- `add_library(<libname> MODULE IMPORTED)` for a runtime loadable-ONLY library

Today's LibTIFF is a proper example of how to declare static library dependencies. The 3rdParty [specifies the path to the library file on disk](https://cmake.org/cmake/help/latest/prop_tgt/IMPORTED_LOCATION.html). In this case, 3rdParty::TIFF points to the prebuilt libtiff.a. The 3rdParty, now acting as a wrapper, can tack on dependencies required by the static library.

```
# Add the CMake standard 3rdParty::TIFF library. It is a static library.
add_library(3rdParty::TIFF STATIC IMPORTED GLOBAL)
set_target_properties(3rdParty::TIFF PROPERTIES IMPORTED_LOCATION "${TIFF_LIBRARY}")
target_link_libraries(3rdParty::TIFF INTERFACE ZLIB::ZLIB)
```

0 comments on commit 9c1758b

Please sign in to comment.