1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Fixed dynamic Beef libs on Linux/macOS

This commit is contained in:
Brian Fiete 2020-06-30 12:13:20 -07:00
parent 455a0d0b46
commit 6e5b6694a1
10 changed files with 139 additions and 34 deletions

View file

@ -16,6 +16,8 @@ set(OUTPUT_RELEASE Release/bin)
project(${PROJECT_NAME} CXX C) project(${PROJECT_NAME} CXX C)
add_compile_options(-fPIC)
# Define Release by default. # Define Release by default.
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug") set(CMAKE_BUILD_TYPE "Debug")

View file

@ -304,9 +304,21 @@ void mkdir(const char* path)
typedef void(*CrashInfoFunc)(); typedef void(*CrashInfoFunc)();
static CritSect gSysCritSect; struct BfpGlobalData
static String gCrashInfo; {
static Array<CrashInfoFunc> gCrashInfoFuncs; CritSect mSysCritSect;
String mCrashInfo;
Array<CrashInfoFunc> mCrashInfoFuncs;
};
static BfpGlobalData* gBfpGlobal;
static BfpGlobalData* BfpGetGlobalData()
{
if (gBfpGlobal == NULL)
gBfpGlobal = new BfpGlobalData();
return gBfpGlobal;
}
#ifdef BFP_HAS_BACKTRACE #ifdef BFP_HAS_BACKTRACE
@ -437,18 +449,18 @@ static void Crashed()
{ {
// //
{ {
AutoCrit autoCrit(gSysCritSect); AutoCrit autoCrit(BfpGetGlobalData()->mSysCritSect);
String debugDump; String debugDump;
debugDump += "**** FATAL APPLICATION ERROR ****\n"; debugDump += "**** FATAL APPLICATION ERROR ****\n";
for (auto func : gCrashInfoFuncs) for (auto func : BfpGetGlobalData()->mCrashInfoFuncs)
func(); func();
if (!gCrashInfo.IsEmpty()) if (!BfpGetGlobalData()->mCrashInfo.IsEmpty())
{ {
debugDump += gCrashInfo; debugDump += BfpGetGlobalData()->mCrashInfo;
debugDump += "\n"; debugDump += "\n";
} }
@ -498,14 +510,16 @@ static void SigHandler(int sig)
} }
if (sigName != NULL) if (sigName != NULL)
gCrashInfo += StrFormat("Signal: %s\n", sigName); BfpGetGlobalData()->mCrashInfo += StrFormat("Signal: %s\n", sigName);
else else
gCrashInfo += StrFormat("Signal: %d\n", sig); BfpGetGlobalData()->mCrashInfo += StrFormat("Signal: %d\n", sig);
Crashed(); Crashed();
} }
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags) BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags)
{ {
BfpGetGlobalData();
if (version != BFP_VERSION) if (version != BFP_VERSION)
{ {
BfpSystem_FatalError(StrFormat("Bfp build version '%d' does not match requested version '%d'", BFP_VERSION, version).c_str(), "BFP FATAL ERROR"); BfpSystem_FatalError(StrFormat("Bfp build version '%d' does not match requested version '%d'", BFP_VERSION, version).c_str(), "BFP FATAL ERROR");
@ -561,14 +575,14 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashReportKind(BfpCrashReportKind cra
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfoFunc(BfpCrashInfoFunc crashInfoFunc) BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfoFunc(BfpCrashInfoFunc crashInfoFunc)
{ {
AutoCrit autoCrit(gSysCritSect); AutoCrit autoCrit(BfpGetGlobalData()->mSysCritSect);
gCrashInfoFuncs.Add(crashInfoFunc); BfpGetGlobalData()->mCrashInfoFuncs.Add(crashInfoFunc);
} }
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str) // Can do at any time, or during CrashInfoFunc callbacks BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str) // Can do at any time, or during CrashInfoFunc callbacks
{ {
AutoCrit autoCrit(gSysCritSect); AutoCrit autoCrit(BfpGetGlobalData()->mSysCritSect);
gCrashInfo.Append(str); BfpGetGlobalData()->mCrashInfo.Append(str);
} }
void BfpSystem_Shutdown() void BfpSystem_Shutdown()

View file

@ -313,7 +313,9 @@ namespace IDE
testProjectInfo = gApp.mTestManager.GetProjectInfo(project); testProjectInfo = gApp.mTestManager.GetProjectInfo(project);
bool isExe = (project.mGeneralOptions.mTargetType != Project.TargetType.BeefLib) || (testProjectInfo != null); bool isExe = (project.mGeneralOptions.mTargetType != Project.TargetType.BeefLib) || (testProjectInfo != null);
if (isExe) bool isDynLib = project.mGeneralOptions.mTargetType == Project.TargetType.BeefDynLib;
if (isExe || isDynLib)
{ {
CopyLibFiles(targetPath, workspaceOptions, options); CopyLibFiles(targetPath, workspaceOptions, options);
@ -335,6 +337,11 @@ namespace IDE
linkLine.Append(" "); linkLine.Append(" ");
}*/ }*/
if (isDynLib)
{
linkLine.Append("-shared ");
}
if ((mPlatformType == .Windows) && if ((mPlatformType == .Windows) &&
((project.mGeneralOptions.mTargetType == Project.TargetType.BeefGUIApplication) || ((project.mGeneralOptions.mTargetType == Project.TargetType.BeefGUIApplication) ||
(project.mGeneralOptions.mTargetType == Project.TargetType.C_GUIApplication))) (project.mGeneralOptions.mTargetType == Project.TargetType.C_GUIApplication)))
@ -1092,10 +1099,8 @@ namespace IDE
absOutputDir.Append(projectBuildDir); absOutputDir.Append(projectBuildDir);
outputDir = absOutputDir; outputDir = absOutputDir;
targetPath.Append(outputDir, "/", project.mProjectName); targetPath.Append(outputDir, "/", project.mProjectName);
#if BF_PLATFORM_WINDOWS if (mPlatformType == .Windows)
targetPath.Append(".exe"); targetPath.Append(".exe");
#endif
Debug.Assert(testProjectInfo.mTestExePath == null); Debug.Assert(testProjectInfo.mTestExePath == null);
testProjectInfo.mTestExePath = new String(targetPath); testProjectInfo.mTestExePath = new String(targetPath);
} }

View file

@ -8337,6 +8337,8 @@ namespace IDE
bfProject.SetDisabled(false); bfProject.SetDisabled(false);
let platform = Workspace.PlatformType.GetFromName(mPlatformName);
var preprocessorMacros = scope DefinesSet(); var preprocessorMacros = scope DefinesSet();
void AddMacros(List<String> macros) void AddMacros(List<String> macros)
{ {
@ -8406,10 +8408,18 @@ namespace IDE
} }
} }
var relocType = options.mBeefOptions.mRelocType;
if (relocType == .NotSet)
{
if (platform != .Windows)
relocType = .PIC;
}
bfProject.SetOptions(targetType, bfProject.SetOptions(targetType,
project.mBeefGlobalOptions.mStartupObject, project.mBeefGlobalOptions.mStartupObject,
preprocessorMacros.mDefines, preprocessorMacros.mDefines,
optimizationLevel, ltoType, options.mBeefOptions.mRelocType, options.mBeefOptions.mPICLevel, optimizationLevel, ltoType, relocType, options.mBeefOptions.mPICLevel,
options.mBeefOptions.mMergeFunctions, options.mBeefOptions.mCombineLoads, options.mBeefOptions.mMergeFunctions, options.mBeefOptions.mCombineLoads,
options.mBeefOptions.mVectorizeLoops, options.mBeefOptions.mVectorizeSLP); options.mBeefOptions.mVectorizeLoops, options.mBeefOptions.mVectorizeSLP);
@ -8930,10 +8940,10 @@ namespace IDE
else if (project.mGeneralOptions.mTargetType != .CustomBuild) else if (project.mGeneralOptions.mTargetType != .CustomBuild)
newString.Append(".exe"); newString.Append(".exe");
case .macOS: case .macOS:
if (project.mGeneralOptions.mTargetType == Project.TargetType.BeefLib) if (project.mGeneralOptions.mTargetType == .BeefLib)
newString.Append(".dylib"); newString.Append(".dylib");
default: default:
if (project.mGeneralOptions.mTargetType == Project.TargetType.BeefLib) if (project.mGeneralOptions.mTargetType == .BeefDynLib)
newString.Append(".so"); newString.Append(".so");
} }
} }

