diff --git a/fpc/.fpc/cc/1762019572/build.cpp.o b/fpc/.fpc/cc/1762019572/build.cpp.o new file mode 100644 index 0000000..e6f37d3 Binary files /dev/null and b/fpc/.fpc/cc/1762019572/build.cpp.o differ diff --git a/fpc/.fpc/ld/855499559/libbuild.so b/fpc/.fpc/ld/855499559/libbuild.so new file mode 100644 index 0000000..0049cbc Binary files /dev/null and b/fpc/.fpc/ld/855499559/libbuild.so differ diff --git a/fpc/Makefile b/fpc/Makefile new file mode 100644 index 0000000..c3a87a6 --- /dev/null +++ b/fpc/Makefile @@ -0,0 +1,9 @@ +TIER0_FILES := $(wildcard ../tier0/*.cpp) +TIER1_FILES := $(wildcard ../tier1/*.cpp) +FPC_FILES := main.cpp library/runner.cpp library/helper.cpp library/c.cpp library/ld.cpp +CC = clang +OUTPUT_DIR = ../build/tools/fpc + +full: $(TIER0_FILES) $(TIER1_FILES) $(FPC_FILES) + mkdir -p ../build/tools + $(CC) -g -rdynamic $(TIER0_FILES) $(TIER1_FILES) $(FPC_FILES) -I../public -Ipublic -lc -lstdc++ -o $(OUTPUT_DIR) diff --git a/fpc/build.cpp b/fpc/build.cpp new file mode 100644 index 0000000..5e8c243 --- /dev/null +++ b/fpc/build.cpp @@ -0,0 +1,8 @@ +#include "helper.h" + +int build_fpc() +{ + V_printf("cool\n"); + return 0; +}; +DECLARE_BUILD_STAGE(fpc, build_fpc); diff --git a/fpc/build.sh b/fpc/build.sh deleted file mode 100644 index e69de29..0000000 diff --git a/fpc/library/c.cpp b/fpc/library/c.cpp new file mode 100644 index 0000000..87183c2 --- /dev/null +++ b/fpc/library/c.cpp @@ -0,0 +1,61 @@ +#include "c.h" +#include "filesystem.h" +#include "helper.h" +#include "tier1/utlvector.h" +#include "libgen.h" + +struct ClangFile_t +{ + CUtlString m_szName; + CUtlVector m_szArguments; +}; + +CUtlVector g_clangFiles; + +CLDProject CCProject::Compile() +{ + CLDProject proj = {}; + proj.m_szName = m_szName; + unsigned int hash = GenerateProjectHash(); + for (auto &file: files) + { + CUtlString szOutputFile = CUtlString("%s/cc/%u/%s.o",FPC_TEMPORAL_DIRNAME, hash, file.GetString()); + CUtlString szOutputDir = szOutputFile; + szOutputDir = dirname(szOutputDir); + IFileSystem2::MakeDirectory(szOutputDir); + + CUtlVector args = { + "-c", + "-o", + szOutputFile, + file, + }; + if (bFPIC) + args.AppendTail("-fPIC"); + if (bFPIE) + args.AppendTail("-fPIE"); + for (auto ¯o: macros) + { + args.AppendTail("-D"); + args.AppendTail(CUtlString("%s=%s", (char*)macro.szName, (char*)macro.szValue)); + } + for (auto &include: includeDirectories) + { + args.AppendTail("-I"); + args.AppendTail(include); + } + for (auto &include: includeFiles) + { + args.AppendTail("-include"); + args.AppendTail(include); + } + IRunner::Run("clang", args); + proj.objects.AppendTail((CObject){szOutputFile}); + + ClangFile_t file = {}; + file.m_szName = m_szName; + file.m_szArguments = args; + g_clangFiles.AppendTail(file); + } + return proj; +} diff --git a/fpc/library/helper.cpp b/fpc/library/helper.cpp new file mode 100644 index 0000000..f06c2b8 --- /dev/null +++ b/fpc/library/helper.cpp @@ -0,0 +1,46 @@ +#include "helper.h" +#include "runner.h" +#include "tier0/platform.h" +#include "tier1/utlvector.h" +#include "tier1/utlstring.h" + +unsigned int g_hashState = 102851263; +unsigned int CProject::GenerateProjectHash( void ) +{ + unsigned int hash = 5381+g_hashState; + int c; + char *szName = m_szName; + + while( (c = *szName++) ) + hash = (hash * 33) + c; + + g_hashState = g_hashState * 1664525 + 1013904223; + + return hash; +}; + +void IFileSystem2::MakeDirectory( const char *psz ) +{ + CUtlVector args = { + "-p", + psz, + }; + IRunner::Run("mkdir", args); +}; + +CUtlVector g_buildStages; + +CBuildStage::CBuildStage( CUtlString sz, int(*pMainFn)() ) +{ + m_sz = sz; + m_pMainFn = pMainFn; + if (sz == 0 || pMainFn == 0) + Plat_FatalErrorFunc("Name and function pointer must be set\n"); + + g_buildStages.AppendTail(this); +}; + +CUtlVector& BuildStages() +{ + return g_buildStages; +} diff --git a/fpc/library/ld.cpp b/fpc/library/ld.cpp new file mode 100644 index 0000000..cad8e50 --- /dev/null +++ b/fpc/library/ld.cpp @@ -0,0 +1,42 @@ +#include "ld.h" +#include "libgen.h" + +CUtlString CLDProject::Link( void ) +{ + CUtlString szFileName; + unsigned int hash = GenerateProjectHash(); + switch(linkType) + { + case ELINK_EXECUTABLE: + szFileName = CUtlString("%s", m_szName.GetString()); + break; + case ELINK_STATIC_LIBRARY: + szFileName = CUtlString("lib%s.a", m_szName.GetString()); + break; + case ELINK_DYNAMIC_LIBRARY: + szFileName = CUtlString("lib%s.so", m_szName.GetString()); + break; + } + CUtlString szOutputFile = CUtlString("%s/ld/%u/%s",FPC_TEMPORAL_DIRNAME, hash, szFileName.GetString()); + CUtlString szOutputDir = szOutputFile; + szOutputDir = dirname(szOutputDir); + IFileSystem2::MakeDirectory(szOutputDir); + if (linkType == ELINK_STATIC_LIBRARY) + { + CUtlVector args = { + "rcs", + }; + IRunner::Run("ar", args); + } else { + CUtlVector args = { + "-o", + szOutputFile, + }; + if (linkType == ELINK_DYNAMIC_LIBRARY) + args.AppendTail("-shared"); + for (auto object: objects) + args.AppendTail(object.m_szObjectFile); + IRunner::Run("clang++", args); + } + return szOutputFile; +}; diff --git a/fpc/library/runner.cpp b/fpc/library/runner.cpp new file mode 100644 index 0000000..a3b0241 --- /dev/null +++ b/fpc/library/runner.cpp @@ -0,0 +1,37 @@ +#include "runner.h" +#include "tier0/platform.h" +#include "tier1/utlstring.h" +#include "tier1/utlvector.h" +#include "unistd.h" +#include "sys/wait.h" +int IRunner::Run(CUtlString szName, CUtlVector& args) +{ + pid_t pid = fork(); + if (pid < 0) + Plat_FatalErrorFunc("Failed to fork"); + /* child */ + if (pid == 0) + { + CUtlVector execargs; + execargs.AppendTail(szName); + for (auto &arg: args) + { + execargs.AppendTail(arg); + } + execargs.AppendTail(0); + execvp(szName, (char *const*)execargs.GetData()); + } + /* parent */ + wait(NULL); + return 0; +} + +int IRunner::Run(CUtlString szName, CUtlString szDirectory, CUtlVector& args) +{ +} + +int IRunner::Run(CUtlString szName, CUtlString szDirectory, CUtlVector& args, CUtlVector& environment) +{ + +} + diff --git a/fpc/main.cpp b/fpc/main.cpp index e69de29..1a0775f 100644 --- a/fpc/main.cpp +++ b/fpc/main.cpp @@ -0,0 +1,35 @@ +#include "public/helper.h" +#include "public/ld.h" +#include "tier0/platform.h" +#include "tier1/commandline.h" +#include "c.h" +#include "tier1/utlvector.h" + +int build() +{ + CCProject compileScriptProject = {}; + compileScriptProject.m_szName = "build"; + compileScriptProject.files = {"build.cpp"}; + compileScriptProject.includeDirectories = {"public","../public"}; + compileScriptProject.bFPIC = true; + CLDProject linkScriptProject = compileScriptProject.Compile(); + linkScriptProject.linkType = ELINK_DYNAMIC_LIBRARY; + CUtlString script = linkScriptProject.Link(); + void *scriptDLL = Plat_LoadLibrary(script); + for (auto &build: BuildStages()) + { + build->m_pMainFn(); + }; + Plat_UnloadLibrary(scriptDLL); + + return 0; +}; + + +int main(int c, char **v) +{ + ICommandLine::CreateCommandLine(c, v); + if (ICommandLine::CheckParam("build")) + return build(); + return 0; +}; diff --git a/fpc/public/c.h b/fpc/public/c.h new file mode 100644 index 0000000..d4c4b1a --- /dev/null +++ b/fpc/public/c.h @@ -0,0 +1,29 @@ +#ifndef C_H +#define C_H + +#include "tier1/utlstring.h" +#include "tier1/utlvector.h" +#include "runner.h" +#include "ld.h" +#include "target.h" +#include "helper.h" + +struct C_Macro_t +{ + CUtlString szName; + CUtlString szValue; +}; + +class CCProject : public CProject +{ +public: + CUtlVector files; + CUtlVector macros; + CUtlVector includeDirectories; + CUtlVector includeFiles; + bool bFPIE; + bool bFPIC; + CLDProject Compile(); +}; + +#endif diff --git a/fpc/public/helper.h b/fpc/public/helper.h new file mode 100644 index 0000000..e3d21be --- /dev/null +++ b/fpc/public/helper.h @@ -0,0 +1,38 @@ +#ifndef HELPER_H +#define HELPER_H + +#include "tier1/utlstring.h" + +#define FPC_TEMPORAL_DIRNAME ".fpc" + +class CProject +{ +public: + CUtlString m_szName; + unsigned int GenerateProjectHash( void ); +}; + +interface IFileSystem2 +{ +public: + static void MakeDirectory( const char *psz ); + static void CopyFile( const char *szDestination, const char *szOrigin ); + static void CopyDirectory( const char *szDestination, const char *szOrigin ); +}; + + + +class CBuildStage +{ +public: + CBuildStage( CUtlString sz, int(*pMainFn)() ); + CUtlString m_sz; + int(*m_pMainFn)(); +}; + +#define DECLARE_BUILD_STAGE(sz, fn) \ +CBuildStage __##sz##_build_stage(#sz, fn); + +CUtlVector& BuildStages(); + +#endif diff --git a/fpc/public/ld.h b/fpc/public/ld.h new file mode 100644 index 0000000..03bd731 --- /dev/null +++ b/fpc/public/ld.h @@ -0,0 +1,33 @@ +#ifndef LD_H +#define LD_H + + +#include "runner.h" +#include "helper.h" +#include "obj.h" +#include "tier1/utlstring.h" + +enum ELinkType +{ + ELINK_EXECUTABLE, + ELINK_DYNAMIC_LIBRARY, + ELINK_STATIC_LIBRARY, +}; + +class CLDProject: public CProject +{ +public: + void AddObject( CObject& object ); + void AddLibrary( CUtlString psz ); + void AddLibraryByPath( CUtlString szPath ); + void AddLibraryDirectory( CUtlString szPath ); + CUtlString Link( void ); + + ELinkType linkType; + CUtlVector objects; + CUtlVector libraries; + CUtlVector libraryDirectories; + CUtlVector libraryObjects; +}; + +#endif diff --git a/fpc/public/obj.h b/fpc/public/obj.h new file mode 100644 index 0000000..51cec75 --- /dev/null +++ b/fpc/public/obj.h @@ -0,0 +1,13 @@ +#ifndef OBJ_H +#define OBJ_H + +#include "tier1/utlstring.h" + +class CObject +{ +public: + CUtlString m_szObjectFile; + CUtlString m_szSourceFile; +}; + +#endif diff --git a/fpc/public/runner.h b/fpc/public/runner.h new file mode 100644 index 0000000..817a938 --- /dev/null +++ b/fpc/public/runner.h @@ -0,0 +1,15 @@ +#ifndef RUNNER_H +#define RUNNER_H + +#include "tier1/utlvector.h" +#include "tier1/utlstring.h" + +interface IRunner +{ +public: + static int Run( CUtlString szName, CUtlVector& args ); + static int Run( CUtlString szName, CUtlString szDirectory, CUtlVector& args ); + static int Run( CUtlString szName, CUtlString szDirectory, CUtlVector& args, CUtlVector& environment ); +}; + +#endif diff --git a/fpc/public/target.h b/fpc/public/target.h new file mode 100644 index 0000000..94fc26e --- /dev/null +++ b/fpc/public/target.h @@ -0,0 +1,23 @@ +#ifndef TARGET_T +#define TARGET_T + +enum ETargetKernel +{ + TARGET_KERNEL_LINUX, + TARGET_KERNEL_WINDOWS, +}; + +enum ETargetCPU +{ + TARGET_CPU_AMD64, + TARGET_CPU_I386, +}; + +struct Target_t +{ + ETargetKernel kernel; + ETargetCPU cpu; + static Target_t DefaultTarget(); +}; + +#endif