@@ -1190,11 +1190,52 @@ getSectionMagicArch(const llvm::Triple &Triple) {
1190
1190
}
1191
1191
}
1192
1192
1193
+ std::string toolchains::GenericUnix::getDefaultLinker () const {
1194
+ switch (getTriple ().getArch ()) {
1195
+ case llvm::Triple::arm:
1196
+ case llvm::Triple::armeb:
1197
+ case llvm::Triple::thumb:
1198
+ case llvm::Triple::thumbeb:
1199
+ // BFD linker has issues wrt relocation of the protocol conformance
1200
+ // section on these targets, it also generates COPY relocations for
1201
+ // final executables, as such, unless specified, we default to gold
1202
+ // linker.
1203
+ return " gold" ;
1204
+ default :
1205
+ // Otherwise, use the default BFD linker.
1206
+ return " " ;
1207
+ }
1208
+ }
1209
+
1210
+ bool toolchains::GenericUnix::shouldProvideRPathToLinker () const {
1211
+ return true ;
1212
+ }
1213
+
1214
+ bool toolchains::GenericUnix::shouldSpecifyTargetTripleToLinker () const {
1215
+ return true ;
1216
+ }
1217
+
1218
+ std::string toolchains::GenericUnix::getPreInputObjectPath (
1219
+ StringRef RuntimeLibraryPath) const {
1220
+ // On Linux and FreeBSD (really, ELF binaries) we need to add objects
1221
+ // to provide markers and size for the metadata sections.
1222
+ SmallString<128 > PreInputObjectPath = RuntimeLibraryPath;
1223
+ llvm::sys::path::append (PreInputObjectPath, getSectionMagicArch (getTriple ()));
1224
+ llvm::sys::path::append (PreInputObjectPath, " swift_begin.o" );
1225
+ return PreInputObjectPath.str ();
1226
+ }
1227
+
1228
+ std::string toolchains::GenericUnix::getPostInputObjectPath (
1229
+ StringRef RuntimeLibraryPath) const {
1230
+ SmallString<128 > PostInputObjectPath = RuntimeLibraryPath;
1231
+ llvm::sys::path::append (PostInputObjectPath, getSectionMagicArch (getTriple ()));
1232
+ llvm::sys::path::append (PostInputObjectPath, " swift_end.o" );
1233
+ return PostInputObjectPath.str ();
1234
+ }
1235
+
1193
1236
ToolChain::InvocationInfo
1194
1237
toolchains::GenericUnix::constructInvocation (const LinkJobAction &job,
1195
1238
const JobContext &context) const {
1196
- const Driver &D = getDriver ();
1197
-
1198
1239
assert (context.Output .getPrimaryOutputType () == types::TY_Image &&
1199
1240
" Invalid linker output type." );
1200
1241
@@ -1212,52 +1253,38 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
1212
1253
}
1213
1254
1214
1255
// Select the linker to use
1215
- StringRef Linker;
1216
-
1256
+ std::string Linker;
1217
1257
if (const Arg *A = context.Args .getLastArg (options::OPT_use_ld)) {
1218
1258
Linker = A->getValue ();
1219
1259
} else {
1220
- switch (getTriple ().getArch ()) {
1221
- default :
1222
- break ;
1223
- case llvm::Triple::arm:
1224
- case llvm::Triple::armeb:
1225
- case llvm::Triple::thumb:
1226
- case llvm::Triple::thumbeb:
1227
- // BFD linker has issues wrt relocation of the protocol conformance
1228
- // section on these targets, it also generates COPY relocations for
1229
- // final executables, as such, unless specified, we default to gold
1230
- // linker.
1231
- Linker = " gold" ;
1232
- }
1260
+ Linker = getDefaultLinker ();
1233
1261
}
1234
-
1235
1262
if (!Linker.empty ()) {
1236
1263
Arguments.push_back (context.Args .MakeArgString (" -fuse-ld=" + Linker));
1237
1264
}
1238
1265
1266
+ // Explicitly pass the target to the linker
1267
+ if (shouldSpecifyTargetTripleToLinker ()) {
1268
+ Arguments.push_back (context.Args .MakeArgString (" --target=" + getTriple ().str ()));
1269
+ }
1270
+
1239
1271
// Add the runtime library link path, which is platform-specific and found
1240
1272
// relative to the compiler.
1241
- // FIXME: Duplicated from CompilerInvocation, but in theory the runtime
1242
- // library link path and the standard library module import path don't
1243
- // need to be the same.
1244
1273
llvm::SmallString<128 > RuntimeLibPath;
1245
-
1246
- if (const Arg *A = context. Args . getLastArg (options::OPT_resource_dir )) {
1247
- RuntimeLibPath = A-> getValue ();
1248
- } else {
1249
- RuntimeLibPath = D. getSwiftProgramPath ( );
1250
- llvm::sys::path::remove_filename (RuntimeLibPath); // remove /swift
1251
- llvm::sys::path::remove_filename (RuntimeLibPath); // remove /bin
1252
- llvm::sys::path::append ( RuntimeLibPath, " lib " , " swift " );
1274
+ getRuntimeLibraryPath (RuntimeLibPath, context. Args , * this );
1275
+ if (shouldProvideRPathToLinker ( )) {
1276
+ // FIXME: We probably shouldn't be adding an rpath here unless we know
1277
+ // ahead of time the standard library won't be copied.
1278
+ Arguments. push_back ( " -Xlinker " );
1279
+ Arguments. push_back ( " -rpath " );
1280
+ Arguments. push_back ( " -Xlinker " );
1281
+ Arguments. push_back (context. Args . MakeArgString ( RuntimeLibPath) );
1253
1282
}
1254
- llvm::sys::path::append (RuntimeLibPath,
1255
- getPlatformNameForTriple (getTriple ()));
1256
1283
1257
- // On Linux and FreeBSD (really, ELF binaries) we need to add objects
1258
- // to provide markers and size for the metadata sections.
1259
- Arguments.push_back (context.Args .MakeArgString (
1260
- Twine (RuntimeLibPath) + " / " + getSectionMagicArch ( getTriple ()) + " /swift_begin.o " ));
1284
+ auto PreInputObjectPath = getPreInputObjectPath (RuntimeLibPath);
1285
+ if (!PreInputObjectPath. empty ()) {
1286
+ Arguments.push_back (context.Args .MakeArgString (PreInputObjectPath));
1287
+ }
1261
1288
addPrimaryInputsOfType (Arguments, context.Inputs , types::TY_Object);
1262
1289
addInputsOfType (Arguments, context.InputActions , types::TY_Object);
1263
1290
@@ -1273,9 +1300,6 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
1273
1300
Arguments.push_back (" -L" );
1274
1301
Arguments.push_back (context.Args .MakeArgString (RuntimeLibPath));
1275
1302
1276
- // Explicitly pass the target to the linker
1277
- Arguments.push_back (context.Args .MakeArgString (" --target=" + getTriple ().str ()));
1278
-
1279
1303
if (context.Args .hasArg (options::OPT_profile_generate)) {
1280
1304
SmallString<128 > LibProfile (RuntimeLibPath);
1281
1305
llvm::sys::path::remove_filename (LibProfile); // remove platform name
@@ -1288,13 +1312,6 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
1288
1312
Arguments.push_back (context.Args .MakeArgString (LibProfile));
1289
1313
}
1290
1314
1291
- // FIXME: We probably shouldn't be adding an rpath here unless we know ahead
1292
- // of time the standard library won't be copied.
1293
- Arguments.push_back (" -Xlinker" );
1294
- Arguments.push_back (" -rpath" );
1295
- Arguments.push_back (" -Xlinker" );
1296
- Arguments.push_back (context.Args .MakeArgString (RuntimeLibPath));
1297
-
1298
1315
// Always add the stdlib
1299
1316
Arguments.push_back (" -lswiftCore" );
1300
1317
@@ -1306,10 +1323,12 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
1306
1323
Twine (" @" ) + OutputInfo.getPrimaryOutputFilename ()));
1307
1324
}
1308
1325
1309
- // It is important that swift_end.o be the last object on the link line
1310
- // therefore, it is included just before the output filename.
1311
- Arguments.push_back (context.Args .MakeArgString (
1312
- Twine (RuntimeLibPath) + " /" + getSectionMagicArch (getTriple ()) + " /swift_end.o" ));
1326
+ // Just before the output option, allow GenericUnix toolchains to add
1327
+ // additional inputs.
1328
+ auto PostInputObjectPath = getPostInputObjectPath (RuntimeLibPath);
1329
+ if (!PostInputObjectPath.empty ()) {
1330
+ Arguments.push_back (context.Args .MakeArgString (PostInputObjectPath));
1331
+ }
1313
1332
1314
1333
// This should be the last option, for convenience in checking output.
1315
1334
Arguments.push_back (" -o" );
@@ -1318,121 +1337,23 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
1318
1337
return {" clang++" , Arguments};
1319
1338
}
1320
1339
1321
- ToolChain::InvocationInfo
1322
- toolchains::Windows::constructInvocation (const InterpretJobAction &job,
1323
- const JobContext &context) const {
1324
- InvocationInfo II = ToolChain::constructInvocation (job, context);
1325
-
1326
- SmallString<128 > runtimeLibraryPath;
1327
- getRuntimeLibraryPath (runtimeLibraryPath, context.Args , *this );
1328
-
1329
- addPathEnvironmentVariableIfNeeded (II.ExtraEnvironment , " LD_LIBRARY_PATH" ,
1330
- " :" , options::OPT_L, context.Args ,
1331
- runtimeLibraryPath);
1332
- return II;
1340
+ std::string toolchains::Cygwin::getDefaultLinker () const {
1341
+ // Cygwin uses the default BFD linker, even on ARM.
1342
+ return " " ;
1333
1343
}
1334
1344
1335
- ToolChain::InvocationInfo
1336
- toolchains::Windows::constructInvocation (const AutolinkExtractJobAction &job,
1337
- const JobContext &context) const {
1338
- assert (context.Output .getPrimaryOutputType () == types::TY_AutolinkFile);
1339
-
1340
- ArgStringList Arguments;
1341
- addPrimaryInputsOfType (Arguments, context.Inputs , types::TY_Object);
1342
- addInputsOfType (Arguments, context.InputActions , types::TY_Object);
1343
-
1344
- Arguments.push_back (" -o" );
1345
- Arguments.push_back (
1346
- context.Args .MakeArgString (context.Output .getPrimaryOutputFilename ()));
1347
-
1348
- return {" swift-autolink-extract" , Arguments};
1345
+ bool toolchains::Cygwin::shouldSpecifyTargetTripleToLinker () const {
1346
+ return false ;
1349
1347
}
1350
1348
1351
- ToolChain::InvocationInfo
1352
- toolchains::Windows::constructInvocation (const LinkJobAction &job,
1353
- const JobContext &context) const {
1354
- const Driver &D = getDriver ();
1355
-
1356
- assert (context.Output .getPrimaryOutputType () == types::TY_Image &&
1357
- " Invalid linker output type." );
1358
-
1359
- ArgStringList Arguments;
1360
-
1361
- switch (job.getKind ()) {
1362
- case LinkKind::None:
1363
- llvm_unreachable (" invalid link kind" );
1364
- case LinkKind::Executable:
1365
- // Default case, nothing extra needed
1366
- break ;
1367
- case LinkKind::DynamicLibrary:
1368
- Arguments.push_back (" -shared" );
1369
- break ;
1370
- }
1371
-
1372
- addPrimaryInputsOfType (Arguments, context.Inputs , types::TY_Object);
1373
- addInputsOfType (Arguments, context.InputActions , types::TY_Object);
1374
-
1375
- context.Args .AddAllArgs (Arguments, options::OPT_Xlinker);
1376
- context.Args .AddAllArgs (Arguments, options::OPT_linker_option_Group);
1377
- context.Args .AddAllArgs (Arguments, options::OPT_F);
1378
-
1379
- if (!context.OI .SDKPath .empty ()) {
1380
- Arguments.push_back (" --sysroot" );
1381
- Arguments.push_back (context.Args .MakeArgString (context.OI .SDKPath ));
1382
- }
1383
-
1384
- // Add the runtime library link path, which is platform-specific and found
1385
- // relative to the compiler.
1386
- // FIXME: Duplicated from CompilerInvocation, but in theory the runtime
1387
- // library link path and the standard library module import path don't
1388
- // need to be the same.
1389
- llvm::SmallString<128 > RuntimeLibPath;
1390
-
1391
- if (const Arg *A = context.Args .getLastArg (options::OPT_resource_dir)) {
1392
- RuntimeLibPath = A->getValue ();
1393
- } else {
1394
- RuntimeLibPath = D.getSwiftProgramPath ();
1395
- llvm::sys::path::remove_filename (RuntimeLibPath); // remove /swift
1396
- llvm::sys::path::remove_filename (RuntimeLibPath); // remove /bin
1397
- llvm::sys::path::append (RuntimeLibPath, " lib" , " swift" );
1398
- }
1399
- llvm::sys::path::append (RuntimeLibPath,
1400
- getPlatformNameForTriple (getTriple ()));
1401
- Arguments.push_back (" -L" );
1402
- Arguments.push_back (context.Args .MakeArgString (RuntimeLibPath));
1403
-
1404
- if (context.Args .hasArg (options::OPT_profile_generate)) {
1405
- SmallString<128 > LibProfile (RuntimeLibPath);
1406
- llvm::sys::path::remove_filename (LibProfile); // remove platform name
1407
- llvm::sys::path::append (LibProfile, " clang" , CLANG_VERSION_STRING);
1408
-
1409
- llvm::sys::path::append (LibProfile, " lib" , getTriple ().getOSName (),
1410
- Twine (" libclang_rt.profile-" ) +
1411
- getTriple ().getArchName () + " .a" );
1412
- Arguments.push_back (context.Args .MakeArgString (LibProfile));
1413
- }
1414
-
1415
- // FIXME: We probably shouldn't be adding an rpath here unless we know ahead
1416
- // of time the standard library won't be copied.
1417
- Arguments.push_back (" -Xlinker" );
1418
- Arguments.push_back (" -rpath" );
1419
- Arguments.push_back (" -Xlinker" );
1420
- Arguments.push_back (context.Args .MakeArgString (RuntimeLibPath));
1421
-
1422
- // Always add the stdlib
1423
- Arguments.push_back (" -lswiftCore" );
1424
-
1425
- // Add any autolinking scripts to the arguments
1426
- for (const Job *Cmd : context.Inputs ) {
1427
- auto &OutputInfo = Cmd->getOutput ();
1428
- if (OutputInfo.getPrimaryOutputType () == types::TY_AutolinkFile)
1429
- Arguments.push_back (context.Args .MakeArgString (
1430
- Twine (" @" ) + OutputInfo.getPrimaryOutputFilename ()));
1431
- }
1432
-
1433
- // This should be the last option, for convenience in checking output.
1434
- Arguments.push_back (" -o" );
1435
- Arguments.push_back (context.Output .getPrimaryOutputFilename ().c_str ());
1349
+ std::string toolchains::Cygwin::getPreInputObjectPath (
1350
+ StringRef RuntimeLibraryPath) const {
1351
+ // Cygwin does not add "begin" and "end" objects.
1352
+ return " " ;
1353
+ }
1436
1354
1437
- return {" clang++" , Arguments};
1355
+ std::string toolchains::Cygwin::getPostInputObjectPath (
1356
+ StringRef RuntimeLibraryPath) const {
1357
+ // Cygwin does not add "begin" and "end" objects.
1358
+ return " " ;
1438
1359
}
0 commit comments