From 5759e401af27a8b662f1504ad7bd0478217489a7 Mon Sep 17 00:00:00 2001 From: kotofyt Date: Thu, 1 Jan 2026 21:34:05 +0200 Subject: [PATCH] reworked linking --- fpc/Makefile | 2 +- fpc/library/clang/ld.cpp | 105 +++++++++++++++++++++++++------------ fpc/library/ld.cpp | 64 +++++++++++++++++++++- fpc/library/windows/c.cpp | 9 +++- fpc/library/windows/ld.cpp | 98 ++++++++++++++++++++++++++++++++++ fpc/public/ld.h | 6 +-- 6 files changed, 245 insertions(+), 39 deletions(-) diff --git a/fpc/Makefile b/fpc/Makefile index fe5afb1..045d2d0 100644 --- a/fpc/Makefile +++ b/fpc/Makefile @@ -21,7 +21,7 @@ recompile: ../build/tools/fpc install: ../build/tools/fpc libfpcbuild.a libfpc.so libtier0.so libtier1.a libtier2.a libfilesystem_std.so install_temp builddir $(CC) -fPIC main.cpp library/helper.cpp library/target.cpp library/builder.cpp -lc -lstdc++ $(CCFLAGS) -o build/fpc libtier0.so build/libtier1.a build/libtier2.a -Wl,--disable-new-dtags -Wl,-rpath,'$$ORIGIN' - build/fpc build + build/fpc build -fpcdebug libtier0.so: $(TIER0_FILES) builddir $(CC) $(CCFLAGS) -fPIC -shared -o build/libtier0.so $(TIER0_FILES) diff --git a/fpc/library/clang/ld.cpp b/fpc/library/clang/ld.cpp index 0d8828b..0014d4e 100644 --- a/fpc/library/clang/ld.cpp +++ b/fpc/library/clang/ld.cpp @@ -9,7 +9,7 @@ class CClangLinker : public ILinker { public: - virtual CUtlString Link( LinkProject_t *pProject ) override; + //virtual CUtlString Link( LinkProject_t *pProject ) override; virtual bool IsLibraryExists( CUtlString szName ) override; protected: //virtual CUtlVector BuildLinkCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName ); @@ -20,12 +20,12 @@ protected: virtual void SetTarget( CUtlVector &cmd, LinkProject_t *pProject ) override; virtual void SetSysroot( CUtlVector &cmd, LinkProject_t *pProject , const char *szSysroot ) override; - virtual void SetOutputFile( CUtlVector &cmd) override; + virtual void SetOutputFile( CUtlVector &cmd, const char *szName ) override; // sets rpath // for windows should be ignored - virtual void SetDefaultLibraryPaths( CUtlVector &cmd ) override; + virtual void SetDefaultLibraryPaths( CUtlVector &cmd, LinkProject_t *pProject ) override; virtual void UseStdLib( CUtlVector &cmd, bool bUse ) override; @@ -48,49 +48,86 @@ protected: const char *CClangLinker::GetCompilerExecutable( LinkProject_t *pProject ) { - IINISection *pSection = NULL; - const char *szLinker = "clang++"; - if (!g_pConfig) - return szLinker; - - - pSection = g_pConfig->GetSection(pProject->m_target.GetTriplet()); - if (!pSection) - return szLinker; - - - szLinker = pSection->GetStringValue("CLANG_LINKER_INTERFACE_NAME"); - if (szLinker == NULL) - return "clang++"; + IINISection *pSection = NULL; + const char *szLinker = "clang++"; + if (!g_pConfig) return szLinker; + + + pSection = g_pConfig->GetSection(pProject->m_target.GetTriplet()); + if (!pSection) + return szLinker; + + + szLinker = pSection->GetStringValue("CLANG_LINKER_INTERFACE_NAME"); + if (szLinker == NULL) + return "clang++"; + return szLinker; } void CClangLinker::SetTarget( CUtlVector &cmd, LinkProject_t *pProject ) -{ - +{ + if (pProject->linkType == ELINK_DYNAMIC_LIBRARY) + cmd.AppendTail("-shared"); + + cmd.AppendTail("-target"); + cmd.AppendTail(pProject->m_target.GetTriplet()); } -void CClangLinker::SetSysroot( CUtlVector &cmd, LinkProject_t *pProject , const char *szSysroot ) +void CClangLinker::SetSysroot( CUtlVector &cmd, LinkProject_t *pProject , const char *szName ) { + if (szName != NULL) + { + cmd.AppendTail("--sysroot"); + cmd.AppendTail(szName); + return; + } + if (!g_pConfig) + return; + + + IINISection *pSection = g_pConfig->GetSection(pProject->m_target.GetTriplet()); + if (!pSection) + return; + + const char *szSysroot = pSection->GetStringValue("sysroot"); + if (szSysroot) + { + cmd.AppendTail("--sysroot"); + cmd.AppendTail(szSysroot); + } } -void CClangLinker::SetOutputFile( CUtlVector &cmd) +void CClangLinker::SetOutputFile( CUtlVector &cmd, const char *szName ) { - + cmd.AppendTail("-o"); + cmd.AppendTail(szName); } -void CClangLinker::SetDefaultLibraryPaths( CUtlVector &cmd ) +void CClangLinker::SetDefaultLibraryPaths( CUtlVector &cmd, LinkProject_t *pProject ) { - + switch (pProject->m_target.kernel) + { + case TARGET_KERNEL_LINUX: + case TARGET_KERNEL_ANDROID: + cmd.AppendTail("-Wl,--disable-new-dtags"); + cmd.AppendTail("-Wl,-rpath,$ORIGIN"); + break; + case TARGET_KERNEL_DARWIN: + break; + default: + break; + } } void CClangLinker::UseStdLib( CUtlVector &cmd, bool bUse ) { - + if (!bUse) + cmd.AppendTail("-nostdlib"); } @@ -102,38 +139,40 @@ void CClangLinker::UseDynamicLookup( CUtlVector &cmd, bool bUse ) void CClangLinker::UseFullFile( CUtlVector &cmd ) { - + cmd.AppendTail("-Wl,--whole-archive"); } void CClangLinker::UsePartialFile( CUtlVector &cmd ) { - + cmd.AppendTail("-Wl,--no-whole-archive"); } void CClangLinker::LinkFile( CUtlVector &cmd, const char *szName ) { - + cmd.AppendTail(szName); } void CClangLinker::LinkLibraryObject( CUtlVector &cmd, const char *szName ) { - + cmd.AppendTail(szName); } void CClangLinker::LinkLibrary( CUtlVector &cmd, const char *szName ) { - + cmd.AppendTail("-l"); + cmd.AppendTail(szName); } void CClangLinker::LinkLibraryPath( CUtlVector &cmd, const char *szName ) { - + cmd.AppendTail("-L"); + cmd.AppendTail(szName); } EXPOSE_INTERFACE(CClangLinker, ILinker, CLANG_LINKER_INTERFACE_NAME); - +/* CUtlString CClangLinker::Link( LinkProject_t *pProject ) { if (pProject->m_szName == 0) @@ -353,7 +392,7 @@ use_default_linker: compiled: return szOutputFile; }; - +*/ bool CClangLinker::IsLibraryExists( CUtlString szName ) { szName = CUtlString("lib%s.so", szName.GetString()); diff --git a/fpc/library/ld.cpp b/fpc/library/ld.cpp index a82eee2..56f0367 100644 --- a/fpc/library/ld.cpp +++ b/fpc/library/ld.cpp @@ -34,13 +34,74 @@ CUtlString ILinker::GetOutputObjectName( LinkProject_t *pProject, unsigned int h szFileNameFormat.GetString()); } +CUtlString ILinker::Link( LinkProject_t *pProject ) +{ + if (pProject->m_szName == 0) + { + Plat_FatalErrorFunc("m_szName must be present\n"); + } + LinkProject_t stLinkProject = *pProject; + if (pProject->m_target.kernel == TARGET_KERNEL_ANDROID) + stLinkProject.linkType = ELINK_DYNAMIC_LIBRARY; + + unsigned int hash = pProject->GenerateProjectHash(); + CUtlString szOutputFile = GetOutputObjectName(&stLinkProject, hash, NULL); + filesystem2->MakeDirectory(szOutputFile.GetDirectory()); + + if (stLinkProject.linkType == ELINK_STATIC_LIBRARY) + { + CUtlVector args; + bool shouldRecompile = false; + for (auto object: pProject->objects) + { + if (filesystem2->ShouldRecompile(object.m_szObjectFile,szOutputFile)) + { + shouldRecompile = true; + break; + } + } + if (!shouldRecompile) + goto compiled; + + V_printf(" AR %s\n", pProject->m_szName.GetString()); + args = { + "rcs", + szOutputFile + }; + for (auto object: pProject->objects) + args.AppendTail(object.m_szObjectFile); + runner->Run("ar", args); + runner->Wait(); + } else { + bool shouldRecompile = false; + for (auto object: pProject->objects) + { + if (filesystem2->ShouldRecompile(object.m_szObjectFile,szOutputFile)) + { + shouldRecompile = true; + break; + } + } + if (!shouldRecompile) + goto compiled; + + V_printf(" LINK %s\n", pProject->m_szName.GetString()); + CUtlVector args; + args = BuildLinkCommandLine(pProject, szOutputFile); + runner->Run(GetCompilerExecutable(pProject), args); + runner->Wait(); + } +compiled: + return szOutputFile; +} CUtlVector ILinker::BuildLinkCommandLine( LinkProject_t *pProject, const char *szOutputFileName ) { CUtlVector cmd; SetTarget(cmd, pProject); - SetOutputFile(cmd); + SetOutputFile(cmd, szOutputFileName); SetSysroot(cmd, pProject, NULL); + SetDefaultLibraryPaths(cmd, pProject); UseFullFile(cmd); for (auto &o: pProject->objects) { @@ -60,6 +121,7 @@ CUtlVector ILinker::BuildLinkCommandLine( LinkProject_t *pProject, c { LinkLibraryPath(cmd, o); }; + return cmd; } diff --git a/fpc/library/windows/c.cpp b/fpc/library/windows/c.cpp index 9a58075..c2ccc72 100644 --- a/fpc/library/windows/c.cpp +++ b/fpc/library/windows/c.cpp @@ -41,8 +41,9 @@ protected: virtual void Macro( CUtlVector &cmd, const char *szName, const char *szValue ) override; virtual void SetTarget( CUtlVector &cmd, CProject_t *pProject ) override; - virtual void CompileFile( CUtlVector &cmd, const char *szName ) override; + virtual void SetSysroot( CUtlVector &cmd, CProject_t *pProject , const char *szSysroot ) override; virtual void SetOutputFile( CUtlVector &cmd, const char *szName ) override; + virtual void CompileFile( CUtlVector &cmd, const char *szName ) override; virtual void EnableDebugSymbols( CUtlVector &cmd ) override; virtual void EnablePIE( CUtlVector &cmd ) override; @@ -99,6 +100,12 @@ void CMSVCCompiler::EnableDebugSymbols( CUtlVector &cmd ) void CMSVCCompiler::SetTarget( CUtlVector &cmd, CProject_t *pProject ) { + +} + +void CMSVCCompiler::SetSysroot( CUtlVector &cmd, CProject_t *pProject , const char *szSysroot ) +{ + } void CMSVCCompiler::CompileFile( CUtlVector &cmd, const char *szName ) diff --git a/fpc/library/windows/ld.cpp b/fpc/library/windows/ld.cpp index 7f1e859..c91d27f 100644 --- a/fpc/library/windows/ld.cpp +++ b/fpc/library/windows/ld.cpp @@ -13,8 +13,106 @@ class CMSVCLinker : public ILinker public: virtual CUtlString Link( LinkProject_t *pProject ) override; virtual bool IsLibraryExists( CUtlString szName ) override; +protected: + // Returns executable which should the OS run + virtual const char *GetCompilerExecutable( LinkProject_t *pProject ) override; + + virtual void SetTarget( CUtlVector &cmd, LinkProject_t *pProject ) override; + virtual void SetSysroot( CUtlVector &cmd, LinkProject_t *pProject , const char *szSysroot ) override; + virtual void SetOutputFile( CUtlVector &cmd, const char *szOutput) override; + + + // sets rpath + // for windows should be ignored + virtual void SetDefaultLibraryPaths( CUtlVector &cmd, LinkProject_t *pProject ) override; + + virtual void UseStdLib( CUtlVector &cmd, bool bUse ) override; + + // windows doesn't use it as well + virtual void UseDynamicLookup( CUtlVector &cmd, bool bUse ) override; + + // includes whole file + virtual void UseFullFile( CUtlVector &cmd ) override; + + // includes used stuff in a file + virtual void UsePartialFile( CUtlVector &cmd ) override; + + virtual void LinkFile( CUtlVector &cmd, const char *szName ) override; + virtual void LinkLibraryObject( CUtlVector &cmd, const char *szName ) override; + virtual void LinkLibrary( CUtlVector &cmd, const char *szName ) override; + virtual void LinkLibraryPath( CUtlVector &cmd, const char *szName ) override; }; +const char *CMSVCLinker::GetCompilerExecutable( LinkProject_t *pProject ) +{ + +} + +void CMSVCLinker::SetTarget( CUtlVector &cmd, LinkProject_t *pProject ) +{ + +} + +void CMSVCLinker::SetSysroot( CUtlVector &cmd, LinkProject_t *pProject , const char *szSysroot ) +{ + +} + +void CMSVCLinker::SetOutputFile( CUtlVector &cmd, const char *szName ) +{ + +} + +void CMSVCLinker::SetDefaultLibraryPaths( CUtlVector &cmd, LinkProject_t *pProject ) +{ + +} + + +void CMSVCLinker::UseStdLib( CUtlVector &cmd, bool bUse ) +{ + +} + + +void CMSVCLinker::UseDynamicLookup( CUtlVector &cmd, bool bUse ) +{ + +} + + +void CMSVCLinker::UseFullFile( CUtlVector &cmd ) +{ + +} + + +void CMSVCLinker::UsePartialFile( CUtlVector &cmd ) +{ + +} + + +void CMSVCLinker::LinkFile( CUtlVector &cmd, const char *szName ) +{ + +} + +void CMSVCLinker::LinkLibraryObject( CUtlVector &cmd, const char *szName ) +{ + +} + +void CMSVCLinker::LinkLibrary( CUtlVector &cmd, const char *szName ) +{ + +} + +void CMSVCLinker::LinkLibraryPath( CUtlVector &cmd, const char *szName ) +{ + +} + EXPOSE_INTERFACE(CMSVCLinker, ILinker, MSVC_LINKER_INTERFACE_NAME); CUtlString CMSVCLinker::Link( LinkProject_t *pProject ) diff --git a/fpc/public/ld.h b/fpc/public/ld.h index b276e87..16d9bc2 100644 --- a/fpc/public/ld.h +++ b/fpc/public/ld.h @@ -91,7 +91,7 @@ abstract_class ILinker public: // Links project - virtual CUtlString Link( LinkProject_t *pProject ) = 0; + virtual CUtlString Link( LinkProject_t *pProject ); virtual bool IsLibraryExists( CUtlString szName ) = 0; @@ -108,12 +108,12 @@ protected: virtual void SetTarget( CUtlVector &cmd, LinkProject_t *pProject ) = 0; virtual void SetSysroot( CUtlVector &cmd, LinkProject_t *pProject , const char *szSysroot ) = 0; - virtual void SetOutputFile( CUtlVector &cmd ) = 0; + virtual void SetOutputFile( CUtlVector &cmd, const char *szName ) = 0; // sets rpath // for windows should be ignored - virtual void SetDefaultLibraryPaths( CUtlVector &cmd ) = 0; + virtual void SetDefaultLibraryPaths( CUtlVector &cmd, LinkProject_t *pProject ) = 0; virtual void UseStdLib( CUtlVector &cmd, bool bUse ) = 0;