From 37f689f36dc45fbb54861f10346e5728a21e08c7 Mon Sep 17 00:00:00 2001 From: kotofyt Date: Thu, 1 Jan 2026 14:45:48 +0200 Subject: [PATCH] started reworking linker --- fpc/library/clang/ld.cpp | 37 ++++++++++++++ fpc/library/ld.cpp | 62 +++++++++++++++++++++++ fpc/library/target.cpp | 52 +++++++++++++++++++ fpc/public/c.h | 5 +- fpc/public/ld.h | 40 +++++++++++++++ fpc/public/target.h | 3 ++ fpc/tests/windows_drivers_build/build.cpp | 0 fpc/tests/windows_drivers_build/main.c | 0 materialsystem/__build.cpp | 2 +- 9 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 fpc/tests/windows_drivers_build/build.cpp create mode 100644 fpc/tests/windows_drivers_build/main.c diff --git a/fpc/library/clang/ld.cpp b/fpc/library/clang/ld.cpp index 96ad9fa..0d1c789 100644 --- a/fpc/library/clang/ld.cpp +++ b/fpc/library/clang/ld.cpp @@ -11,6 +11,43 @@ class CClangLinker : public ILinker public: virtual CUtlString Link( LinkProject_t *pProject ) override; virtual bool IsLibraryExists( CUtlString szName ) override; +protected: + // Returns file name of the + CUtlString GetOutputObjectName( LinkProject_t *pProject, unsigned int hash, CUtlString szFileName ); + + virtual CUtlVector BuildLinkCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName ); + virtual CUtlVector BuildArchiveCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName ); + + // Returns executable which should the OS run + virtual const char *GetCompilerExecutable( LinkProject_t *pProject ) override; + + // returns object file format, eg .obj or .o + virtual const char *GetOutputObjectFormat() 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 *szName ) override; + + + // sets rpath + // for windows should be ignored + virtual void SetDefaultLibraryPaths( CUtlVector &cmd ) 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; }; EXPOSE_INTERFACE(CClangLinker, ILinker, CLANG_LINKER_INTERFACE_NAME); diff --git a/fpc/library/ld.cpp b/fpc/library/ld.cpp index a8e7290..a82eee2 100644 --- a/fpc/library/ld.cpp +++ b/fpc/library/ld.cpp @@ -6,3 +6,65 @@ void LinkProject_t::AddObject( Object_t object ) { objects.AppendTail(object); }; +CUtlString ILinker::GetOutputObjectName( LinkProject_t *pProject, unsigned int hash, CUtlString szFileName ) +{ + CUtlString szTarget = pProject->m_target.GetTriplet(); + CUtlString szFileNameFormat; + switch (pProject->linkType) + { + case ELINK_EXECUTABLE: + szFileNameFormat = CUtlString(pProject->m_target.GetExecutableFileFormat(),pProject->m_szName.GetString()); + break; + case ELINK_DYNAMIC_LIBRARY: + szFileNameFormat = CUtlString(pProject->m_target.GetDynamicLibraryFileFormat(),pProject->m_szName.GetString()); + break; + case ELINK_STATIC_LIBRARY: + szFileNameFormat = CUtlString(pProject->m_target.GetStaticLibraryFileFormat(),pProject->m_szName.GetString()); + break; + default: + break; + } + + return CUtlString( + "%s/%s/ld/%u_%s/%s", + FPC_TEMPORAL_DIRNAME, + szTarget.GetString(), + hash, + pProject->m_szName.GetString(), + szFileNameFormat.GetString()); +} + + +CUtlVector ILinker::BuildLinkCommandLine( LinkProject_t *pProject, const char *szOutputFileName ) +{ + CUtlVector cmd; + SetTarget(cmd, pProject); + SetOutputFile(cmd); + SetSysroot(cmd, pProject, NULL); + UseFullFile(cmd); + for (auto &o: pProject->objects) + { + LinkFile(cmd, o.m_szObjectFile); + } + UsePartialFile(cmd); + + for (auto &o: pProject->libraryObjects) + { + LinkLibraryObject(cmd, o); + }; + for (auto &o: pProject->libraries) + { + LinkLibrary(cmd, o); + }; + for (auto &o: pProject->libraryDirectories) + { + LinkLibraryPath(cmd, o); + }; + +} + +CUtlVector ILinker::BuildArchiveCommandLine( LinkProject_t *pProject, const char *szOutputFileName ) +{ + CUtlVector cmd; +} + diff --git a/fpc/library/target.cpp b/fpc/library/target.cpp index be9dd43..ff5916c 100644 --- a/fpc/library/target.cpp +++ b/fpc/library/target.cpp @@ -39,6 +39,58 @@ CUtlString Target_t::GetTriplet() return triplet; } +const char *Target_t::GetExecutableFileFormat() +{ + switch(kernel) + { + case TARGET_KERNEL_LINUX: + case TARGET_KERNEL_ANDROID: + case TARGET_KERNEL_DARWIN: + case TARGET_KERNEL_IOS: + return "%s"; + break; + case TARGET_KERNEL_WINDOWS_MSVC: + case TARGET_KERNEL_WINDOWS_GNU: + return "%s.exe"; + default: + break; + } + return NULL; +} + +const char *Target_t::GetStaticLibraryFileFormat() +{ + switch(kernel) + { + case TARGET_KERNEL_LINUX: + case TARGET_KERNEL_ANDROID: + case TARGET_KERNEL_DARWIN: + case TARGET_KERNEL_IOS: + case TARGET_KERNEL_WINDOWS_GNU: + return "lib%s.a"; + case TARGET_KERNEL_WINDOWS_MSVC: + return "%s.lib"; + default: + break; + } + return NULL; +} +const char *Target_t::GetDynamicLibraryFileFormat() +{ + switch(kernel) + { + case TARGET_KERNEL_LINUX: + case TARGET_KERNEL_ANDROID: + return "lib%s.so"; + case TARGET_KERNEL_DARWIN: + return "lib%s.dylib"; + case TARGET_KERNEL_WINDOWS_GNU: + return "%s.dll"; + default: + break; + } + return NULL; +} //---------------------------------------------------------------------------- // Returns target on which fpc is being run //---------------------------------------------------------------------------- diff --git a/fpc/public/c.h b/fpc/public/c.h index 240f792..2e409c1 100644 --- a/fpc/public/c.h +++ b/fpc/public/c.h @@ -123,14 +123,15 @@ protected: virtual void Macro( CUtlVector &cmd, const char *szName, const char *szValue ) = 0; virtual void SetTarget( CUtlVector &cmd, CProject_t *pProject ) = 0; - virtual void CompileFile( CUtlVector &cmd, const char *szName ) = 0; + virtual void SetSysroot( CUtlVector &cmd, CProject_t *pProject , const char *szSysroot ) = 0; virtual void SetOutputFile( CUtlVector &cmd, const char *szName ) = 0; + + virtual void CompileFile( CUtlVector &cmd, const char *szName ) = 0; virtual void EnableDebugSymbols( CUtlVector &cmd ) = 0; virtual void EnablePIE( CUtlVector &cmd ) = 0; virtual void EnablePIC( CUtlVector &cmd ) = 0; - virtual void SetSysroot( CUtlVector &cmd, CProject_t *pProject , const char *szSysroot ) = 0; }; extern ICCompiler *ccompiler; diff --git a/fpc/public/ld.h b/fpc/public/ld.h index 34bf80a..710cfc1 100644 --- a/fpc/public/ld.h +++ b/fpc/public/ld.h @@ -94,6 +94,46 @@ public: virtual CUtlString Link( LinkProject_t *pProject ) = 0; virtual bool IsLibraryExists( CUtlString szName ) = 0; + +protected: + // Link + // Returns file name of the + CUtlString GetOutputObjectName( LinkProject_t *pProject, unsigned int hash, CUtlString szFileName ); + + virtual CUtlVector BuildLinkCommandLine( LinkProject_t *pProject, const char *szOutputFileName ); + virtual CUtlVector BuildArchiveCommandLine( LinkProject_t *pProject, const char *szOutputFileName ); + + // Returns executable which should the OS run + virtual const char *GetCompilerExecutable( LinkProject_t *pProject ) = 0; + + // returns object file format, eg .obj or .o + virtual const char *GetOutputObjectFormat() = 0; + + 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; + + + // sets rpath + // for windows should be ignored + virtual void SetDefaultLibraryPaths( CUtlVector &cmd ) = 0; + + virtual void UseStdLib( CUtlVector &cmd, bool bUse ) = 0; + + // windows doesn't use it as well + virtual void UseDynamicLookup( CUtlVector &cmd, bool bUse ) = 0; + + // includes whole file + virtual void UseFullFile( CUtlVector &cmd ) = 0; + + // includes used stuff in a file + virtual void UsePartialFile( CUtlVector &cmd ) = 0; + + virtual void LinkFile( CUtlVector &cmd, const char *szName ) = 0; + virtual void LinkLibraryObject( CUtlVector &cmd, const char *szName ) = 0; + virtual void LinkLibrary( CUtlVector &cmd, const char *szName ) = 0; + virtual void LinkLibraryPath( CUtlVector &cmd, const char *szName ) = 0; + }; extern ILinker *linker; diff --git a/fpc/public/target.h b/fpc/public/target.h index 5b659bc..eac8229 100644 --- a/fpc/public/target.h +++ b/fpc/public/target.h @@ -49,6 +49,9 @@ struct Target_t const char *szSysroot = CommandLine()->ParamValue("-sysroot"); CUtlString GetTriplet(); + const char *GetExecutableFileFormat(); + const char *GetStaticLibraryFileFormat(); + const char *GetDynamicLibraryFileFormat(); static Target_t HostTarget(); static Target_t DefaultTarget(); }; diff --git a/fpc/tests/windows_drivers_build/build.cpp b/fpc/tests/windows_drivers_build/build.cpp new file mode 100644 index 0000000..e69de29 diff --git a/fpc/tests/windows_drivers_build/main.c b/fpc/tests/windows_drivers_build/main.c new file mode 100644 index 0000000..e69de29 diff --git a/materialsystem/__build.cpp b/materialsystem/__build.cpp index 9c05fd6..04acb4b 100644 --- a/materialsystem/__build.cpp +++ b/materialsystem/__build.cpp @@ -22,7 +22,7 @@ CUtlVector RenderContextVulkan_CompiledFiles = { "materialsystem/vulkan/commands/base.cpp", "materialsystem/vulkan/libraries/raster.cpp", "external/volk/volk.c", -} +}; CUtlString material_lib; DECLARE_BUILD_STAGE(MaterialSystem)