View file

@ -2318,6 +2318,12 @@ void BeIRCodeGen::HandleNextCmd()
else if (attribute == BFIRAttribute_NoRecurse) else if (attribute == BFIRAttribute_NoRecurse)
{ {
} }
else if (attribute == BFIRAttribute_Constructor)
{
}
else if (attribute == BFIRAttribute_Destructor)
{
}
else else
BF_FATAL("Unhandled"); BF_FATAL("Unhandled");
} }

View file

@ -735,7 +735,7 @@ BfIRFunction BfCompiler::CreateLoadSharedLibraries(BfVDataModule* bfModule, Arra
bfModule->GetDefaultValue(bfModule->GetPrimitiveType(BfTypeCode_NullPtr)), dllHandleName); bfModule->GetDefaultValue(bfModule->GetPrimitiveType(BfTypeCode_NullPtr)), dllHandleName);
BfIRValue namePtr = bfModule->GetStringCharPtr(strNum); BfIRValue namePtr = bfModule->GetStringCharPtr(strNum);
SmallVector<BfIRValue, 1> args; SmallVector<BfIRValue, 2> args;
args.push_back(namePtr); args.push_back(namePtr);
args.push_back(dllHandleVar); args.push_back(dllHandleVar);
BfIRValue dllHandleValue = bfModule->mBfIRBuilder->CreateCall(loadSharedLibraryProc.mFunc, args); BfIRValue dllHandleValue = bfModule->mBfIRBuilder->CreateCall(loadSharedLibraryProc.mFunc, args);
@ -1624,6 +1624,8 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
if ((targetType == BfTargetType_BeefWindowsApplication) && (mOptions.mPlatformType != BfPlatformType_Windows)) if ((targetType == BfTargetType_BeefWindowsApplication) && (mOptions.mPlatformType != BfPlatformType_Windows))
targetType = BfTargetType_BeefConsoleApplication; targetType = BfTargetType_BeefConsoleApplication;
bool isPosixDynLib = (targetType == BfTargetType_BeefDynLib) && (mOptions.mPlatformType != BfPlatformType_Windows);
// Generate "main" // Generate "main"
if (!IsHotCompile()) if (!IsHotCompile())
{ {
@ -1677,7 +1679,8 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
auto entryBlock = bfModule->mBfIRBuilder->CreateBlock("entry", true); auto entryBlock = bfModule->mBfIRBuilder->CreateBlock("entry", true);
bfModule->mBfIRBuilder->SetInsertPoint(entryBlock); bfModule->mBfIRBuilder->SetInsertPoint(entryBlock);
#ifndef BF_PLATFORM_WINDOWS if ((mOptions.mPlatformType != BfPlatformType_Windows) &&
((targetType == BfTargetType_BeefConsoleApplication) || (targetType == BfTargetType_BeefTest)))
{ {
SmallVector<BfIRType, 2> paramTypes; SmallVector<BfIRType, 2> paramTypes;
paramTypes.push_back(int32Type); paramTypes.push_back(int32Type);
@ -1692,7 +1695,6 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
args.push_back(bfModule->mBfIRBuilder->GetArgument(1)); args.push_back(bfModule->mBfIRBuilder->GetArgument(1));
bfModule->mBfIRBuilder->CreateCall(setCmdLineFunc, args); bfModule->mBfIRBuilder->CreateCall(setCmdLineFunc, args);
} }
#endif
BfIRBlock initSkipBlock; BfIRBlock initSkipBlock;
if (targetType == BfTargetType_BeefDynLib) if (targetType == BfTargetType_BeefDynLib)
@ -1949,6 +1951,37 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
BfIRMDNode dbgArrayType = bfModule->mBfIRBuilder->DbgCreateArrayType(dataSize * 8, 8, bfModule->mBfIRBuilder->DbgGetType(int8Type), dataSize); BfIRMDNode dbgArrayType = bfModule->mBfIRBuilder->DbgCreateArrayType(dataSize * 8, 8, bfModule->mBfIRBuilder->DbgGetType(int8Type), dataSize);
bfModule->mBfIRBuilder->DbgCreateGlobalVariable(bfModule->mDICompileUnit, name, name, NULL, 0, dbgArrayType, false, irVal); bfModule->mBfIRBuilder->DbgCreateGlobalVariable(bfModule->mDICompileUnit, name, name, NULL, 0, dbgArrayType, false, irVal);
} }
if (isPosixDynLib)
{
auto voidType = bfModule->mBfIRBuilder->MapType(bfModule->GetPrimitiveType(BfTypeCode_None));
SizedArray<BfIRType, 4> paramTypes;
BfIRFunctionType funcType = bfModule->mBfIRBuilder->CreateFunctionType(voidType, paramTypes);
BfIRFunction func = bfModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_Internal, "BfDynLib__Startup");
bfModule->mBfIRBuilder->SetActiveFunction(func);
bfModule->mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_Constructor);
auto entryBlock = bfModule->mBfIRBuilder->CreateBlock("main", true);
bfModule->mBfIRBuilder->SetInsertPoint(entryBlock);
SmallVector<BfIRValue, 2> startArgs;
startArgs.push_back(bfModule->mBfIRBuilder->CreateConstNull());
startArgs.push_back(bfModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 1));
startArgs.push_back(bfModule->mBfIRBuilder->CreateConstNull());
bfModule->mBfIRBuilder->CreateCall(mainFunc, startArgs);
bfModule->mBfIRBuilder->CreateRetVoid();
//////////////////////////////////////////////////////////////////////////
func = bfModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_Internal, "BfDynLib__Shutdown");
bfModule->mBfIRBuilder->Func_AddAttribute(func, -1, BFIRAttribute_Destructor);
bfModule->mBfIRBuilder->SetActiveFunction(func);
entryBlock = bfModule->mBfIRBuilder->CreateBlock("main", true);
bfModule->mBfIRBuilder->SetInsertPoint(entryBlock);
SmallVector<BfIRValue, 2> stopArgs;
startArgs[1] = bfModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 0);
bfModule->mBfIRBuilder->CreateCall(mainFunc, startArgs);
bfModule->mBfIRBuilder->CreateRetVoid();
}
} }
// Generate "System.GC.MarkAllStaticMembers" // Generate "System.GC.MarkAllStaticMembers"

