When linking in a library with start-lib and end-lib, lld-link would discard a symbol unless it is already seen in the prior objects. It discards the symbol even if the symbol is referenced in a latter object from the same library (latter as the command line order).
The following fails with error: lld-link: error: relocation against symbol in discarded section: ?get_localtime@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ
Note that the only difference between success and fail cases is the object order between start-lib and end-lib. I'm able to reproduce with the latest llvm version (19.1.0).
When linking in a library with `start-lib` and `end-lib`, `lld-link` would discard a symbol unless it is already seen in the prior objects. It discards the symbol even if the symbol is referenced in a latter object from the same library (latter as the command line order).
## A simple case to repro (Powershell on Windows):
1. Setup
```powershell
Set-Content -Path .\hello-time.h -Value @"
#ifndef LIB_HELLO_TIME_H_
#define LIB_HELLO_TIME_H_
#include <string>
std::string get_localtime();
#endif
"@
Set-Content -Path .\hello-time.cc -Value @"
#include "hello-time.h"
#include <ctime>
#include <string>
std::string get_localtime() {
std::time_t result = std::time(nullptr);
return std::asctime(std::localtime(&result));
}
"@
Set-Content -Path .\hello-greet.h -Value @"
#ifndef MAIN_HELLO_GREET_H_
#define MAIN_HELLO_GREET_H_
#include <string>
std::string get_greet(const std::string &thing);
#endif
"@
Set-Content -Path .\hello-greet.cc -Value @"
#include "hello-time.h"
#include "hello-greet.h"
#include <string>
std::string get_greet(const std::string& who) {
return "Hello " + who + "; " + get_localtime();
}
"@
Set-Content -Path .\hello-world.cc -Value @"
#include "hello-greet.h"
#include <iostream>
#include <string>
int main(int argc, char** argv) {
std::cout << get_greet("world") << std::endl;
return 0;
}
"@
```
2. The following succeeds:
```powershell
If (Test-Path 'out') {
Remove-Item -Path 'out' -Recurse -Force -Verbose
}
New-Item -Path 'out' -ItemType Directory
clang-cl.exe /c 'hello-time.cc' /Fo'out/hello-time.obj'
clang-cl.exe /c 'hello-greet.cc' /Fo'out/hello-greet.obj'
clang-cl.exe /c 'hello-world.cc' /Fo'out/hello-world.obj'
lld-link.exe /OUT:'out/hello-world.exe' `
out/hello-world.obj `
'/start-lib' `
out/hello-greet.obj `
out/hello-time.obj `
'/end-lib'
```
3. The following fails with error: `lld-link: error: relocation against symbol in discarded section: ?get_localtime@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ`
```powershell
$ErrorActionPreference = "Stop"
If (Test-Path 'out') {
Remove-Item -Path 'out' -Recurse -Force -Verbose
}
New-Item -Path 'out' -ItemType Directory
clang-cl.exe /c 'hello-time.cc' /Fo'out/hello-time.obj'
clang-cl.exe /c 'hello-greet.cc' /Fo'out/hello-greet.obj'
clang-cl.exe /c 'hello-world.cc' /Fo'out/hello-world.obj'
lld-link.exe /OUT:'out/hello-world.exe' `
out/hello-world.obj `
'/start-lib' `
out/hello-time.obj `
out/hello-greet.obj `
'/end-lib'
```
**Note that the only difference between success and fail cases is the object order between `start-lib` and `end-lib`.** I'm able to reproduce with the latest llvm version (19.1.0).
When linking in a library with
start-lib
andend-lib
,lld-link
would discard a symbol unless it is already seen in the prior objects. It discards the symbol even if the symbol is referenced in a latter object from the same library (latter as the command line order).A simple case to repro (Powershell on Windows):
Setup
The following succeeds:
The following fails with error:
lld-link: error: relocation against symbol in discarded section: ?get_localtime@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ
Note that the only difference between success and fail cases is the object order between
start-lib
andend-lib
. I'm able to reproduce with the latest llvm version (19.1.0).