Skip to content

paveloom-o/swift-dynamic-library-via-cmake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Swift Dynamic Library via CMake

This repository provides an example of using CMake to build and distribute a dynamic library written in Swift on Linux systems.

Git mirrors:

Instructions

There are two targets that are installed separately:

  • The Library target that provides some code
  • The Application target that makes use of that code, while loading the Library dynamically

To build both targets, run ./scripts/rebuild_all.bash.

This is the expected result:

$ tree -a prefix
prefix
├── application
│   └── usr
│       └── bin
│           └── Application
└── library
    └── usr
        ├── include
        │   └── Library-1
        │       ├── Library.swiftdoc
        │       └── Library.swiftinterface
        └── lib64
            ├── cmake
            │   └── Library-1
            │       ├── LibraryConfig.cmake
            │       ├── LibraryConfigVersion.cmake
            │       ├── LibraryTargets.cmake
            │       └── LibraryTargets-noconfig.cmake
            └── Library-1
                ├── libLibrary.so -> libLibrary.so.1
                ├── libLibrary.so.1 -> libLibrary.so.1.0.0
                └── libLibrary.so.1.0.0

12 directories, 10 files

Here's the list of dynamic libraries the built Application depends upon:

$ objdump -p prefix/application/usr/bin/Application | grep NEEDED
  NEEDED               libLibrary.so.1
  NEEDED               libswiftSwiftOnoneSupport.so
  NEEDED               libswiftCore.so
  NEEDED               libswift_Concurrency.so
  NEEDED               libswift_StringProcessing.so
  NEEDED               libswift_RegexParser.so
  NEEDED               libc.so.6

The libLibrary.so.1 entry is the Library.

To run the application with correct LD_LIBRARY_PATH set, run ./scripts/run_application.bash:

$ ./scripts/run_application.bash
Hello there!
$ ./scripts/run_application.bash Pavel
Hello there, Pavel!

Experiment with changing the Library code and rebuilding the Library target via ./scripts/rebuild_library.bash. This should make the Application reflect the changes made without rebuilding it, assuming the changes don't break binary compatibility.

Flags

Essential swiftc flags for preparing a dynamic library for consumption:

  • -emit-module-interface: Output module interface file
  • -enable-library-evolution: Build the module to allow binary-compatible library evolution

See also:

Output files

Besides the dynamic library file (.so) and CMake package files (.cmake), other files are distributed with the library.

The .swiftinterface file is akin to a header file (.h) in C. It represents the module's public interface, with implementation code omitted. To avoid the cost of loading these files, the compiler keeps a cache of module abstract syntax trees it has seen, serialized in a binary format (.swiftmodule). You can see those in the CMake's build directories.

The .swiftdoc file is a binary file that contains serialized documentation information for Swift modules. This is where documentation strings can be pulled from by language servers (e.g., SourceKit-LSP) to aid in writing code.

See also:

About

An example of using CMake to build and distribute a dynamic library written in Swift on Linux systems

Resources

License

Stars

Watchers

Forks