Skip to content

Commit 7318efe

Browse files
author
Harlan
authored
[TBDGen] Allow user-provided dylib version flags (#18716)
* [TBDGen] Allow user-provided dylib version flags This patch adds two frontend arguments, -tbd-compatibility-version and -tbd-current-version, both of which accept SemVer versions. These will show up in the generated TBD file for a given module as current-version: 2.7 compatibility-version: 2.0 These flags both default to `1.0.0`. * Reword some comments * Add test for invalid version string * Expand on comments for TBD flags
1 parent efe5661 commit 7318efe

File tree

7 files changed

+84
-3
lines changed

7 files changed

+84
-3
lines changed

include/swift/Frontend/FrontendOptions.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define SWIFT_FRONTEND_FRONTENDOPTIONS_H
1515

1616
#include "swift/Basic/FileTypes.h"
17+
#include "swift/Basic/Version.h"
1718
#include "swift/Frontend/FrontendInputsAndOutputs.h"
1819
#include "swift/Frontend/InputFile.h"
1920
#include "llvm/ADT/Hashing.h"
@@ -262,6 +263,16 @@ class FrontendOptions {
262263
/// The install_name to use in the TBD file.
263264
std::string TBDInstallName;
264265

266+
// The current project version to use in the generated TBD file. Defaults
267+
// to 1, which matches the default if the DYLIB_CURRENT_VERSION build setting
268+
// is not set.
269+
version::Version TBDCurrentVersion = {1, 0, 0};
270+
271+
// The dylib compatibility-version to use in the generated TBD file. Defaults
272+
// to 1, which matches the default if the DYLIB_COMPATIBILITY_VERSION build
273+
// setting is not set.
274+
version::Version TBDCompatibilityVersion = {1, 0, 0};
275+
265276
/// An enum with different modes for automatically crashing at defined times.
266277
enum class DebugCrashMode {
267278
None, ///< Don't automatically crash.

include/swift/Option/FrontendOptions.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ def tbd_install_name
7474
def tbd_install_name_EQ : Joined<["-"], "tbd-install_name=">,
7575
Alias<tbd_install_name>;
7676

77+
def tbd_current_version
78+
: Separate<["-"], "tbd-current-version">, MetaVarName<"<version>">,
79+
HelpText<"The current_version to use in an emitted TBD file">;
80+
81+
def tbd_current_version_EQ : Joined<["-"], "tbd-current-version=">,
82+
Alias<tbd_current_version>;
83+
84+
def tbd_compatibility_version
85+
: Separate<["-"], "tbd-compatibility-version">, MetaVarName<"<version>">,
86+
HelpText<"The compatibility_version to use in an emitted TBD file">;
87+
88+
def tbd_compatibility_version_EQ : Joined<["-"], "tbd-compatibility-version=">,
89+
Alias<tbd_compatibility_version>;
90+
7791
def verify : Flag<["-"], "verify">,
7892
HelpText<"Verify diagnostics against expected-{error|warning|note} "
7993
"annotations">;

include/swift/TBDGen/TBDGen.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "llvm/ADT/StringRef.h"
1616
#include "llvm/ADT/StringSet.h"
17+
#include "swift/Basic/Version.h"
1718

1819
namespace llvm {
1920
class raw_ostream;
@@ -35,6 +36,10 @@ struct TBDGenOptions {
3536
llvm::StringRef InstallName;
3637
/// \brief The module link name (for force loading).
3738
llvm::StringRef ModuleLinkName;
39+
/// \brief The current project version.
40+
version::Version CurrentVersion;
41+
/// \brief The dylib compatibility version.
42+
version::Version CompatibilityVersion;
3843
};
3944

4045
void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,18 @@ void ArgsToFrontendOptionsConverter::computeTBDOptions() {
217217
if (const Arg *A = Args.getLastArg(OPT_tbd_install_name)) {
218218
Opts.TBDInstallName = A->getValue();
219219
}
220+
if (const Arg *A = Args.getLastArg(OPT_tbd_compatibility_version)) {
221+
if (auto vers = version::Version::parseVersionString(
222+
A->getValue(), SourceLoc(), &Diags)) {
223+
Opts.TBDCompatibilityVersion = *vers;
224+
}
225+
}
226+
if (const Arg *A = Args.getLastArg(OPT_tbd_current_version)) {
227+
if (auto vers = version::Version::parseVersionString(
228+
A->getValue(), SourceLoc(), &Diags)) {
229+
Opts.TBDCurrentVersion = *vers;
230+
}
231+
}
220232
}
221233

222234
void ArgsToFrontendOptionsConverter::setUnsignedIntegerArgument(

lib/FrontendTool/FrontendTool.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,8 @@ static bool writeTBDIfNeeded(CompilerInvocation &Invocation,
801801
opts.InstallName = installName;
802802
opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
803803
opts.ModuleLinkName = frontendOpts.ModuleLinkName;
804+
opts.CurrentVersion = frontendOpts.TBDCurrentVersion;
805+
opts.CompatibilityVersion = frontendOpts.TBDCompatibilityVersion;
804806

805807
return writeTBD(Instance.getMainModule(), TBDPath, opts);
806808
}

lib/TBDGen/TBDGen.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,18 @@ void TBDGenVisitor::addFirstFileSymbols() {
411411
}
412412
}
413413

414+
/// Converts a version tuple into a packed version, ignoring components beyond
415+
/// major, minor, and subminor.
416+
static tapi::internal::PackedVersion
417+
convertToPacked(version::Version &version) {
418+
// FIXME: Warn if version is greater than 3 components?
419+
unsigned major = 0, minor = 0, subminor = 0;
420+
if (version.size() > 0) major = version[0];
421+
if (version.size() > 1) minor = version[1];
422+
if (version.size() > 2) subminor = version[2];
423+
return tapi::internal::PackedVersion(major, minor, subminor);
424+
}
425+
414426
static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
415427
StringSet *symbols,
416428
llvm::raw_ostream *os,
@@ -422,10 +434,9 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
422434
tapi::internal::InterfaceFile file;
423435
file.setFileType(tapi::internal::FileType::TBD_V3);
424436
file.setInstallName(opts.InstallName);
425-
file.setCompatibilityVersion(tapi::internal::PackedVersion(1, 0, 0));
437+
file.setCurrentVersion(convertToPacked(opts.CurrentVersion));
438+
file.setCompatibilityVersion(convertToPacked(opts.CompatibilityVersion));
426439
file.setTwoLevelNamespace();
427-
// FIXME: proper version
428-
file.setCurrentVersion(tapi::internal::PackedVersion(1, 0, 0));
429440
file.setSwiftABIVersion(TAPI_SWIFT_ABI_VERSION);
430441
file.setPlatform(tapi::internal::mapToSinglePlatform(target));
431442
auto arch = tapi::internal::getArchType(target.getArchName());

test/TBD/dylib-version.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-ir -o /dev/null %s -tbd-current-version 2.0.3 -tbd-compatibility-version 1.7 -emit-tbd -emit-tbd-path %t/both_provided.tbd
3+
// RUN: %target-swift-frontend -emit-ir -o /dev/null %s -tbd-current-version 2.0 -emit-tbd -emit-tbd-path %t/only_current_provided.tbd
4+
// RUN: %target-swift-frontend -emit-ir -o /dev/null %s -tbd-compatibility-version 2 -emit-tbd -emit-tbd-path %t/only_compat_provided.tbd
5+
// RUN: not %target-swift-frontend -emit-ir -o /dev/null %s -tbd-compatibility-version not_a_version_string -emit-tbd -emit-tbd-path /dev/null 2>&1 | %FileCheck %s --check-prefix BOGUS
6+
7+
// RUN: %FileCheck %s --check-prefix BOTH < %t/both_provided.tbd
8+
// RUN: %FileCheck %s --check-prefix CURRENT < %t/only_current_provided.tbd
9+
// RUN: %FileCheck %s --check-prefix COMPAT < %t/only_compat_provided.tbd
10+
11+
// BOTH: current-version: 2.0.3
12+
// BOTH: compatibility-version: 1.7
13+
// CURRENT: current-version: 2
14+
15+
// Compatibility version defaults to 1 if not present in TBD file, and
16+
// tapi does not write field if compatibility version is 1
17+
18+
// CURRENT-NOT: compatibility-version: 1
19+
20+
// COMPAT: compatibility-version: 2
21+
22+
// Same as above -- current version defaults to 1 and is not present in
23+
// emitted TBD file if it's 1.
24+
// COMPAT-NOT: current-version: 1
25+
26+
// BOGUS: version component contains non-numeric characters

0 commit comments

Comments
 (0)