mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Initial checkin
This commit is contained in:
parent
c74712dad9
commit
078564ac9e
3242 changed files with 1616395 additions and 0 deletions
93
BeefBoot/BeefBoot.cpp
Normal file
93
BeefBoot/BeefBoot.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
//#define USE_OLD_BEEFBUILD
|
||||
|
||||
#pragma warning(disable:4996)
|
||||
|
||||
#include <iostream>
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BeefySysLib/util/Array.h"
|
||||
#include "BeefySysLib/util/SizedArray.h"
|
||||
#include "BeefySysLib/util/Dictionary.h"
|
||||
#include "BeefySysLib/util/CabUtil.h"
|
||||
#include "BeefySysLib/util/BeefPerf.h"
|
||||
#include "BeefySysLib/util/Deque.h"
|
||||
#include "BeefySysLib/util/HashSet.h"
|
||||
#include "BeefySysLib/util/MultiHashSet.h"
|
||||
|
||||
//#include <mmsystem.h>
|
||||
//#include <shellapi.h>
|
||||
//#include <Objbase.h>
|
||||
|
||||
#define BF_DBG_64
|
||||
#include "IDEHelper/StrHashMap.h"
|
||||
|
||||
using namespace Beefy;
|
||||
|
||||
#include "BootApp.h"
|
||||
|
||||
BF_IMPORT void BF_CALLTYPE Debugger_ProgramDone();
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
BfpSystem_SetCommandLine(argc, argv);
|
||||
|
||||
BfpThread_SetName(NULL, "MainThread", NULL);
|
||||
|
||||
BfpSystem_Init(BFP_VERSION, BfpSystemInitFlag_InstallCrashCatcher);
|
||||
|
||||
gApp = new BootApp();
|
||||
|
||||
bool success = true;
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
std::string arg = argv[i];
|
||||
|
||||
if (arg[0] == '"')
|
||||
{
|
||||
arg.erase(0, 1);
|
||||
if ((arg.length() > 1) && (arg[arg.length() - 1] == '"'))
|
||||
arg.erase(arg.length() - 1);
|
||||
success &= gApp->HandleCmdLine(arg, "");
|
||||
continue;
|
||||
}
|
||||
|
||||
int eqPos = (int)arg.find('=');
|
||||
if (eqPos == -1)
|
||||
{
|
||||
success &= gApp->HandleCmdLine(arg, "");
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string cmd = arg.substr(0, eqPos);
|
||||
std::string param = arg.substr(eqPos + 1);
|
||||
if ((param.length() > 1) && (param[0] == '"'))
|
||||
{
|
||||
param.erase(0, 1);
|
||||
if ((param.length() > 1) && (param[param.length() - 1] == '"'))
|
||||
param.erase(param.length() - 1);
|
||||
}
|
||||
success &= gApp->HandleCmdLine(cmd, param);
|
||||
}
|
||||
|
||||
if (!gApp->mShowedHelp)
|
||||
{
|
||||
if (success)
|
||||
success = gApp->Init();
|
||||
if (success)
|
||||
success = gApp->Compile();
|
||||
|
||||
if (success)
|
||||
gApp->OutputLine("SUCCESS", OutputPri_Critical);
|
||||
else
|
||||
gApp->OutputLine("FAILED", OutputPri_Critical);
|
||||
}
|
||||
|
||||
delete gApp;
|
||||
|
||||
Debugger_ProgramDone();
|
||||
|
||||
BfpSystem_Shutdown();
|
||||
|
||||
BP_SHUTDOWN();
|
||||
|
||||
return success ? 0 : 1;
|
||||
}
|
180
BeefBoot/BeefBoot.h
Normal file
180
BeefBoot/BeefBoot.h
Normal file
|
@ -0,0 +1,180 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BeefySysLib/util/Array.h"
|
||||
#include "BeefySysLib/util/String.h"
|
||||
#include <set>
|
||||
//#include <direct.h>
|
||||
|
||||
#pragma warning(disable:4996)
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
#define APPEND2(VAL1, VAL2) VAL1##VAL2
|
||||
#define APPEND(VAL1, VAL2) APPEND2(VAL1, VAL2)
|
||||
#define ENUM_VAL_GENERATE(ENUM_ENTRY) APPEND(ENUM_TYPE, _##ENUM_ENTRY),
|
||||
#define ENUM_NAME_GENERATE(ENUM_ENTRY) #ENUM_ENTRY,
|
||||
#define ENUM_CREATE_DO2(EnumName) \
|
||||
static const char* EnumName##_Names[] = { ENUM_DECLARE(ENUM_NAME_GENERATE) }; \
|
||||
enum EnumName { ENUM_DECLARE(ENUM_VAL_GENERATE) }; \
|
||||
static bool EnumParse(const String& name, EnumName& result) \
|
||||
{ \
|
||||
for (int i = 0; i < sizeof(EnumName##_Names)/sizeof(const char*); i++) \
|
||||
if (name == EnumName##_Names[i]) { result = (EnumName)i; return true; } \
|
||||
return false; \
|
||||
} \
|
||||
static const char* EnumToString(EnumName enumVal) \
|
||||
{ \
|
||||
return EnumName##_Names[(int)enumVal]; \
|
||||
}
|
||||
#define ENUM_CREATE_DO(EnumType) ENUM_CREATE_DO2(EnumType)
|
||||
#define ENUM_CREATE ENUM_CREATE_DO(ENUM_TYPE)
|
||||
|
||||
class IDEUtils
|
||||
{
|
||||
public:
|
||||
static bool FixFilePath(String& filePath)
|
||||
{
|
||||
if (filePath.length() == 0)
|
||||
return false;
|
||||
|
||||
if (filePath[0] == '<')
|
||||
return false;
|
||||
|
||||
if ((filePath.length() > 1) && (filePath[1] == ':'))
|
||||
filePath[0] = tolower(filePath[0]);
|
||||
|
||||
bool prevWasSlash = false;
|
||||
for (int i = 0; i < filePath.length(); i++)
|
||||
{
|
||||
//if ((filePath[i] == '/') && (filePath[i - 1])
|
||||
|
||||
if (filePath[i] == DIR_SEP_CHAR_ALT)
|
||||
filePath[i] = DIR_SEP_CHAR;
|
||||
|
||||
if (filePath[i] == DIR_SEP_CHAR)
|
||||
{
|
||||
if ((prevWasSlash) && (i > 1))
|
||||
{
|
||||
filePath.Remove(i, 1);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
prevWasSlash = true;
|
||||
}
|
||||
else
|
||||
prevWasSlash = false;
|
||||
|
||||
if ((i >= 4) && (filePath[i - 3] == DIR_SEP_CHAR) && (filePath[i - 2] == '.') && (filePath[i - 1] == '.') && (filePath[i] == DIR_SEP_CHAR))
|
||||
{
|
||||
int prevSlash = (int)filePath.LastIndexOf(DIR_SEP_CHAR, i - 4);
|
||||
if (prevSlash != -1)
|
||||
{
|
||||
filePath.Remove(prevSlash, i - prevSlash);
|
||||
i = prevSlash;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void GetDirWithSlash(String& dirName)
|
||||
{
|
||||
if (dirName.length() == 0)
|
||||
return;
|
||||
char lastC = dirName[dirName.length() - 1];
|
||||
if ((lastC != '\\') && (lastC != '/'))
|
||||
dirName += DIR_SEP_CHAR;
|
||||
}
|
||||
|
||||
static FILE* CreateFileWithDir(const String& fileName, const char* options)
|
||||
{
|
||||
FILE* fp = fopen(fileName.c_str(), options);
|
||||
if (fp == NULL)
|
||||
{
|
||||
String fileDir = GetFileDir(fileName);
|
||||
if (!fileDir.empty())
|
||||
{
|
||||
RecursiveCreateDirectory(fileDir);
|
||||
fp = fopen(fileName.c_str(), "w");
|
||||
}
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
static bool WriteAllText(const String& fileName, const String& data)
|
||||
{
|
||||
FILE* fp = CreateFileWithDir(fileName, "w");
|
||||
if (fp == NULL)
|
||||
return false;
|
||||
fwrite(data.c_str(), 1, data.length(), fp);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void GetFileNameWithoutExtension(const String& filePath, String& outFileName)
|
||||
{
|
||||
outFileName += GetFileName(filePath);
|
||||
int dot = (int)outFileName.LastIndexOf('.');
|
||||
if (dot != -1)
|
||||
outFileName.RemoveToEnd(dot);
|
||||
}
|
||||
|
||||
static void GetExtension(const String& filePath, String& ext)
|
||||
{
|
||||
int idx = (int)filePath.LastIndexOf('.');
|
||||
if (idx != -1)
|
||||
ext = filePath.Substring(idx);
|
||||
}
|
||||
|
||||
static void AppendWithOptionalQuotes(String& targetStr, const String& srcFileName)
|
||||
{
|
||||
if ((int)srcFileName.IndexOf(' ') == -1)
|
||||
targetStr += srcFileName;
|
||||
else
|
||||
targetStr += "\"" + srcFileName + "\"";
|
||||
}
|
||||
};
|
||||
|
||||
class ArgBuilder
|
||||
{
|
||||
public:
|
||||
String* mTarget;
|
||||
bool mDoLongBreak;
|
||||
int mLastBreak;
|
||||
std::multiset<String> mLinkPaths;
|
||||
|
||||
public:
|
||||
ArgBuilder(String& target, bool doLongBreak)
|
||||
{
|
||||
mTarget = ⌖
|
||||
mDoLongBreak = doLongBreak;
|
||||
if (mDoLongBreak)
|
||||
mLastBreak = (int)mTarget->LastIndexOf('\n');
|
||||
else
|
||||
mLastBreak = 0;
|
||||
}
|
||||
|
||||
void AddSep()
|
||||
{
|
||||
if (mDoLongBreak)
|
||||
{
|
||||
if (mTarget->length() - mLastBreak > 0x1F000)
|
||||
{
|
||||
mLastBreak = (int)mTarget->length();
|
||||
mTarget->Append('\n');
|
||||
return;
|
||||
}
|
||||
}
|
||||
mTarget->Append(' ');
|
||||
}
|
||||
|
||||
void AddFileName(const String& filePath)
|
||||
{
|
||||
IDEUtils::AppendWithOptionalQuotes(*mTarget, filePath);
|
||||
}
|
||||
};
|
||||
|
||||
NS_BF_END
|
||||
|
177
BeefBoot/BeefBoot.vcxproj
Normal file
177
BeefBoot/BeefBoot.vcxproj
Normal file
|
@ -0,0 +1,177 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{755663F3-7C3F-4321-ABFF-CB036C0F2C9F}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>BeefBoot</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\ide\dist\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>$(ProjectName)_d</TargetName>
|
||||
<OutDir>$(SolutionDir)\ide\dist\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\ide\dist\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\ide\dist\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_8_0_0\llvm\include;..\extern\llvm_win64_8_0_0\include;..\extern\llvm-project_8_0_0\llvm\lib\Target;..\extern\llvm_win64_8_0_0\lib\Target\X86;..\extern\llvm-project_8_0_0\llvm\tools\clang\include</AdditionalIncludeDirectories>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OutputFile>$(SolutionDir)\ide\dist\$(TargetName).exe</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<AdditionalIncludeDirectories>../;../IDEHelper;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_8_0_0\llvm\include;..\extern\llvm_win64_8_0_0\include;..\extern\llvm-project_8_0_0\llvm\lib\Target;..\extern\llvm_win64_8_0_0\lib\Target\X86;..\extern\llvm\tools\clang\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OutputFile>$(SolutionDir)\ide\dist\$(TargetName).exe</OutputFile>
|
||||
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BeefBoot.cpp" />
|
||||
<ClCompile Include="BootApp.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BeefySysLib\BeefySysLib_static.vcxproj">
|
||||
<Project>{eceab68d-2f15-495f-a29c-5ea9548aa23d}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\IDEHelper\IDEHelper.vcxproj">
|
||||
<Project>{f8d29c38-d37c-4af2-8540-2f6e543264f1}</Project>
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BeefBoot.h" />
|
||||
<ClInclude Include="BootApp.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
33
BeefBoot/BeefBoot.vcxproj.filters
Normal file
33
BeefBoot/BeefBoot.vcxproj.filters
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BeefBoot.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BootApp.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BootApp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BeefBoot.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
841
BeefBoot/BootApp.cpp
Normal file
841
BeefBoot/BootApp.cpp
Normal file
|
@ -0,0 +1,841 @@
|
|||
#pragma warning(disable:4996)
|
||||
|
||||
//#define BFBUILD_MAIN_THREAD_COMPILE
|
||||
|
||||
#include "BootApp.h"
|
||||
#include <iostream>
|
||||
#include "BeefySysLib/util/String.h"
|
||||
#include "BeefySysLib/util/FileEnumerator.h"
|
||||
#include "BeefySysLib/util/WorkThread.h"
|
||||
#include "BeefySysLib/platform/PlatformHelper.h"
|
||||
#include "Compiler/BfSystem.h"
|
||||
|
||||
#ifdef BF_PLATFORM_WINDOWS
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
BF_IMPORT void BF_CALLTYPE Targets_Create();
|
||||
BF_IMPORT void BF_CALLTYPE Targets_Delete();
|
||||
|
||||
BF_IMPORT void BF_CALLTYPE BfSystem_ReportMemory(void* bfSystem);
|
||||
BF_EXPORT void BF_CALLTYPE BfCompiler_ProgramDone();
|
||||
|
||||
BF_IMPORT void BF_CALLTYPE Debugger_FullReportMemory();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum BfCompilerOptionFlags
|
||||
{
|
||||
BfCompilerOptionFlag_None = 0,
|
||||
BfCompilerOptionFlag_EmitDebugInfo = 1,
|
||||
BfCompilerOptionFlag_EmitLineInfo = 2,
|
||||
BfCompilerOptionFlag_WriteIR = 4,
|
||||
BfCompilerOptionFlag_GenerateOBJ = 8,
|
||||
BfCompilerOptionFlag_NoFramePointerElim = 0x10,
|
||||
BfCompilerOptionFlag_ClearLocalVars = 0x20,
|
||||
BfCompilerOptionFlag_ArrayBoundsCheck = 0x40,
|
||||
BfCompilerOptionFlag_EmitDynamicCastCheck = 0x80,
|
||||
BfCompilerOptionFlag_EnableObjectDebugFlags = 0x100,
|
||||
BfCompilerOptionFlag_EmitObjectAccessCheck = 0x200,
|
||||
BfCompilerOptionFlag_EnableCustodian = 0x400,
|
||||
BfCompilerOptionFlag_EnableRealtimeLeakCheck = 0x800,
|
||||
BfCompilerOptionFlag_EnableSideStack = 0x1000,
|
||||
BfCompilerOptionFlag_EnableHotSwapping = 0x2000
|
||||
};
|
||||
|
||||
BF_IMPORT void BF_CALLTYPE BfCompiler_Delete(void* bfCompiler);
|
||||
BF_EXPORT void BF_CALLTYPE BfCompiler_SetOptions(void* bfCompiler, void* hotProject, int hotIdx,
|
||||
int machineType, int toolsetType, int simdSetting, int allocStackCount, int maxWorkerThreads,
|
||||
BfCompilerOptionFlags optionFlags, const char* mallocLinkName, const char* freeLinkName);
|
||||
BF_IMPORT void BF_CALLTYPE BfCompiler_ClearBuildCache(void* bfCompiler);
|
||||
BF_IMPORT bool BF_CALLTYPE BfCompiler_Compile(void* bfCompiler, void* bfPassInstance, const char* outputPath);
|
||||
BF_IMPORT float BF_CALLTYPE BfCompiler_GetCompletionPercentage(void* bfCompiler);
|
||||
BF_IMPORT const char* BF_CALLTYPE BfCompiler_GetOutputFileNames(void* bfCompiler, void* bfProject, bool* hadOutputChanges);
|
||||
BF_IMPORT const char* BF_CALLTYPE BfCompiler_GetUsedOutputFileNames(void* bfCompiler, void* bfProject, bool flushQueuedHotFiles, bool* hadOutputChanges);
|
||||
|
||||
BF_IMPORT void* BF_CALLTYPE BfSystem_CreateParser(void* bfSystem, void* bfProject);
|
||||
BF_IMPORT void BF_CALLTYPE BfParser_SetSource(void* bfParser, const char* data, int length, const char* fileName);
|
||||
BF_IMPORT void BF_CALLTYPE BfParser_SetCharIdData(void* bfParser, uint8* data, int length);
|
||||
BF_IMPORT bool BF_CALLTYPE BfParser_Parse(void* bfParser, void* bfPassInstance, bool compatMode);
|
||||
BF_IMPORT bool BF_CALLTYPE BfParser_Reduce(void* bfParser, void* bfPassInstance);
|
||||
BF_IMPORT bool BF_CALLTYPE BfParser_BuildDefs(void* bfParser, void* bfPassInstance, void* resolvePassData, bool fullRefresh);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BF_IMPORT void* BF_CALLTYPE BfSystem_Create();
|
||||
BF_IMPORT void BF_CALLTYPE BfSystem_ReportMemory(void* bfSystem);
|
||||
BF_IMPORT void BF_CALLTYPE BfSystem_Delete(void* bfSystem);
|
||||
BF_IMPORT void* BF_CALLTYPE BfSystem_CreatePassInstance(void* bfSystem);
|
||||
BF_IMPORT void* BF_CALLTYPE BfSystem_CreateCompiler(void* bfSystem, bool isResolveOnly);
|
||||
BF_IMPORT void* BF_CALLTYPE BfSystem_CreateProject(void* bfSystem, const char* projectName);
|
||||
BF_IMPORT void BF_CALLTYPE BfParser_Delete(void* bfParser);
|
||||
BF_IMPORT void BF_CALLTYPE BfSystem_AddTypeOptions(void* bfSystem, const char* filter, int32 simdSetting, int32 optimizationLevel, int32 emitDebugInfo, int32 arrayBoundsCheck,
|
||||
int32 initLocalVariables, int32 emitDynamicCastCheck, int32 emitObjectAccessCheck, int32 allocStackTraceDepth);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BF_IMPORT void BF_CALLTYPE BfProject_SetDisabled(void* bfProject, bool disabled);
|
||||
BF_IMPORT void BF_CALLTYPE BfProject_SetOptions(void* bfProject, int targetType, const char* startupObject, const char* preprocessorMacros,
|
||||
int optLevel, int ltoType, bool mergeFunctions, bool combineLoads, bool vectorizeLoops, bool vectorizeSLP);
|
||||
BF_IMPORT void BF_CALLTYPE BfProject_ClearDependencies(void* bfProject);
|
||||
BF_IMPORT void BF_CALLTYPE BfProject_AddDependency(void* bfProject, void* depProject);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BF_IMPORT const char* BF_CALLTYPE BfPassInstance_PopOutString(void* bfPassInstance);
|
||||
BF_IMPORT void BF_CALLTYPE BfPassInstance_Delete(void* bfPassInstance);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BF_IMPORT const char* BF_CALLTYPE VSSupport_Find();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
BootApp* Beefy::gApp = NULL;
|
||||
uint32 gConsoleFGColor = 0;
|
||||
uint32 gConsoleBGColor = 0;
|
||||
|
||||
static bool GetConsoleColor(uint32& fgColor, uint32& bgColor)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
static uint32 consoleColors[16] = { 0xff000000, 0xff000080, 0xff008000, 0xff008080, 0xff800000, 0xff800080, 0xff808000, 0xffc0c0c0,
|
||||
0xff808080, 0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff };
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO screenBuffInfo = { 0 };
|
||||
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &screenBuffInfo);
|
||||
fgColor = consoleColors[screenBuffInfo.wAttributes & 0xF];
|
||||
bgColor = consoleColors[(screenBuffInfo.wAttributes >> 4) & 0xF];
|
||||
return true;
|
||||
#else
|
||||
fgColor = 0xFF808080;
|
||||
bgColor = 0xFF000000;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static WORD GetColorCode(uint32 color)
|
||||
{
|
||||
WORD code = 0;
|
||||
#ifdef _WIN32
|
||||
if (((color >> 0) & 0xFF) > 0x40)
|
||||
code |= FOREGROUND_BLUE;
|
||||
if (((color >> 8) & 0xFF) > 0x40)
|
||||
code |= FOREGROUND_GREEN;
|
||||
if (((color >> 16) & 0xFF) > 0x40)
|
||||
code |= FOREGROUND_RED;
|
||||
if ((((color >> 0) & 0xFF) > 0xC0) ||
|
||||
(((color >> 8) & 0xFF) > 0xC0) ||
|
||||
(((color >> 16) & 0xFF) > 0xC0))
|
||||
code |= FOREGROUND_INTENSITY;
|
||||
#endif
|
||||
return code;
|
||||
}
|
||||
|
||||
static bool SetConsoleColor(uint32 fgColor, uint32 bgColor)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WORD attr = GetColorCode(fgColor) | (GetColorCode(bgColor) << 4);
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attr);
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), attr);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BootApp::BootApp()
|
||||
{
|
||||
Targets_Create();
|
||||
|
||||
mVerbosity = Verbosity_Normal;
|
||||
mTargetType = BfTargetType_BeefConsoleApplication;
|
||||
|
||||
//char str[MAX_PATH];
|
||||
//GetModuleFileNameA(NULL, str, MAX_PATH);
|
||||
//mInstallDir = GetFileDir(str) + "/";
|
||||
|
||||
//getcwd(str, MAX_PATH);
|
||||
//mStartupDir = str;
|
||||
//mStartupDir += "/";
|
||||
|
||||
//mDoClean = false;
|
||||
mHadCmdLine = false;
|
||||
mShowedHelp = false;
|
||||
mHadErrors = false;
|
||||
|
||||
mSystem = NULL;
|
||||
mCompiler = NULL;
|
||||
mProject = NULL;
|
||||
|
||||
#ifdef BF_PLATFORM_WINDOWS
|
||||
mOptLevel = BfOptLevel_OgPlus;
|
||||
mToolset = BfToolsetType_Microsoft;
|
||||
#else
|
||||
mOptLevel = BfOptLevel_O0;
|
||||
mToolset = BfToolsetType_GNU;
|
||||
#endif
|
||||
mEmitIR = false;
|
||||
|
||||
GetConsoleColor(gConsoleFGColor, gConsoleBGColor);
|
||||
}
|
||||
|
||||
BootApp::~BootApp()
|
||||
{
|
||||
Targets_Delete();
|
||||
}
|
||||
|
||||
void BootApp::OutputLine(const String& text, OutputPri outputPri)
|
||||
{
|
||||
if (mLogFile.IsOpen())
|
||||
{
|
||||
mLogFile.WriteSNZ(text);
|
||||
mLogFile.WriteSNZ("\n");
|
||||
}
|
||||
|
||||
if (outputPri == OutputPri_Error)
|
||||
mHadErrors = true;
|
||||
|
||||
switch (outputPri)
|
||||
{
|
||||
case OutputPri_Low:
|
||||
if (mVerbosity < Verbosity_Detailed)
|
||||
return;
|
||||
break;
|
||||
case OutputPri_Normal:
|
||||
if (mVerbosity < Verbosity_Normal)
|
||||
return;
|
||||
break;
|
||||
case OutputPri_High:
|
||||
case OutputPri_Warning:
|
||||
case OutputPri_Error:
|
||||
if (mVerbosity < Verbosity_Minimal)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
if (outputPri == OutputPri_Warning)
|
||||
{
|
||||
SetConsoleColor(0xFFFFFF00, gConsoleBGColor);
|
||||
std::cerr << text.c_str() << std::endl;
|
||||
SetConsoleColor(gConsoleFGColor, gConsoleBGColor);
|
||||
}
|
||||
else if (outputPri == OutputPri_Error)
|
||||
{
|
||||
SetConsoleColor(0xFFFF0000, gConsoleBGColor);
|
||||
std::cerr << text.c_str() << std::endl;
|
||||
SetConsoleColor(gConsoleFGColor, gConsoleBGColor);
|
||||
}
|
||||
else
|
||||
std::cout << text.c_str() << std::endl;
|
||||
}
|
||||
|
||||
void BootApp::Fail(const String& error)
|
||||
{
|
||||
if (mLogFile.IsOpen())
|
||||
mLogFile.WriteSNZ("FAIL: " + error + "\n");
|
||||
std::cerr << "FAIL: " << error.c_str() << std::endl;
|
||||
mHadErrors = true;
|
||||
}
|
||||
|
||||
bool BootApp::HandleCmdLine(const String &cmd, const String& param)
|
||||
{
|
||||
mHadCmdLine = true;
|
||||
|
||||
bool wantedParam = false;
|
||||
|
||||
if ((cmd == "--help") || (cmd == "-h") || (cmd == "/?"))
|
||||
{
|
||||
mShowedHelp = true;
|
||||
std::cout << "BeefBoot - Beef bootstrapping tool" << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (cmd == "--src")
|
||||
{
|
||||
mRequestedSrc.Add(param);
|
||||
wantedParam = true;
|
||||
}
|
||||
else if (cmd == "--verbosity")
|
||||
{
|
||||
if (param == "quiet")
|
||||
mVerbosity = Verbosity_Quiet;
|
||||
else if (param == "minimal")
|
||||
mVerbosity = Verbosity_Minimal;
|
||||
else if (param == "normal")
|
||||
mVerbosity = Verbosity_Normal;
|
||||
else if (param == "detailed")
|
||||
mVerbosity = Verbosity_Detailed;
|
||||
else if (param == "diagnostic")
|
||||
mVerbosity = Verbosity_Diagnostic;
|
||||
else
|
||||
{
|
||||
Fail(StrFormat("Invalid verbosity level: '%s'", param.c_str()));
|
||||
return false;
|
||||
}
|
||||
wantedParam = true;
|
||||
}
|
||||
else if (cmd == "--define")
|
||||
{
|
||||
if (!mDefines.IsEmpty())
|
||||
mDefines += "\n";
|
||||
mDefines += param;
|
||||
wantedParam = true;
|
||||
}
|
||||
else if (cmd == "--startup")
|
||||
{
|
||||
mStartupObject = param;
|
||||
wantedParam = true;
|
||||
}
|
||||
else if (cmd == "--out")
|
||||
{
|
||||
mTargetPath = param;
|
||||
wantedParam = true;
|
||||
}
|
||||
else if (cmd == "--linkparams")
|
||||
{
|
||||
mLinkParams = param;
|
||||
wantedParam = true;
|
||||
}
|
||||
else if (cmd == "-Og+")
|
||||
{
|
||||
mOptLevel = BfOptLevel_OgPlus;
|
||||
}
|
||||
else if (cmd == "-O0")
|
||||
{
|
||||
mOptLevel = BfOptLevel_O0;
|
||||
}
|
||||
else if (cmd == "-O1")
|
||||
{
|
||||
mOptLevel = BfOptLevel_O1;
|
||||
}
|
||||
else if (cmd == "-O2")
|
||||
{
|
||||
mOptLevel = BfOptLevel_O2;
|
||||
}
|
||||
else if (cmd == "-O3")
|
||||
{
|
||||
mOptLevel = BfOptLevel_O3;
|
||||
}
|
||||
else if (cmd == "-gnu")
|
||||
{
|
||||
mToolset = BfToolsetType_GNU;
|
||||
}
|
||||
else if (cmd == "-emitir")
|
||||
{
|
||||
mEmitIR = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fail("Unknown option: " + cmd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((wantedParam) && (param.empty()))
|
||||
{
|
||||
Fail(StrFormat("Parameter expected for '%s'", cmd.c_str()));
|
||||
return false;
|
||||
}
|
||||
else if ((!wantedParam) && (!param.empty()))
|
||||
{
|
||||
Fail(StrFormat("No parameter expected for '%s'", cmd.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BootApp::Init()
|
||||
{
|
||||
char* cwdPtr = getcwd(NULL, 0);
|
||||
mWorkingDir = cwdPtr;
|
||||
free(cwdPtr);
|
||||
|
||||
if (mTargetPath.IsEmpty())
|
||||
{
|
||||
Fail("'Out' path not specified");
|
||||
}
|
||||
|
||||
if (mRequestedSrc.IsEmpty())
|
||||
{
|
||||
Fail("No source specified");
|
||||
}
|
||||
|
||||
return !mHadErrors;
|
||||
}
|
||||
|
||||
void BootApp::QueueFile(const StringImpl& path)
|
||||
{
|
||||
String ext;
|
||||
ext = GetFileExtension(path);
|
||||
if ((ext.Equals(".bf", StringImpl::CompareKind_OrdinalIgnoreCase)) ||
|
||||
(ext.Equals(".cs", StringImpl::CompareKind_OrdinalIgnoreCase)))
|
||||
{
|
||||
int len;
|
||||
const char* data = LoadTextData(path, &len);
|
||||
if (data == NULL)
|
||||
{
|
||||
Fail(StrFormat("Unable to load file '%s'", path.c_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
bool worked = true;
|
||||
void* bfParser = BfSystem_CreateParser(mSystem, mProject);
|
||||
BfParser_SetSource(bfParser, data, len, path.c_str());
|
||||
//bfParser.SetCharIdData(charIdData);
|
||||
worked &= BfParser_Parse(bfParser, mPassInstance, false);
|
||||
worked &= BfParser_Reduce(bfParser, mPassInstance);
|
||||
worked &= BfParser_BuildDefs(bfParser, mPassInstance, NULL, false);
|
||||
|
||||
delete data;
|
||||
}
|
||||
}
|
||||
|
||||
void BootApp::QueuePath(const StringImpl& path)
|
||||
{
|
||||
if (DirectoryExists(path))
|
||||
{
|
||||
for (auto& fileEntry : FileEnumerator(path, FileEnumerator::Flags_Files))
|
||||
{
|
||||
String filePath = fileEntry.GetFilePath();
|
||||
|
||||
String fileName;
|
||||
fileName = GetFileName(filePath);
|
||||
|
||||
QueueFile(filePath);
|
||||
}
|
||||
|
||||
for (auto& fileEntry : FileEnumerator(path, FileEnumerator::Flags_Directories))
|
||||
{
|
||||
String childPath = fileEntry.GetFilePath();
|
||||
String dirName;
|
||||
dirName = GetFileName(childPath);
|
||||
|
||||
if (dirName == "build")
|
||||
continue;
|
||||
|
||||
QueuePath(childPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QueueFile(path);
|
||||
}
|
||||
}
|
||||
|
||||
static void CompileThread(void* param)
|
||||
{
|
||||
BfpThread_SetName(NULL, "CompileThread", NULL);
|
||||
|
||||
BootApp* app = (BootApp*)param;
|
||||
BfCompiler_ClearBuildCache(app->mCompiler);
|
||||
|
||||
if (!BfCompiler_Compile(app->mCompiler, app->mPassInstance, app->mBuildDir.c_str()))
|
||||
app->mHadErrors = true;
|
||||
}
|
||||
|
||||
void BootApp::DoCompile()
|
||||
{
|
||||
#ifdef BFBUILD_MAIN_THREAD_COMPILE
|
||||
mOutputDirectory = outputDirectory;
|
||||
CompileThread(this);
|
||||
#else
|
||||
|
||||
WorkThreadFunc workThread;
|
||||
workThread.Start(CompileThread, this);
|
||||
|
||||
int lastProgressTicks = 0;
|
||||
|
||||
bool showProgress = mVerbosity >= Verbosity_Normal;
|
||||
|
||||
int progressSize = 30;
|
||||
if (showProgress)
|
||||
{
|
||||
std::cout << "[";
|
||||
for (int i = 0; i < progressSize; i++)
|
||||
std::cout << " ";
|
||||
std::cout << "]";
|
||||
for (int i = 0; i < progressSize + 1; i++)
|
||||
std::cout << "\b";
|
||||
std::cout.flush();
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
bool isDone = workThread.WaitForFinish(100);
|
||||
|
||||
float pct = BfCompiler_GetCompletionPercentage(mCompiler);
|
||||
if (isDone)
|
||||
pct = 1.0;
|
||||
int progressTicks = (int)(pct * progressSize + 0.5f);
|
||||
|
||||
while (progressTicks > lastProgressTicks)
|
||||
{
|
||||
if (showProgress)
|
||||
{
|
||||
std::cout << "*";
|
||||
std::cout.flush();
|
||||
}
|
||||
lastProgressTicks++;
|
||||
}
|
||||
|
||||
if (isDone)
|
||||
break;
|
||||
}
|
||||
|
||||
if (showProgress)
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct OutputContext
|
||||
{
|
||||
bool mIsError;
|
||||
BfpFile* mFile;
|
||||
};
|
||||
|
||||
static void OutputThread(void* param)
|
||||
{
|
||||
OutputContext* context = (OutputContext*)param;
|
||||
|
||||
String queuedStr;
|
||||
|
||||
while (true)
|
||||
{
|
||||
char data[1024];
|
||||
|
||||
BfpFileResult result;
|
||||
int bytesRead = (int)BfpFile_Read(context->mFile, data, 1023, -1, &result);
|
||||
if ((result != BfpFileResult_Ok) && (result != BfpFileResult_PartialData))
|
||||
return;
|
||||
|
||||
data[bytesRead] = 0;
|
||||
if (context->mIsError)
|
||||
{
|
||||
std::cerr << data;
|
||||
std::cerr.flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << data;
|
||||
std::cout.flush();
|
||||
}
|
||||
|
||||
if (gApp->mLogFile.IsOpen())
|
||||
{
|
||||
// This is to ensure that error and output lines are not merged together, though they may interleave
|
||||
queuedStr.Append(data, bytesRead);
|
||||
while (true)
|
||||
{
|
||||
int crPos = (int)queuedStr.IndexOf('\n');
|
||||
if (crPos == -1)
|
||||
break;
|
||||
|
||||
AutoCrit autoCrit(gApp->mLogCritSect);
|
||||
if (context->mIsError)
|
||||
gApp->mLogFile.WriteSNZ("err> ");
|
||||
else
|
||||
gApp->mLogFile.WriteSNZ("out> ");
|
||||
|
||||
int endPos = crPos;
|
||||
if ((endPos > 0) && (queuedStr[endPos - 1] == '\r'))
|
||||
endPos--;
|
||||
gApp->mLogFile.Write((void*)queuedStr.c_str(), endPos);
|
||||
gApp->mLogFile.WriteSNZ("\n");
|
||||
queuedStr.Remove(0, crPos + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BootApp::QueueRun(const String& fileName, const String& args, const String& workingDir, BfpSpawnFlags extraFlags)
|
||||
{
|
||||
OutputLine(StrFormat("EXECUTING: %s %s", fileName.c_str(), args.c_str()), OutputPri_Low);
|
||||
|
||||
BfpSpawnFlags spawnFlags = (BfpSpawnFlags)(BfpSpawnFlag_NoWindow | BfpSpawnFlag_RedirectStdOutput | BfpSpawnFlag_RedirectStdError | extraFlags);
|
||||
BfpSpawn* spawn = BfpSpawn_Create(fileName.c_str(), args.c_str(), workingDir.c_str(), NULL, spawnFlags, NULL);
|
||||
if (spawn == NULL)
|
||||
{
|
||||
Fail(StrFormat("Failed to execute '%s'", fileName.c_str()));
|
||||
return false;
|
||||
}
|
||||
int exitCode = 0;
|
||||
|
||||
OutputContext outputContext;;
|
||||
outputContext.mIsError = false;
|
||||
OutputContext errorContext;
|
||||
errorContext.mIsError = false;
|
||||
BfpSpawn_GetStdHandles(spawn, NULL, &outputContext.mFile, &errorContext.mFile);
|
||||
|
||||
BfpThread* outputThread = BfpThread_Create(OutputThread, (void*)&outputContext);
|
||||
BfpThread* errorThread = BfpThread_Create(OutputThread, (void*)&errorContext);
|
||||
|
||||
BfpSpawn_WaitFor(spawn, -1, &exitCode, NULL);
|
||||
|
||||
if (outputContext.mFile != NULL)
|
||||
BfpFile_Close(outputContext.mFile, NULL);
|
||||
if (errorContext.mFile != NULL)
|
||||
BfpFile_Close(errorContext.mFile, NULL);
|
||||
|
||||
BfpThread_WaitFor(outputThread, -1);
|
||||
BfpThread_WaitFor(errorThread, -1);
|
||||
|
||||
BfpThread_Release(outputThread);
|
||||
BfpThread_Release(errorThread);
|
||||
BfpSpawn_Release(spawn);
|
||||
|
||||
if (exitCode != 0)
|
||||
{
|
||||
Fail(StrFormat("Exit code returned: %d", exitCode));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef BF_PLATFORM_WINDOWS
|
||||
void BootApp::DoLinkMS()
|
||||
{
|
||||
String vsStr = VSSupport_Find();
|
||||
|
||||
int toolIdx = (int)vsStr.IndexOf("TOOL64\t");
|
||||
int toolCrIdx = (int)vsStr.IndexOf('\n', toolIdx + 1);
|
||||
if ((toolIdx == -1) || (toolCrIdx == -1))
|
||||
{
|
||||
Fail("Failed to detect Visual Studio configuration. Is Visual Studio 2015 or later installed?");
|
||||
return;
|
||||
}
|
||||
|
||||
String linkerPath = vsStr.Substring(toolIdx + 7, toolCrIdx - toolIdx - 7);
|
||||
linkerPath.Append("\\link.exe");
|
||||
|
||||
String linkLine;
|
||||
|
||||
String targetPath = mTargetPath;
|
||||
|
||||
bool hadOutputChanges;
|
||||
const char* result = BfCompiler_GetUsedOutputFileNames(mCompiler, mProject, true, &hadOutputChanges);
|
||||
if (result == NULL)
|
||||
return;
|
||||
std::string fileNamesStr;
|
||||
fileNamesStr += result;
|
||||
if (fileNamesStr.length() == 0)
|
||||
return;
|
||||
int curIdx = -1;
|
||||
while (curIdx < (int)fileNamesStr.length())
|
||||
{
|
||||
int nextBr = (int)fileNamesStr.find('\n', curIdx + 1);
|
||||
if (nextBr == -1)
|
||||
nextBr = (int)fileNamesStr.length();
|
||||
linkLine.Append(fileNamesStr.substr(curIdx + 1, nextBr - curIdx - 1));
|
||||
linkLine.Append(" ");
|
||||
curIdx = nextBr;
|
||||
}
|
||||
|
||||
linkLine.Append("-out:");
|
||||
IDEUtils::AppendWithOptionalQuotes(linkLine, targetPath);
|
||||
linkLine.Append(" ");
|
||||
|
||||
if (mTargetType == BfTargetType_BeefConsoleApplication)
|
||||
linkLine.Append("-subsystem:console ");
|
||||
else
|
||||
linkLine.Append("-subsystem:windows ");
|
||||
|
||||
linkLine.Append("-defaultlib:libcmtd ");
|
||||
linkLine.Append("-nologo ");
|
||||
|
||||
linkLine.Append("-pdb:");
|
||||
int lastDotPos = (int)targetPath.LastIndexOf('.');
|
||||
if (lastDotPos == -1)
|
||||
lastDotPos = (int)targetPath.length();
|
||||
auto pdbName = String(targetPath, 0, lastDotPos);
|
||||
pdbName.Append(".pdb");
|
||||
IDEUtils::AppendWithOptionalQuotes(linkLine, pdbName);
|
||||
linkLine.Append(" ");
|
||||
|
||||
linkLine.Append("-debug ");
|
||||
|
||||
int checkIdx = 0;
|
||||
while (true)
|
||||
{
|
||||
int libIdx = (int)vsStr.IndexOf("LIB64\t", checkIdx);
|
||||
if (libIdx == -1)
|
||||
break;
|
||||
int libCrIdx = (int)vsStr.IndexOf('\n', libIdx + 1);
|
||||
if (libCrIdx == -1)
|
||||
break;
|
||||
|
||||
String libPath = vsStr.Substring(libIdx + 6, libCrIdx - libIdx - 6);
|
||||
linkLine.Append("-libpath:\"");
|
||||
linkLine.Append(libPath);
|
||||
linkLine.Append("\" ");
|
||||
checkIdx = libCrIdx + 1;
|
||||
}
|
||||
|
||||
linkLine.Append(mLinkParams);
|
||||
|
||||
BfpSpawnFlags flags = BfpSpawnFlag_None;
|
||||
if (true)
|
||||
{
|
||||
//if (linkLine.HasMultibyteChars())
|
||||
if (true)
|
||||
flags = (BfpSpawnFlags)(BfpSpawnFlag_UseArgsFile | BfpSpawnFlag_UseArgsFile_Native | BfpSpawnFlag_UseArgsFile_BOM);
|
||||
else
|
||||
flags = (BfpSpawnFlags)(BfpSpawnFlag_UseArgsFile);
|
||||
}
|
||||
|
||||
auto runCmd = QueueRun(linkerPath, linkLine, mWorkingDir, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
void BootApp::DoLinkGNU()
|
||||
{
|
||||
String linkerPath = "/usr/bin/c++";
|
||||
|
||||
String linkLine;
|
||||
|
||||
String targetPath = mTargetPath;
|
||||
|
||||
bool hadOutputChanges;
|
||||
const char* result = BfCompiler_GetUsedOutputFileNames(mCompiler, mProject, true, &hadOutputChanges);
|
||||
if (result == NULL)
|
||||
return;
|
||||
std::string fileNamesStr;
|
||||
fileNamesStr += result;
|
||||
if (fileNamesStr.length() == 0)
|
||||
return;
|
||||
int curIdx = -1;
|
||||
while (curIdx < (int)fileNamesStr.length())
|
||||
{
|
||||
int nextBr = (int)fileNamesStr.find('\n', curIdx + 1);
|
||||
if (nextBr == -1)
|
||||
nextBr = (int)fileNamesStr.length();
|
||||
linkLine.Append(fileNamesStr.substr(curIdx + 1, nextBr - curIdx - 1));
|
||||
linkLine.Append(" ");
|
||||
curIdx = nextBr;
|
||||
}
|
||||
|
||||
linkLine.Append("-o ");
|
||||
IDEUtils::AppendWithOptionalQuotes(linkLine, targetPath);
|
||||
linkLine.Append(" ");
|
||||
linkLine.Append("-g ");
|
||||
|
||||
linkLine.Append("-debug -no-pie ");
|
||||
linkLine.Append(mLinkParams);
|
||||
|
||||
auto runCmd = QueueRun(linkerPath, linkLine, mWorkingDir, true ? BfpSpawnFlag_UseArgsFile : BfpSpawnFlag_None);
|
||||
}
|
||||
|
||||
bool BootApp::Compile()
|
||||
{
|
||||
DWORD startTick = BFTickCount();
|
||||
|
||||
mSystem = BfSystem_Create();
|
||||
|
||||
mCompiler = BfSystem_CreateCompiler(mSystem, false);
|
||||
|
||||
String projectName = GetFileName(mTargetPath);
|
||||
int dotPos = (int)projectName.IndexOf('.');
|
||||
if (dotPos != -1)
|
||||
projectName.RemoveToEnd(dotPos);
|
||||
|
||||
mProject = BfSystem_CreateProject(mSystem, projectName.c_str());
|
||||
|
||||
int ltoType = 0;
|
||||
BfProject_SetOptions(mProject, mTargetType, mStartupObject.c_str(), mDefines.c_str(), mOptLevel, ltoType, false, false, false, false);
|
||||
|
||||
mPassInstance = BfSystem_CreatePassInstance(mSystem);
|
||||
|
||||
Beefy::String exePath;
|
||||
BfpGetStrHelper(exePath, [](char* outStr, int* inOutStrSize, BfpResult* result)
|
||||
{
|
||||
BfpSystem_GetExecutablePath(outStr, inOutStrSize, (BfpSystemResult*)result);
|
||||
});
|
||||
mBuildDir = GetFileDir(exePath) + "/build";
|
||||
|
||||
RecursiveCreateDirectory(mBuildDir + "/" + projectName);
|
||||
|
||||
BfCompilerOptionFlags optionFlags = (BfCompilerOptionFlags)(BfCompilerOptionFlag_EmitDebugInfo | BfCompilerOptionFlag_EmitLineInfo | BfCompilerOptionFlag_GenerateOBJ);
|
||||
if (mEmitIR)
|
||||
optionFlags = (BfCompilerOptionFlags)(optionFlags | BfCompilerOptionFlag_WriteIR);
|
||||
|
||||
|
||||
int maxWorkerThreads = BfpSystem_GetNumLogicalCPUs(NULL);
|
||||
if (maxWorkerThreads <= 1)
|
||||
maxWorkerThreads = 6;
|
||||
|
||||
BfCompiler_SetOptions(mCompiler, NULL, 0, BfMachineType_x64, mToolset, BfSIMDSetting_SSE2, 1, maxWorkerThreads, optionFlags, "malloc", "free");
|
||||
|
||||
for (auto& srcName : mRequestedSrc)
|
||||
{
|
||||
String absPath = GetAbsPath(srcName, mWorkingDir);
|
||||
QueuePath(absPath);
|
||||
}
|
||||
|
||||
if (!mHadErrors)
|
||||
{
|
||||
DoCompile();
|
||||
OutputLine(StrFormat("TIMING: Beef compiling: %0.1fs", (BFTickCount() - startTick) / 1000.0), OutputPri_Normal);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
const char* msg = BfPassInstance_PopOutString(mPassInstance);
|
||||
if (msg == NULL)
|
||||
break;
|
||||
|
||||
if ((strncmp(msg, ":warn ", 6) == 0))
|
||||
{
|
||||
OutputLine(msg + 6, OutputPri_Warning);
|
||||
}
|
||||
else if ((strncmp(msg, ":error ", 7) == 0))
|
||||
{
|
||||
OutputLine(msg + 7, OutputPri_Error);
|
||||
}
|
||||
else if ((strncmp(msg, ":med ", 5) == 0))
|
||||
{
|
||||
OutputLine(msg + 5, OutputPri_Normal);
|
||||
}
|
||||
else if ((strncmp(msg, ":low ", 5) == 0))
|
||||
{
|
||||
OutputLine(msg + 5, OutputPri_Low);
|
||||
}
|
||||
else if ((strncmp(msg, "ERROR(", 6) == 0) || (strncmp(msg, "ERROR:", 6) == 0))
|
||||
{
|
||||
OutputLine(msg, OutputPri_Error);
|
||||
}
|
||||
else if ((strncmp(msg, "WARNING(", 8) == 0) || (strncmp(msg, "WARNING:", 8) == 0))
|
||||
{
|
||||
OutputLine(msg, OutputPri_Warning);
|
||||
}
|
||||
else
|
||||
OutputLine(msg);
|
||||
}
|
||||
|
||||
if (!mHadErrors)
|
||||
{
|
||||
if (mVerbosity == Verbosity_Normal)
|
||||
{
|
||||
std::cout << "Linking " << mTargetPath.c_str() << "...";
|
||||
std::cout.flush();
|
||||
}
|
||||
|
||||
#ifdef BF_PLATFORM_WINDOWS
|
||||
DoLinkMS();
|
||||
#else
|
||||
DoLinkGNU();
|
||||
#endif
|
||||
|
||||
if (mVerbosity == Verbosity_Normal)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
BfPassInstance_Delete(mPassInstance);
|
||||
BfCompiler_Delete(mCompiler);
|
||||
|
||||
BfSystem_Delete(mSystem);
|
||||
|
||||
return !mHadErrors;
|
||||
}
|
||||
|
80
BeefBoot/BootApp.h
Normal file
80
BeefBoot/BootApp.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefBoot.h"
|
||||
#include "BeefySysLib/FileStream.h"
|
||||
#include "BeefySysLib/util/CritSect.h"
|
||||
#include "BeefySysLib/util/String.h"
|
||||
#include "BeefySysLib/util/Array.h"
|
||||
#include "Compiler/BfSystem.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
enum OutputPri
|
||||
{
|
||||
OutputPri_Low,
|
||||
OutputPri_Normal,
|
||||
OutputPri_High,
|
||||
OutputPri_Warning,
|
||||
OutputPri_Error,
|
||||
OutputPri_Critical
|
||||
};
|
||||
|
||||
enum Verbosity
|
||||
{
|
||||
Verbosity_Quiet,
|
||||
Verbosity_Minimal,
|
||||
Verbosity_Normal,
|
||||
Verbosity_Detailed,
|
||||
Verbosity_Diagnostic,
|
||||
};
|
||||
|
||||
class BootApp
|
||||
{
|
||||
public:
|
||||
CritSect mLogCritSect;
|
||||
FileStream mLogFile;
|
||||
Verbosity mVerbosity;
|
||||
BfTargetType mTargetType;
|
||||
bool mHadCmdLine;
|
||||
bool mShowedHelp;
|
||||
bool mHadErrors;
|
||||
Array<String> mRequestedSrc;
|
||||
BfOptLevel mOptLevel;
|
||||
BfToolsetType mToolset;
|
||||
bool mEmitIR;
|
||||
String mBuildDir;
|
||||
String mWorkingDir;
|
||||
String mDefines;
|
||||
String mStartupObject;
|
||||
String mTargetPath;
|
||||
String mLinkParams;
|
||||
|
||||
void* mSystem;
|
||||
void* mCompiler;
|
||||
void* mProject;
|
||||
void* mPassInstance;
|
||||
|
||||
public:
|
||||
void Fail(const String & error);
|
||||
void OutputLine(const String& text, OutputPri outputPri = OutputPri_Normal);
|
||||
bool QueueRun(const String& fileName, const String& args, const String& workingDir, BfpSpawnFlags extraFlags);
|
||||
|
||||
void QueueFile(const StringImpl& path);
|
||||
void QueuePath(const StringImpl& path);
|
||||
void DoCompile();
|
||||
void DoLinkMS();
|
||||
void DoLinkGNU();
|
||||
|
||||
public:
|
||||
BootApp();
|
||||
~BootApp();
|
||||
|
||||
bool HandleCmdLine(const String& cmd, const String& param);
|
||||
|
||||
bool Init();
|
||||
bool Compile();
|
||||
};
|
||||
|
||||
extern BootApp* gApp;
|
||||
|
||||
NS_BF_END
|
122
BeefBoot/CMakeLists.txt
Normal file
122
BeefBoot/CMakeLists.txt
Normal file
|
@ -0,0 +1,122 @@
|
|||
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
|
||||
|
||||
################### Variables. ####################
|
||||
# Change if you want modify path or other values. #
|
||||
###################################################
|
||||
|
||||
set(PROJECT_NAME BeefBoot)
|
||||
# Output Variables
|
||||
set(OUTPUT_DEBUG Debug/bin)
|
||||
set(OUTPUT_RELEASE Release/bin)
|
||||
|
||||
############## CMake Project ################
|
||||
# The main options of project #
|
||||
#############################################
|
||||
|
||||
project(${PROJECT_NAME} CXX C)
|
||||
|
||||
# Define Release by default.
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
message(STATUS "Build type not specified: Use Debug by default.")
|
||||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# Definition of Macros
|
||||
add_definitions(
|
||||
-DIDEHELPER_EXPORTS
|
||||
-DBFSYSLIB_DYNAMIC
|
||||
-DUNICODE
|
||||
-D_UNICODE
|
||||
-DBF_NO_FBX
|
||||
-DFT2_BUILD_LIBRARY
|
||||
-DBFSYSLIB_DYNAMIC
|
||||
)
|
||||
|
||||
include_directories(
|
||||
.
|
||||
../BeefySysLib/
|
||||
../BeefySysLib/platform/linux
|
||||
../BeefySysLib/third_party
|
||||
../BeefySysLib/third_party/freetype/include
|
||||
../
|
||||
../extern/llvm-project_8_0_0/llvm/include
|
||||
../extern/llvm-project_8_0_0/llvm/lib/Target
|
||||
../IDEHelper
|
||||
)
|
||||
|
||||
############## Artefacts Output #################
|
||||
# Defines outputs , depending Debug or Release. #
|
||||
#################################################
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_definitions(
|
||||
-D_DEBUG
|
||||
)
|
||||
include_directories(
|
||||
../extern/llvm_linux_8_0_0/include
|
||||
../extern/llvm_linux_8_0_0/lib/Target/X86
|
||||
)
|
||||
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${OUTPUT_DEBUG}")
|
||||
set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_8_0_0/lib")
|
||||
else()
|
||||
include_directories(
|
||||
../extern/llvm_linux_rel_8_0_0/include
|
||||
../extern/llvm_linux_rel_8_0_0/lib/Target/X86
|
||||
)
|
||||
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${OUTPUT_RELEASE}")
|
||||
set(LLVM_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../extern/llvm_linux_rel_8_0_0/lib")
|
||||
endif()
|
||||
|
||||
################### Dependencies ##################
|
||||
# Add Dependencies to project. #
|
||||
###################################################
|
||||
|
||||
option(BUILD_DEPENDS
|
||||
"Build other CMake project."
|
||||
ON
|
||||
)
|
||||
|
||||
# Dependencies : disable BUILD_DEPENDS to link with lib already build.
|
||||
if(BUILD_DEPENDS)
|
||||
|
||||
else()
|
||||
|
||||
endif()
|
||||
|
||||
################# Flags ################
|
||||
# Defines Flags for Windows and Linux. #
|
||||
########################################
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W3 /MD /MDd /Od /EHsc")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc")
|
||||
endif(MSVC)
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-multichar -Wno-invalid-offsetof")
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
endif()
|
||||
endif(NOT MSVC)
|
||||
|
||||
################ Files ################
|
||||
# -- Add files to project. -- #
|
||||
#######################################
|
||||
|
||||
file(GLOB SRC_FILES
|
||||
BeefBoot.cpp
|
||||
BootApp.cpp
|
||||
)
|
||||
|
||||
# Add executable to build.
|
||||
add_executable(${PROJECT_NAME}
|
||||
${SRC_FILES}
|
||||
)
|
||||
|
||||
# Link with other dependencies.
|
||||
if(MSVC)
|
||||
target_link_libraries(${PROJECT_NAME} BeefySysLib IDEHelper kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} BeefySysLib IDEHelper tinfo
|
||||
#${LLVM_LIB}/libLLVMMC.a
|
||||
)
|
||||
endif()
|
Loading…
Add table
Add a link
Reference in a new issue