View file

@ -611,7 +611,9 @@ enum BfIRAttribute
BFIRAttribute_NoFramePointerElim, BFIRAttribute_NoFramePointerElim,
BFIRAttribute_DllImport, BFIRAttribute_DllImport,
BFIRAttribute_DllExport, BFIRAttribute_DllExport,
BFIRAttribute_NoRecurse BFIRAttribute_NoRecurse,
BFIRAttribute_Constructor,
BFIRAttribute_Destructor,
}; };
struct BfIRFunctionType struct BfIRFunctionType

View file

@ -2737,6 +2737,35 @@ void BfIRCodeGen::HandleNextCmd()
{ {
func->addFnAttr("no-frame-pointer-elim", "true"); func->addFnAttr("no-frame-pointer-elim", "true");
} }
else if ((attribute == BFIRAttribute_Constructor) || (attribute == BFIRAttribute_Destructor))
{
CmdParamVec<llvm::Type*> members;
members.push_back(llvm::Type::getInt32Ty(*mLLVMContext));
members.push_back(func->getType());
members.push_back(llvm::Type::getInt8PtrTy(*mLLVMContext));
llvm::StructType* structType = llvm::StructType::get(*mLLVMContext, members);
CmdParamVec<llvm::Constant*> structVals;
structVals.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0x7FFFFF00));
structVals.push_back(func);
structVals.push_back(llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(*mLLVMContext)));
auto constStruct = llvm::ConstantStruct::get(structType, structVals);
CmdParamVec<llvm::Constant*> structArrVals;
structArrVals.push_back(constStruct);
auto arrTy = llvm::ArrayType::get(structType, 1);
auto constArr = llvm::ConstantArray::get(arrTy, structArrVals);
auto globalVariable = new llvm::GlobalVariable(
*mLLVMModule,
arrTy,
false,
llvm::GlobalValue::AppendingLinkage,
constArr,
(attribute == BFIRAttribute_Constructor) ? "llvm.global_ctors" : "llvm.global_dtors",
NULL, llvm::GlobalValue::NotThreadLocal);
}
else else
func->addAttribute(argIdx, LLVMMapAttribute(attribute)); func->addAttribute(argIdx, LLVMMapAttribute(attribute));
} }

