Skip to content

Commit ae7671d

Browse files
author
Harlan
committed
[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 e3044cf commit ae7671d

File tree

7 files changed

+85
-3
lines changed

7 files changed

+85
-3
lines changed

include/swift/Frontend/FrontendOptions.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#ifndef SWIFT_FRONTEND_FRONTENDOPTIONS_H
1414
#define SWIFT_FRONTEND_FRONTENDOPTIONS_H
1515

16+
#include "swift/Basic/FileTypes.h"
17+
#include "swift/Basic/Version.h"
1618
#include "swift/Frontend/FrontendInputsAndOutputs.h"
1719
#include "swift/Frontend/InputFile.h"
1820
#include "llvm/ADT/Hashing.h"
@@ -261,6 +263,16 @@ class FrontendOptions {
261263
/// The install_name to use in the TBD file.
262264
std::string TBDInstallName;
263265

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+
264276
/// An enum with different modes for automatically crashing at defined times.
265277
enum class DebugCrashMode {
266278
None, ///< Don't automatically crash.

include/swift/Option/FrontendOptions.td

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

73+
def tbd_current_version
74+
: Separate<["-"], "tbd-current-version">, MetaVarName<"<version>">,
75+
HelpText<"The current_version to use in an emitted TBD file">;
76+
77+
def tbd_current_version_EQ : Joined<["-"], "tbd-current-version=">,
78+
Alias<tbd_current_version>;
79+
80+
def tbd_compatibility_version
81+
: Separate<["-"], "tbd-compatibility-version">, MetaVarName<"<version>">,
82+
HelpText<"The compatibility_version to use in an emitted TBD file">;
83+
84+
def tbd_compatibility_version_EQ : Joined<["-"], "tbd-compatibility-version=">,
85+
Alias<tbd_compatibility_version>;
86+
7387
def verify : Flag<["-"], "verify">,
7488
HelpText<"Verify diagnostics against expected-{error|warning|note} "
7589
"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
@@ -786,6 +786,8 @@ static bool writeTBDIfNeeded(CompilerInvocation &Invocation,
786786
opts.InstallName = installName;
787787
opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
788788
opts.ModuleLinkName = frontendOpts.ModuleLinkName;
789+
opts.CurrentVersion = frontendOpts.TBDCurrentVersion;
790+
opts.CompatibilityVersion = frontendOpts.TBDCompatibilityVersion;
789791

790792
return writeTBD(Instance.getMainModule(), TBDPath, opts);
791793
}

lib/TBDGen/TBDGen.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,18 @@ void TBDGenVisitor::addFirstFileSymbols() {
414414
}
415415
}
416416

417+
/// Converts a version tuple into a packed version, ignoring components beyond
418+
/// major, minor, and subminor.
419+
static tapi::internal::PackedVersion
420+
convertToPacked(version::Version &version) {
421+
// FIXME: Warn if version is greater than 3 components?
422+
unsigned major = 0, minor = 0, subminor = 0;
423+
if (version.size() > 0) major = version[0];
424+
if (version.size() > 1) minor = version[1];
425+
if (version.size() > 2) subminor = version[2];
426+
return tapi::internal::PackedVersion(major, minor, subminor);
427+
}
428+
417429
static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
418430
StringSet *symbols,
419431
llvm::raw_ostream *os,
@@ -425,10 +437,9 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
425437
tapi::internal::InterfaceFile file;
426438
file.setFileType(tapi::internal::FileType::TBD_V3);
427439
file.setInstallName(opts.InstallName);
428-
file.setCompatibilityVersion(tapi::internal::PackedVersion(1, 0, 0));
440+
file.setCurrentVersion(convertToPacked(opts.CurrentVersion));
441+
file.setCompatibilityVersion(convertToPacked(opts.CompatibilityVersion));
429442
file.setTwoLevelNamespace();
430-
// FIXME: proper version
431-
file.setCurrentVersion(tapi::internal::PackedVersion(1, 0, 0));
432443
file.setSwiftABIVersion(TAPI_SWIFT_ABI_VERSION);
433444
file.setPlatform(tapi::internal::mapToSinglePlatform(target));
434445
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)