From f031ed3f7007b27f65be770cdf62280edf9fc92d Mon Sep 17 00:00:00 2001 From: kotofyt Date: Thu, 27 Nov 2025 20:09:11 +0200 Subject: [PATCH] improvements to the fpc --- fpc/library/c.cpp | 69 ++++++++++++++++ fpc/library/clang/c.cpp | 166 +++++++++++++++++++++++++------------- fpc/library/windows/c.cpp | 107 +++++++++++++++++++++--- fpc/library/windows/c.h | 0 fpc/public/c.h | 31 ++++--- 5 files changed, 298 insertions(+), 75 deletions(-) delete mode 100644 fpc/library/windows/c.h diff --git a/fpc/library/c.cpp b/fpc/library/c.cpp index 2a27021..f5be086 100644 --- a/fpc/library/c.cpp +++ b/fpc/library/c.cpp @@ -1,3 +1,72 @@ #include "c.h" +#include "target.h" +#include ICCompiler *ccompiler; + +CUtlString ICCompiler::GetOutputObjectName( CProject_t *pProject, unsigned int hash, CUtlString szFileName ) +{ + CUtlString szTarget = pProject->m_target.GetTriplet(); + return CUtlString("%s/%s/cc/%u_%s/%s/%s%s",FPC_TEMPORAL_DIRNAME, szTarget.GetString(), hash, pProject->m_szName.GetString(), filesystem2->BuildDirectory(), szFileName.GetString(), GetOutputObjectFormat()); +}; + +CUtlVector ICCompiler::BuildCommandLine( CProject_t *pProject, const char *szFileName, const char *szOutputFileName ) +{ + + CUtlVector cmd; + + EnableDebugSymbols(cmd); + if (pProject->bFPIC) + EnablePIC(cmd); + if (pProject->bFPIE) + EnablePIE(cmd); + SetTarget(cmd, pProject); + SetOutputFile(cmd, szOutputFileName); + CompileFile(cmd, szFileName); + for (auto ¯o: pProject->macros) + Macro(cmd, macro.szName, macro.szValue.GetString()); + for (auto &dir: pProject->includeDirectories) + IncludeDirectory(cmd, dir); + + return cmd; +} + +LinkProject_t ICCompiler::Compile( CProject_t *pProject ) +{ + if (pProject->m_szName == 0) + { + Plat_FatalErrorFunc("m_szName must be present\n"); + } + + LinkProject_t proj = {}; + proj.m_szName = pProject->m_szName; + proj.m_target = pProject->m_target; + proj.m_androidmanifest = pProject->m_androidmanifest; + unsigned int hash = pProject->GenerateProjectHash(); + + // Get output directories + for (auto &file: pProject->files) + { + CUtlString szOutputFile = GetOutputObjectName(pProject, hash, file); + CUtlString szOutputDir = szOutputFile; + szOutputDir = dirname(szOutputDir); + filesystem2->MakeDirectory(szOutputDir); + } + + // Run CC + for (auto &file: pProject->files) + { + V_printf(" CC %s\n", file.GetString()); + CUtlString szOutputFile = GetOutputObjectName(pProject, hash, file); + CUtlVector args; + + args = BuildCommandLine(pProject, file, szOutputFile); + if (!filesystem2->ShouldRecompile(file, szOutputFile)) + goto skipcompile; + runner->Run(GetCompilerExecutable(pProject), args); +skipcompile: + proj.objects.AppendTail((Object_t){szOutputFile}); + } + runner->Wait(); + return proj; +} diff --git a/fpc/library/clang/c.cpp b/fpc/library/clang/c.cpp index 207e65a..3221c57 100644 --- a/fpc/library/clang/c.cpp +++ b/fpc/library/clang/c.cpp @@ -22,8 +22,103 @@ class CClangCompiler : public ICCompiler { public: virtual LinkProject_t Compile( CProject_t *pProject ) override; + + virtual void GenerateLinterData() override; +protected: + + virtual CUtlVector BuildCommandLine( CProject_t *pProject, const char *szFileName, const char *szOutputFileName ) override; + + // Returns executable which should the OS run + virtual const char *GetCompilerExecutable( CProject_t *pProject ) override; + + // returns object file format, eg .obj or .o + virtual const char *GetOutputObjectFormat() override; + + virtual void IncludeDirectory( CUtlVector &cmd, const char *szName ) override; + virtual void IncludeFile( CUtlVector &cmd, const char *szName ) override; + virtual void Macro( CUtlVector &cmd, const char *szName ) override; + 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 SetOutputFile( CUtlVector &cmd, const char *szName ) override; + + virtual void EnableDebugSymbols( CUtlVector &cmd ) override; + virtual void EnablePIE( CUtlVector &cmd ) override; + virtual void EnablePIC( CUtlVector &cmd ) override; }; +const char *CClangCompiler::GetOutputObjectFormat() +{ + return ".o"; +} + +CUtlVector CClangCompiler::BuildCommandLine( CProject_t *pProject, const char *szFileName, const char *szOutputFileName ) +{ + CUtlVector cmd; + cmd = ICCompiler::BuildCommandLine(pProject, szFileName, szOutputFileName); + cmd.AppendHead("-c"); + return cmd; +} + + +const char *CClangCompiler::GetCompilerExecutable( CProject_t *pProject ) +{ + return "clang"; +} + + +void CClangCompiler::IncludeDirectory( CUtlVector &cmd, const char *szName ) +{ + cmd.AppendTail("-I"); + cmd.AppendTail(szName); +} + +void CClangCompiler::IncludeFile( CUtlVector &cmd, const char *szName ) +{ +} + +void CClangCompiler::Macro( CUtlVector &cmd, const char *szName ) +{ +} + +void CClangCompiler::Macro( CUtlVector &cmd, const char *szName, const char *szValue ) +{ + cmd.AppendTail("-D"); + cmd.AppendTail(CUtlString("%s=%s", (char*)szName, (char*)szValue)); +} + +void CClangCompiler::EnableDebugSymbols( CUtlVector &cmd ) +{ + cmd.AppendTail("-g"); +} + +void CClangCompiler::SetTarget( CUtlVector &cmd, CProject_t *pProject ) +{ + cmd.AppendTail("-target"); + cmd.AppendTail(pProject->m_target.GetTriplet()); +} + +void CClangCompiler::CompileFile( CUtlVector &cmd, const char *szName ) +{ + cmd.AppendTail(szName); +} +void CClangCompiler::SetOutputFile( CUtlVector &cmd, const char *szName ) +{ + cmd.AppendTail("-o"); + cmd.AppendTail(szName); +} +void CClangCompiler::EnablePIE( CUtlVector &cmd ) +{ + cmd.AppendTail("-fPIE"); +} + +void CClangCompiler::EnablePIC( CUtlVector &cmd ) +{ + cmd.AppendTail("-fPIC"); +} + + EXPOSE_INTERFACE(CClangCompiler, ICCompiler, CLANG_C_COMPILER_INTERFACE_NAME); CUtlVector g_clangFiles; @@ -48,8 +143,7 @@ LinkProject_t CClangCompiler::Compile( CProject_t *pProject ) // Get output directories for (auto &file: pProject->files) { - CUtlString szTarget = pProject->m_target.GetTriplet(); - CUtlString szOutputFile = CUtlString("%s/%s/cc/%u_%s/%s/%s.o",FPC_TEMPORAL_DIRNAME, szTarget.GetString(), hash, pProject->m_szName.GetString(), filesystem2->BuildDirectory(), file.GetString()); + CUtlString szOutputFile = GetOutputObjectName(pProject, hash, file); CUtlString szOutputDir = szOutputFile; szOutputDir = dirname(szOutputDir); filesystem2->MakeDirectory(szOutputDir); @@ -59,11 +153,13 @@ LinkProject_t CClangCompiler::Compile( CProject_t *pProject ) for (auto &file: pProject->files) { V_printf(" CC %s\n", file.GetString()); - + + bool bAreDependenciesUpdated = false; + CUtlString szOutputFile = GetOutputObjectName(pProject, hash, file); CUtlVector args; + /* CUtlString szTarget = pProject->m_target.GetTriplet(); CUtlString szCompiledTarget = szTarget; - bool bAreDependenciesUpdated = false; if (pProject->m_target.kernel == TARGET_KERNEL_ANDROID) { szCompiledTarget = CUtlString("%s%u", szTarget.GetString(), pProject->m_androidmanifest.m_nTargetVersion); @@ -74,13 +170,20 @@ LinkProject_t CClangCompiler::Compile( CProject_t *pProject ) "-target", szCompiledTarget, }; + */ + + /* if (!strcmp(Plat_GetExtension(file),"cpp")) args.AppendTail("-std=c++17"); else if (!strcmp(Plat_GetExtension(file),"mm")) ; else - args.AppendTail("-std=c99"); + args.AppendTail("-std=c99"); + */ + + args = BuildCommandLine(pProject, file, szOutputFile); + /* if (pProject->m_target.kernel == TARGET_KERNEL_DARWIN) { args.AppendTail("-isysroot"); @@ -97,63 +200,16 @@ LinkProject_t CClangCompiler::Compile( CProject_t *pProject ) { args.AppendTail(CUtlString("--sysroot=%s", pProject->m_target.szSysroot)); } + */ - if (pProject->bFPIC) - args.AppendTail("-fPIC"); - if (pProject->bFPIE) - args.AppendTail("-fPIE"); - for (auto ¯o: pProject->macros) - { - args.AppendTail("-D"); - args.AppendTail(CUtlString("%s=%s", (char*)macro.szName, (char*)macro.szValue)); - } - for (auto &include: pProject->includeDirectories) - { - args.AppendTail("-I"); - args.AppendTail(include); - } - for (auto &include: pProject->includeFiles) - { - args.AppendTail("-include"); - args.AppendTail(include); - } - - if (clangbackend) - bAreDependenciesUpdated = clangbackend->AreFileDependenciesUpdated(file, 0, szOutputFile, args); - if (!filesystem2->ShouldRecompile(file, szOutputFile) && !bAreDependenciesUpdated) - goto skipcompile; - - args.AppendTail("-c"); - args.AppendTail("-g"); - args.AppendTail("-o"); - args.AppendTail(szOutputFile); - args.AppendTail(file); - - if (pProject->m_target.kernel == TARGET_KERNEL_ANDROID) - { - if (!pProject->m_target.szSysroot) - Plat_FatalErrorFunc("-sysroot must be specified for android\n"); - runner->Run(CUtlString("%s/bin/clang",pProject->m_target.szSysroot), args); - - } - else - { - runner->Run("clang", args); - } + runner->Run(GetCompilerExecutable(pProject), args); skipcompile: proj.objects.AppendTail((Object_t){szOutputFile}); ClangFile_t cfile = {}; cfile.m_szName = file; cfile.m_szArguments = args; - if (pProject->m_target.kernel == TARGET_KERNEL_ANDROID) - { - if (!pProject->m_target.szSysroot) - Plat_FatalErrorFunc("sysroot must be specified for android\n"); - cfile.m_szArguments.AppendHead(CUtlString("%s/bin/clang",pProject->m_target.szSysroot)); - } - else - cfile.m_szArguments.AppendHead("clang"); + cfile.m_szArguments.AppendHead(GetCompilerExecutable(pProject)); g_clangFiles.AppendTail(cfile); } diff --git a/fpc/library/windows/c.cpp b/fpc/library/windows/c.cpp index 3f698ab..a936822 100644 --- a/fpc/library/windows/c.cpp +++ b/fpc/library/windows/c.cpp @@ -23,14 +23,108 @@ struct ClangFile_t class CMSVCCompiler : public ICCompiler { public: - virtual LinkProject_t Compile( CProject_t *pProject ) override; - virtual void GenerateLinterData( void ) override; + + virtual void GenerateLinterData() override; +protected: + + virtual CUtlVector BuildCommandLine( CProject_t *pProject, const char *szFileName, const char *szOutputFileName ) override; + + // Returns executable which should the OS run + virtual const char *GetCompilerExecutable( CProject_t *pProject ) override; + + // returns object file format, eg .obj or .o + virtual const char *GetOutputObjectFormat() override; + + virtual void IncludeDirectory( CUtlVector &cmd, const char *szName ) override; + virtual void IncludeFile( CUtlVector &cmd, const char *szName ) override; + virtual void Macro( CUtlVector &cmd, const char *szName ) override; + 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 SetOutputFile( CUtlVector &cmd, const char *szName ) override; + + virtual void EnableDebugSymbols( CUtlVector &cmd ) override; + virtual void EnablePIE( CUtlVector &cmd ) override; + virtual void EnablePIC( CUtlVector &cmd ) override; }; +const char *CMSVCCompiler::GetOutputObjectFormat() +{ + return ".o"; +} + +CUtlVector CMSVCCompiler::BuildCommandLine( CProject_t *pProject, const char *szFileName, const char *szOutputFileName ) +{ + CUtlVector cmd; + cmd = ICCompiler::BuildCommandLine(pProject, szFileName, szOutputFileName); + cmd.AppendHead("/c"); + return cmd; +} + + +const char *CMSVCCompiler::GetCompilerExecutable( CProject_t *pProject ) +{ + if (!g_pConfig) + Plat_FatalErrorFunc(".fpccfg was not found\n"); + static IINISection *pSection = g_pConfig->GetSection("MSVC_C_COMPILER_INTERFACE_NAME"); + if (!pSection) + Plat_FatalErrorFunc("MSVC_C_COMPILER_INTERFACE_NAME was not found in .fpccfg\n"); + static CUtlString szExePath = pSection->GetStringValue("exe"); + return szExePath; +} + + +void CMSVCCompiler::IncludeDirectory( CUtlVector &cmd, const char *szName ) +{ + cmd.AppendTail(CUtlString("/I%s",szName)); +} + +void CMSVCCompiler::IncludeFile( CUtlVector &cmd, const char *szName ) +{ +} + +void CMSVCCompiler::Macro( CUtlVector &cmd, const char *szName ) +{ +} + +void CMSVCCompiler::Macro( CUtlVector &cmd, const char *szName, const char *szValue ) +{ + cmd.AppendTail(CUtlString("/D%s=%s", (char*)szName, (char*)szValue)); +} + +void CMSVCCompiler::EnableDebugSymbols( CUtlVector &cmd ) +{ +} + +void CMSVCCompiler::SetTarget( CUtlVector &cmd, CProject_t *pProject ) +{ +} + +void CMSVCCompiler::CompileFile( CUtlVector &cmd, const char *szName ) +{ + cmd.AppendTail(szName); +} +void CMSVCCompiler::SetOutputFile( CUtlVector &cmd, const char *szName ) +{ + cmd.AppendTail("/Fo"); + cmd.AppendTail(szName); +} +void CMSVCCompiler::EnablePIE( CUtlVector &cmd ) +{ +} + +void CMSVCCompiler::EnablePIC( CUtlVector &cmd ) +{ +} + + EXPOSE_INTERFACE(CMSVCCompiler, ICCompiler, MSVC_C_COMPILER_INTERFACE_NAME); /* CUtlVector g_msvcFiles; */ + +/* LinkProject_t CMSVCCompiler::Compile( CProject_t *pProject ) { if (pProject->m_szName == 0) @@ -55,7 +149,6 @@ LinkProject_t CMSVCCompiler::Compile( CProject_t *pProject ) if (!pSection) Plat_FatalErrorFunc("MSVC_C_COMPILER_INTERFACE_NAME was not found in .fpccfg\n"); CUtlString szExePath = pSection->GetStringValue("exe"); - bool bUseClangCL = pSection->GetStringValue("exe"); @@ -87,7 +180,6 @@ LinkProject_t CMSVCCompiler::Compile( CProject_t *pProject ) args = { "/nologo", }; - /* if (!strcmp(Plat_GetExtension(file),"cpp")) args.AppendTail("-std=c++17"); else if (!strcmp(Plat_GetExtension(file),"mm")) @@ -99,7 +191,6 @@ LinkProject_t CMSVCCompiler::Compile( CProject_t *pProject ) args.AppendTail("-fPIC"); if (pProject->bFPIE) args.AppendTail("-fPIE"); - */ for (auto ¯o: pProject->macros) { args.AppendTail(CUtlString("/D%s=%s", (char*)macro.szName, (char*)macro.szValue)); @@ -110,13 +201,11 @@ LinkProject_t CMSVCCompiler::Compile( CProject_t *pProject ) args.AppendTail(CUtlString("/I%s", szWindowsPath)); V_free((void*)szWindowsPath); } - /* for (auto &include: pProject->includeFiles) { args.AppendTail("-include"); args.AppendTail(include); } - */ if (!filesystem2->ShouldRecompile(file, szOutputFile) && !bAreDependenciesUpdated) @@ -142,13 +231,13 @@ skipcompile: else cfile.m_szArguments.AppendHead("clang"); - /* g_clangFiles.AppendTail(cfile); - */ } winerunner->Wait(); return proj; } +*/ + void CMSVCCompiler::GenerateLinterData() { diff --git a/fpc/library/windows/c.h b/fpc/library/windows/c.h deleted file mode 100644 index e69de29..0000000 diff --git a/fpc/public/c.h b/fpc/public/c.h index ea1e537..5d41552 100644 --- a/fpc/public/c.h +++ b/fpc/public/c.h @@ -34,8 +34,8 @@ enum ECVersion // Target C++ version enum ECPPVersion { - CPPVERSION_98 = 1, - CPPVERSION_11 = 0, + CPPVERSION_98 = 0, + CPPVERSION_11 = 1, CPPVERSION_14 = 2, CPPVERSION_17 = 3, CPPVERSION_20 = 4, @@ -94,7 +94,7 @@ public: #define GNU_C_COMPILER_INTERFACE_NAME "GNU" C_COMPILER_INTERFACE_NAME #define MSVC_C_COMPILER_INTERFACE_NAME "MSVC" C_COMPILER_INTERFACE_NAME -abstract_class ICCompiler +class ICCompiler { public: @@ -102,24 +102,33 @@ public: // which can be linked into executable or library. virtual LinkProject_t Compile( CProject_t *pProject ); - + virtual void GenerateLinterData() = 0; protected: // Compiler internals // Returns file name of the - CUtlString GetOutputObjectName( CUtlString szFileName ); + CUtlString GetOutputObjectName( CProject_t *pProject, unsigned int hash, CUtlString szFileName ); - virtual CUtlVector BuildCommandLine( CProject_t *pProject ); + virtual CUtlVector BuildCommandLine( CProject_t *pProject, const char *szFileName, const char *szOutputFileName ); // Returns executable which should the OS run - virtual CUtlString GetCompilerExecutable( CProject_t *pProject ) = 0; + virtual const char *GetCompilerExecutable( CProject_t *pProject ) = 0; + // returns object file format, eg .obj or .o virtual const char *GetOutputObjectFormat() = 0; - virtual bool IncludeDirectory( CUtlVector &cmd ) = 0; - virtual bool IncludeFile( CUtlVector &cmd ) = 0; - virtual void Macro( const char *szName ) = 0; - virtual void Macro( const char *szName, const char *szValue ) = 0; + virtual void IncludeDirectory( CUtlVector &cmd, const char *szName ) = 0; + virtual void IncludeFile( CUtlVector &cmd, const char *szName ) = 0; + virtual void Macro( CUtlVector &cmd, const char *szName ) = 0; + 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 SetOutputFile( CUtlVector &cmd, const char *szName ) = 0; + + virtual void EnableDebugSymbols( CUtlVector &cmd ) = 0; + virtual void EnablePIE( CUtlVector &cmd ) = 0; + virtual void EnablePIC( CUtlVector &cmd ) = 0; }; extern ICCompiler *ccompiler;