View file

@ -719,7 +719,12 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst)
} }
mangleContext.mPrefixObjectPointer = true; mangleContext.mPrefixObjectPointer = true;
String methodName = methodInst->mMethodDef->mName; StringT<128> methodName = methodInst->mMethodDef->mName;
for (int i = 0; i < (int)methodName.length(); i++)
{
if (methodName[i] == '@')
methodName[i] = '$';
}
if (methodInst->mMethodDef->mIsOperator) if (methodInst->mMethodDef->mIsOperator)
{ {

View file

@ -3,6 +3,7 @@ echo Starting build.sh
PATH=/usr/local/bin:$PATH:$HOME/bin PATH=/usr/local/bin:$PATH:$HOME/bin
SCRIPTPATH=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P) SCRIPTPATH=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
ROOTPATH="$(dirname "$SCRIPTPATH")"
echo Building from from $SCRIPTPATH echo Building from from $SCRIPTPATH
cd $SCRIPTPATH cd $SCRIPTPATH
@ -50,15 +51,13 @@ else
LINKOPTS="-ldl -lpthread -Wl,-rpath -Wl,\$ORIGIN" LINKOPTS="-ldl -lpthread -Wl,-rpath -Wl,\$ORIGIN"
fi fi
if [ ! -L libBeefRT_d.a ]; then ln -s -f $ROOTPATH/jbuild_d/Debug/bin/libBeefRT_d.a libBeefRT_d.a
ln -s ../../jbuild_d/Debug/bin/libBeefRT_d.a libBeefRT_d.a ln -s -f $ROOTPATH/jbuild_d/Debug/bin/libBeefySysLib_d.$LIBEXT libBeefySysLib_d.$LIBEXT
ln -s ../../jbuild_d/Debug/bin/libBeefySysLib_d.$LIBEXT libBeefySysLib_d.$LIBEXT ln -s -f $ROOTPATH/jbuild_d/Debug/bin/libIDEHelper_d.$LIBEXT libIDEHelper_d.$LIBEXT
ln -s ../../jbuild_d/Debug/bin/libIDEHelper_d.$LIBEXT libIDEHelper_d.$LIBEXT
ln -s ../../jbuild/Release/bin/libBeefRT.a libBeefRT.a ln -s -f $ROOTPATH/jbuild/Release/bin/libBeefRT.a libBeefRT.a
ln -s ../../jbuild/Release/bin/libBeefySysLib.$LIBEXT libBeefySysLib.$LIBEXT ln -s -f $ROOTPATH/jbuild/Release/bin/libBeefySysLib.$LIBEXT libBeefySysLib.$LIBEXT
ln -s ../../jbuild/Release/bin/libIDEHelper.$LIBEXT libIDEHelper.$LIBEXT ln -s -f $ROOTPATH/jbuild/Release/bin/libIDEHelper.$LIBEXT libIDEHelper.$LIBEXT
fi
### DEBUG ### ### DEBUG ###