This commit is contained in:
parent
03d7ec15eb
commit
dbee23c564
1 changed files with 25 additions and 3 deletions
|
|
@ -635,6 +635,20 @@ BuildResult Crafter::Build(Configuration& config, std::unordered_map<fs::path, s
|
|||
|
||||
std::string cmakeBuildType;
|
||||
|
||||
// Behaviour-neutral release performance for the binaries we emit: ThinLTO
|
||||
// (cross-TU inlining) plus dead-section GC and safe identical-code folding.
|
||||
// Default-on in Release, never Debug (keeps builds fast and debuggable).
|
||||
// Excluded for wasm32 — its -mllvm/sjlj codegen flags don't compose with
|
||||
// LTO here — and for nvcc .cu objects below (they can't emit LLVM bitcode,
|
||||
// so they link in as ordinary objects alongside the bitcode ones). ThinLTO
|
||||
// rather than monolithic -flto so link time and memory scale with arbitrary
|
||||
// user project sizes. Compile-side flags (-flto, -ffunction/-fdata-sections)
|
||||
// ride on `command`, which is reused as the link base; the link-only -Wl
|
||||
// flags go on linkExtras so they don't warn on each -c compile.
|
||||
const bool useLto = !config.debug && !isWasm;
|
||||
const std::string ltoCompileFlags = useLto ? " -flto=thin -ffunction-sections -fdata-sections" : "";
|
||||
const std::string ltoLinkFlags = useLto ? " -flto=thin -Wl,--gc-sections -Wl,--icf=safe" : "";
|
||||
|
||||
if(config.debug) {
|
||||
cmakeBuildType = "Debug";
|
||||
command += " -g -D CRAFTER_BUILD_CONFIGURATION_DEBUG";
|
||||
|
|
@ -642,6 +656,7 @@ BuildResult Crafter::Build(Configuration& config, std::unordered_map<fs::path, s
|
|||
cmakeBuildType = "Release";
|
||||
command += " -O3";
|
||||
}
|
||||
command += ltoCompileFlags;
|
||||
|
||||
// Same target-aware setup as the C++ compile path (line 459-): wasm32
|
||||
// rejects -march, silently ignores -mtune, and needs --sysroot to find
|
||||
|
|
@ -664,11 +679,11 @@ BuildResult Crafter::Build(Configuration& config, std::unordered_map<fs::path, s
|
|||
const std::string objPath = (buildDir / cFile.filename()).string() + "_source.o";
|
||||
const std::string srcPath = cFile.string() + ".c";
|
||||
if (!fs::exists(objPath) || (fs::exists(srcPath) && fs::last_write_time(srcPath) > fs::last_write_time(objPath))) {
|
||||
threads.emplace_back([&cFile, &buildDir, &buildError, &buildCancelled, &config, &includeFlags, &defineFlags, &userFlags, &cArchFlags]() {
|
||||
threads.emplace_back([&cFile, &buildDir, &buildError, &buildCancelled, &config, &includeFlags, &defineFlags, &userFlags, &cArchFlags, <oCompileFlags]() {
|
||||
Progress::Task task(std::format("Compiling {}.c", cFile.filename().string()));
|
||||
if (buildCancelled.load(std::memory_order_relaxed)) return;
|
||||
|
||||
std::string result = RunCommand(std::format("clang {}.c --target={}{} -O3 -c{}{}{} -o {}_source.o", cFile.string(), config.target, cArchFlags, includeFlags, defineFlags, userFlags, (buildDir / cFile.filename()).string()));
|
||||
std::string result = RunCommand(std::format("clang {}.c --target={}{} -O3{} -c{}{}{} -o {}_source.o", cFile.string(), config.target, cArchFlags, ltoCompileFlags, includeFlags, defineFlags, userFlags, (buildDir / cFile.filename()).string()));
|
||||
if (result.empty()) return;
|
||||
|
||||
bool expected = false;
|
||||
|
|
@ -876,6 +891,10 @@ BuildResult Crafter::Build(Configuration& config, std::unordered_map<fs::path, s
|
|||
for(const std::string& flag : buildResult.libs) {
|
||||
linkExtras += " " + flag;
|
||||
}
|
||||
// Link-only LTO/section flags (empty in Debug and for wasm). Every exe/lib
|
||||
// link below ends with linkExtras, so this reaches them all; the static-lib
|
||||
// archive path uses ar instead and is handled separately.
|
||||
linkExtras += ltoLinkFlags;
|
||||
// mingw uses libstdc++; C++26 std::print/format extras live in libstdc++exp.
|
||||
// libstdc++ on mingw uses winpthreads for std::atomic_wait /
|
||||
// counting_semaphore / stop_token, so -lpthread is required as soon as
|
||||
|
|
@ -1058,7 +1077,10 @@ BuildResult Crafter::Build(Configuration& config, std::unordered_map<fs::path, s
|
|||
#endif
|
||||
} else if(config.type == ConfigurationType::LibraryStatic) {
|
||||
#ifdef CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_linux_gnu
|
||||
buildResult.result = RunCommand(std::format("ar rcs {}.a {}", (outputDir/fs::path(std::string("lib")+config.outputName)).string(), files));
|
||||
// ThinLTO emits LLVM bitcode objects; plain `ar` writes an archive
|
||||
// index that omits their symbols, so a consumer's lld link can't
|
||||
// pull the needed members. llvm-ar writes a bitcode-aware index.
|
||||
buildResult.result = RunCommand(std::format("{} rcs {}.a {}", useLto ? "llvm-ar" : "ar", (outputDir/fs::path(std::string("lib")+config.outputName)).string(), files));
|
||||
#endif
|
||||
|
||||
#if defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_pc_windows_msvc) || defined(CRAFTER_BUILD_CONFIGURATION_TARGET_x86_64_w64_mingw32)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue