reworked linking

This commit is contained in:
2026-01-01 21:34:05 +02:00
parent 9245138eb0
commit 5759e401af
6 changed files with 245 additions and 39 deletions

View File

@@ -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 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' $(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 libtier0.so: $(TIER0_FILES) builddir
$(CC) $(CCFLAGS) -fPIC -shared -o build/libtier0.so $(TIER0_FILES) $(CC) $(CCFLAGS) -fPIC -shared -o build/libtier0.so $(TIER0_FILES)

View File

@@ -9,7 +9,7 @@
class CClangLinker : public ILinker class CClangLinker : public ILinker
{ {
public: public:
virtual CUtlString Link( LinkProject_t *pProject ) override; //virtual CUtlString Link( LinkProject_t *pProject ) override;
virtual bool IsLibraryExists( CUtlString szName ) override; virtual bool IsLibraryExists( CUtlString szName ) override;
protected: protected:
//virtual CUtlVector<CUtlString> BuildLinkCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName ); //virtual CUtlVector<CUtlString> BuildLinkCommandLine( LinkProject_t *pProject, const char *szFileName, const char *szOutputFileName );
@@ -20,12 +20,12 @@ protected:
virtual void SetTarget( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject ) override; virtual void SetTarget( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject ) override;
virtual void SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot ) override; virtual void SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot ) override;
virtual void SetOutputFile( CUtlVector<CUtlString> &cmd) override; virtual void SetOutputFile( CUtlVector<CUtlString> &cmd, const char *szName ) override;
// sets rpath // sets rpath
// for windows should be ignored // for windows should be ignored
virtual void SetDefaultLibraryPaths( CUtlVector<CUtlString> &cmd ) override; virtual void SetDefaultLibraryPaths( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject ) override;
virtual void UseStdLib( CUtlVector<CUtlString> &cmd, bool bUse ) override; virtual void UseStdLib( CUtlVector<CUtlString> &cmd, bool bUse ) override;
@@ -69,28 +69,65 @@ const char *CClangLinker::GetCompilerExecutable( LinkProject_t *pProject )
void CClangLinker::SetTarget( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject ) void CClangLinker::SetTarget( CUtlVector<CUtlString> &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<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot ) void CClangLinker::SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szName )
{ {
if (szName != NULL)
{
cmd.AppendTail("--sysroot");
cmd.AppendTail(szName);
return;
} }
void CClangLinker::SetOutputFile( CUtlVector<CUtlString> &cmd) 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::SetDefaultLibraryPaths( CUtlVector<CUtlString> &cmd ) void CClangLinker::SetOutputFile( CUtlVector<CUtlString> &cmd, const char *szName )
{ {
cmd.AppendTail("-o");
cmd.AppendTail(szName);
}
void CClangLinker::SetDefaultLibraryPaths( CUtlVector<CUtlString> &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<CUtlString> &cmd, bool bUse ) void CClangLinker::UseStdLib( CUtlVector<CUtlString> &cmd, bool bUse )
{ {
if (!bUse)
cmd.AppendTail("-nostdlib");
} }
@@ -102,38 +139,40 @@ void CClangLinker::UseDynamicLookup( CUtlVector<CUtlString> &cmd, bool bUse )
void CClangLinker::UseFullFile( CUtlVector<CUtlString> &cmd ) void CClangLinker::UseFullFile( CUtlVector<CUtlString> &cmd )
{ {
cmd.AppendTail("-Wl,--whole-archive");
} }
void CClangLinker::UsePartialFile( CUtlVector<CUtlString> &cmd ) void CClangLinker::UsePartialFile( CUtlVector<CUtlString> &cmd )
{ {
cmd.AppendTail("-Wl,--no-whole-archive");
} }
void CClangLinker::LinkFile( CUtlVector<CUtlString> &cmd, const char *szName ) void CClangLinker::LinkFile( CUtlVector<CUtlString> &cmd, const char *szName )
{ {
cmd.AppendTail(szName);
} }
void CClangLinker::LinkLibraryObject( CUtlVector<CUtlString> &cmd, const char *szName ) void CClangLinker::LinkLibraryObject( CUtlVector<CUtlString> &cmd, const char *szName )
{ {
cmd.AppendTail(szName);
} }
void CClangLinker::LinkLibrary( CUtlVector<CUtlString> &cmd, const char *szName ) void CClangLinker::LinkLibrary( CUtlVector<CUtlString> &cmd, const char *szName )
{ {
cmd.AppendTail("-l");
cmd.AppendTail(szName);
} }
void CClangLinker::LinkLibraryPath( CUtlVector<CUtlString> &cmd, const char *szName ) void CClangLinker::LinkLibraryPath( CUtlVector<CUtlString> &cmd, const char *szName )
{ {
cmd.AppendTail("-L");
cmd.AppendTail(szName);
} }
EXPOSE_INTERFACE(CClangLinker, ILinker, CLANG_LINKER_INTERFACE_NAME); EXPOSE_INTERFACE(CClangLinker, ILinker, CLANG_LINKER_INTERFACE_NAME);
/*
CUtlString CClangLinker::Link( LinkProject_t *pProject ) CUtlString CClangLinker::Link( LinkProject_t *pProject )
{ {
if (pProject->m_szName == 0) if (pProject->m_szName == 0)
@@ -353,7 +392,7 @@ use_default_linker:
compiled: compiled:
return szOutputFile; return szOutputFile;
}; };
*/
bool CClangLinker::IsLibraryExists( CUtlString szName ) bool CClangLinker::IsLibraryExists( CUtlString szName )
{ {
szName = CUtlString("lib%s.so", szName.GetString()); szName = CUtlString("lib%s.so", szName.GetString());

View File

@@ -34,13 +34,74 @@ CUtlString ILinker::GetOutputObjectName( LinkProject_t *pProject, unsigned int h
szFileNameFormat.GetString()); 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<CUtlString> 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<CUtlString> args;
args = BuildLinkCommandLine(pProject, szOutputFile);
runner->Run(GetCompilerExecutable(pProject), args);
runner->Wait();
}
compiled:
return szOutputFile;
}
CUtlVector<CUtlString> ILinker::BuildLinkCommandLine( LinkProject_t *pProject, const char *szOutputFileName ) CUtlVector<CUtlString> ILinker::BuildLinkCommandLine( LinkProject_t *pProject, const char *szOutputFileName )
{ {
CUtlVector<CUtlString> cmd; CUtlVector<CUtlString> cmd;
SetTarget(cmd, pProject); SetTarget(cmd, pProject);
SetOutputFile(cmd); SetOutputFile(cmd, szOutputFileName);
SetSysroot(cmd, pProject, NULL); SetSysroot(cmd, pProject, NULL);
SetDefaultLibraryPaths(cmd, pProject);
UseFullFile(cmd); UseFullFile(cmd);
for (auto &o: pProject->objects) for (auto &o: pProject->objects)
{ {
@@ -60,6 +121,7 @@ CUtlVector<CUtlString> ILinker::BuildLinkCommandLine( LinkProject_t *pProject, c
{ {
LinkLibraryPath(cmd, o); LinkLibraryPath(cmd, o);
}; };
return cmd;
} }

View File

@@ -41,8 +41,9 @@ protected:
virtual void Macro( CUtlVector<CUtlString> &cmd, const char *szName, const char *szValue ) override; virtual void Macro( CUtlVector<CUtlString> &cmd, const char *szName, const char *szValue ) override;
virtual void SetTarget( CUtlVector<CUtlString> &cmd, CProject_t *pProject ) override; virtual void SetTarget( CUtlVector<CUtlString> &cmd, CProject_t *pProject ) override;
virtual void CompileFile( CUtlVector<CUtlString> &cmd, const char *szName ) override; virtual void SetSysroot( CUtlVector<CUtlString> &cmd, CProject_t *pProject , const char *szSysroot ) override;
virtual void SetOutputFile( CUtlVector<CUtlString> &cmd, const char *szName ) override; virtual void SetOutputFile( CUtlVector<CUtlString> &cmd, const char *szName ) override;
virtual void CompileFile( CUtlVector<CUtlString> &cmd, const char *szName ) override;
virtual void EnableDebugSymbols( CUtlVector<CUtlString> &cmd ) override; virtual void EnableDebugSymbols( CUtlVector<CUtlString> &cmd ) override;
virtual void EnablePIE( CUtlVector<CUtlString> &cmd ) override; virtual void EnablePIE( CUtlVector<CUtlString> &cmd ) override;
@@ -99,6 +100,12 @@ void CMSVCCompiler::EnableDebugSymbols( CUtlVector<CUtlString> &cmd )
void CMSVCCompiler::SetTarget( CUtlVector<CUtlString> &cmd, CProject_t *pProject ) void CMSVCCompiler::SetTarget( CUtlVector<CUtlString> &cmd, CProject_t *pProject )
{ {
}
void CMSVCCompiler::SetSysroot( CUtlVector<CUtlString> &cmd, CProject_t *pProject , const char *szSysroot )
{
} }
void CMSVCCompiler::CompileFile( CUtlVector<CUtlString> &cmd, const char *szName ) void CMSVCCompiler::CompileFile( CUtlVector<CUtlString> &cmd, const char *szName )

View File

@@ -13,8 +13,106 @@ class CMSVCLinker : public ILinker
public: public:
virtual CUtlString Link( LinkProject_t *pProject ) override; virtual CUtlString Link( LinkProject_t *pProject ) override;
virtual bool IsLibraryExists( CUtlString szName ) 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<CUtlString> &cmd, LinkProject_t *pProject ) override;
virtual void SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot ) override;
virtual void SetOutputFile( CUtlVector<CUtlString> &cmd, const char *szOutput) override;
// sets rpath
// for windows should be ignored
virtual void SetDefaultLibraryPaths( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject ) override;
virtual void UseStdLib( CUtlVector<CUtlString> &cmd, bool bUse ) override;
// windows doesn't use it as well
virtual void UseDynamicLookup( CUtlVector<CUtlString> &cmd, bool bUse ) override;
// includes whole file
virtual void UseFullFile( CUtlVector<CUtlString> &cmd ) override;
// includes used stuff in a file
virtual void UsePartialFile( CUtlVector<CUtlString> &cmd ) override;
virtual void LinkFile( CUtlVector<CUtlString> &cmd, const char *szName ) override;
virtual void LinkLibraryObject( CUtlVector<CUtlString> &cmd, const char *szName ) override;
virtual void LinkLibrary( CUtlVector<CUtlString> &cmd, const char *szName ) override;
virtual void LinkLibraryPath( CUtlVector<CUtlString> &cmd, const char *szName ) override;
}; };
const char *CMSVCLinker::GetCompilerExecutable( LinkProject_t *pProject )
{
}
void CMSVCLinker::SetTarget( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject )
{
}
void CMSVCLinker::SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot )
{
}
void CMSVCLinker::SetOutputFile( CUtlVector<CUtlString> &cmd, const char *szName )
{
}
void CMSVCLinker::SetDefaultLibraryPaths( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject )
{
}
void CMSVCLinker::UseStdLib( CUtlVector<CUtlString> &cmd, bool bUse )
{
}
void CMSVCLinker::UseDynamicLookup( CUtlVector<CUtlString> &cmd, bool bUse )
{
}
void CMSVCLinker::UseFullFile( CUtlVector<CUtlString> &cmd )
{
}
void CMSVCLinker::UsePartialFile( CUtlVector<CUtlString> &cmd )
{
}
void CMSVCLinker::LinkFile( CUtlVector<CUtlString> &cmd, const char *szName )
{
}
void CMSVCLinker::LinkLibraryObject( CUtlVector<CUtlString> &cmd, const char *szName )
{
}
void CMSVCLinker::LinkLibrary( CUtlVector<CUtlString> &cmd, const char *szName )
{
}
void CMSVCLinker::LinkLibraryPath( CUtlVector<CUtlString> &cmd, const char *szName )
{
}
EXPOSE_INTERFACE(CMSVCLinker, ILinker, MSVC_LINKER_INTERFACE_NAME); EXPOSE_INTERFACE(CMSVCLinker, ILinker, MSVC_LINKER_INTERFACE_NAME);
CUtlString CMSVCLinker::Link( LinkProject_t *pProject ) CUtlString CMSVCLinker::Link( LinkProject_t *pProject )

