What is the difference between a clang (C++, Objective-C, C) module and a Swift module?
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.Submodulein 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
.swiftmodulefile 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
.modulemapfor 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.modulemapfile (previouslymodule.map, but this is deprecated), formatted like this - Can have submodules, e.g.
stdmodule hasstd.ioandstd.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
#includeor#importstyle 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.