They are different. At the end of the build process though, they both need to be linked to your application/ library's other .o
and .dylib
files for it to run.
Swift modules
From Swift Serialization.md docs:
The fundamental unit of distribution for Swift code is a module. A module contains declarations as an interface for clients to write code against.
A module is a single unit of code distribution: a framework or application that’s built and shipped as a single unit and that can be imported by another module with Swift’s import keyword.
Configured by
.target()
's inPackage.swift
Cannot have submodules, so users cannot
import Module.Submodule
in Swift. Users can still import specific entities,import struct PackageModel.Manifest
, but this is a lot more verbose than importing submodules.Its interface exists as a
.swiftmodule
. What is a .swiftmodule
?. The documentation says:Conceptually, the file containing the interface for a module serves much the same purpose as the collection of C header files for a particular library.
The compiler produces this
.swiftmodule
file a lot, like a generated objective-C header, but instead of text, its a binary repesentation. It includes the bodies of inlinable functions, much like static inline functions in objective-C or header implementations in C++. However, Swift modules does include the names and types of private declarations. This allows you to refer to them in the debugger, but it does mean you shouldn't name a private variable after your deepest darkest secret. from WWDC 2018: Behind the Scenes of the Xcode Build Process- So private declarations are exposed in your
.swiftmodule
(Swift module interface).
- So private declarations are exposed in your
When importing pure Objective-C frameworks into Swift, the Swift compiler uses its built-in clang compiler to import an Objective-C header.
The importer finds declarations in the headers exposed in Clangs
.modulemap
for that framework. (again, from WWDC2018)When importing Objective-C + Swift frameworks into Swift, the Swift compiler uses the Umbrella header.
Clang modules
- Configured by
YourModuleName.modulemap
file (previouslymodule.map
, but this is deprecated), formatted like this - Can have submodules, e.g.
std
module hasstd.io
andstd.complex
. - A clang module exposes header files specified in the module map. Private details (in
.m
) are not exposed at all. - Is an improvement of the original
#include
or#import
style imports to improve the build process (This is a big topic, read the Clang module docs).
I originally posted this question and answer on Stack Overflow here. I had to do some digging and reading for this one.