View File

@@ -91,7 +91,7 @@ abstract_class ILinker
public: public:
// Links project // Links project
virtual CUtlString Link( LinkProject_t *pProject ) = 0; virtual CUtlString Link( LinkProject_t *pProject );
virtual bool IsLibraryExists( CUtlString szName ) = 0; virtual bool IsLibraryExists( CUtlString szName ) = 0;
@@ -108,12 +108,12 @@ protected:
virtual void SetTarget( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject ) = 0; virtual void SetTarget( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject ) = 0;
virtual void SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot ) = 0; virtual void SetSysroot( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject , const char *szSysroot ) = 0;
virtual void SetOutputFile( CUtlVector<CUtlString> &cmd ) = 0; virtual void SetOutputFile( CUtlVector<CUtlString> &cmd, const char *szName ) = 0;
// sets rpath // sets rpath
// for windows should be ignored // for windows should be ignored
virtual void SetDefaultLibraryPaths( CUtlVector<CUtlString> &cmd ) = 0; virtual void SetDefaultLibraryPaths( CUtlVector<CUtlString> &cmd, LinkProject_t *pProject ) = 0;
virtual void UseStdLib( CUtlVector<CUtlString> &cmd, bool bUse ) = 0; virtual void UseStdLib( CUtlVector<CUtlString> &cmd, bool bUse ) = 0;