2020-04-29 06:40:03 -07:00
|
|
|
using System.Collections;
|
2019-08-27 08:04:41 -07:00
|
|
|
using System;
|
|
|
|
using IDE.Compiler;
|
|
|
|
using System.IO;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using Beefy;
|
|
|
|
using IDE.util;
|
|
|
|
|
|
|
|
namespace IDE
|
|
|
|
{
|
2020-05-13 12:28:20 -07:00
|
|
|
enum CompileKind
|
|
|
|
{
|
|
|
|
case Normal;
|
|
|
|
case RunAfter;
|
|
|
|
case DebugAfter;
|
|
|
|
case Test;
|
|
|
|
|
|
|
|
public bool WantsRunAfter
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return (this == .RunAfter) || (this == .DebugAfter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
class BuildContext
|
|
|
|
{
|
2019-09-28 09:48:37 -07:00
|
|
|
public int32 mUpdateCnt;
|
2019-08-27 08:04:41 -07:00
|
|
|
public Project mHotProject;
|
|
|
|
public Workspace.Options mWorkspaceOptions;
|
2021-02-25 10:14:22 -08:00
|
|
|
public Dictionary<Project, String> mImpLibMap = new .() ~ DeleteDictionaryAndValues!(_);
|
|
|
|
public Dictionary<Project, String> mTargetPathMap = new .() ~ DeleteDictionaryAndValues!(_);
|
2020-05-21 11:47:15 -07:00
|
|
|
public ScriptManager.Context mScriptContext = new .() ~ _.ReleaseLastRef();
|
2019-08-27 08:04:41 -07:00
|
|
|
public ScriptManager mScriptManager ~ delete _;
|
|
|
|
|
|
|
|
public bool Failed
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
if (mScriptManager != null)
|
|
|
|
return mScriptManager.mFailed;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public enum CustomBuildCommandResult
|
|
|
|
{
|
|
|
|
NoCommands,
|
|
|
|
HadCommands,
|
|
|
|
Failed
|
|
|
|
}
|
|
|
|
|
2019-10-15 12:28:21 -07:00
|
|
|
Workspace.PlatformType mPlatformType;
|
|
|
|
Workspace.ToolsetType mToolset;
|
|
|
|
int mPtrSize;
|
|
|
|
|
|
|
|
public this()
|
|
|
|
{
|
|
|
|
Workspace.Options workspaceOptions = gApp.GetCurWorkspaceOptions();
|
|
|
|
mToolset = workspaceOptions.mToolsetType;
|
|
|
|
mPlatformType = Workspace.PlatformType.GetFromName(gApp.mPlatformName);
|
|
|
|
mPtrSize = Workspace.PlatformType.GetPtrSizeByName(gApp.mPlatformName);
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
public CustomBuildCommandResult QueueProjectCustomBuildCommands(Project project, String targetPath, Project.BuildCommandTrigger trigger, List<String> cmdList)
|
|
|
|
{
|
|
|
|
if (cmdList.IsEmpty)
|
|
|
|
return .NoCommands;
|
|
|
|
|
|
|
|
if (trigger == .Never)
|
|
|
|
return .NoCommands;
|
|
|
|
|
2020-05-12 06:44:09 -07:00
|
|
|
List<Project> depProjectList = scope .();
|
|
|
|
gApp.GetDependentProjectList(project, depProjectList);
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
if ((trigger == .IfFilesChanged) && (!project.mForceCustomCommands))
|
|
|
|
{
|
|
|
|
int64 highestDateTime = 0;
|
|
|
|
|
|
|
|
int64 targetDateTime = File.GetLastWriteTime(targetPath).Get().ToFileTime();
|
|
|
|
|
|
|
|
bool forceRebuild = false;
|
|
|
|
|
2020-05-12 06:44:09 -07:00
|
|
|
for (var depName in depProjectList)
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
|
|
|
var depProject = gApp.mWorkspace.FindProject(depName.mProjectName);
|
|
|
|
if (depProject != null)
|
|
|
|
{
|
|
|
|
if (depProject.mLastDidBuild)
|
|
|
|
forceRebuild = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
project.WithProjectItems(scope [&] (projectItem) =>
|
|
|
|
{
|
|
|
|
var projectSource = projectItem as ProjectSource;
|
|
|
|
var importPath = scope String();
|
|
|
|
projectSource.GetFullImportPath(importPath);
|
|
|
|
Result<DateTime> fileDateTime = File.GetLastWriteTime(importPath);
|
|
|
|
if (fileDateTime case .Ok)
|
|
|
|
{
|
|
|
|
let date = fileDateTime.Get().ToFileTime();
|
|
|
|
/*if (date > targetDateTime)
|
|
|
|
Console.WriteLine("Custom build higher time: {0}", importPath);*/
|
|
|
|
highestDateTime = Math.Max(highestDateTime, date);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if ((highestDateTime <= targetDateTime) && (!forceRebuild))
|
|
|
|
return .NoCommands;
|
|
|
|
|
|
|
|
project.mLastDidBuild = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Workspace.Options workspaceOptions = gApp.GetCurWorkspaceOptions();
|
|
|
|
Project.Options options = gApp.GetCurProjectOptions(project);
|
|
|
|
|
|
|
|
bool didCommands = false;
|
|
|
|
|
2021-02-25 10:14:22 -08:00
|
|
|
//let targetName = scope String("Project ", project.mProjectName);
|
2019-08-27 08:04:41 -07:00
|
|
|
|
|
|
|
//Console.WriteLine("Executing custom command {0} {1} {2}", highestDateTime, targetDateTime, forceRebuild);
|
|
|
|
for (let origCustomCmd in cmdList)
|
|
|
|
{
|
|
|
|
bool isCommand = false;
|
|
|
|
for (let c in origCustomCmd.RawChars)
|
|
|
|
{
|
2020-06-22 08:49:23 -07:00
|
|
|
if ((c == '\"') || (c == '$') || (c == '\n'))
|
2019-08-27 08:04:41 -07:00
|
|
|
break;
|
|
|
|
if (c == '(')
|
|
|
|
isCommand = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
String customCmd = scope String();
|
|
|
|
|
|
|
|
if (isCommand)
|
|
|
|
{
|
|
|
|
customCmd.Append(origCustomCmd);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
customCmd.Append("%exec ");
|
2019-10-14 17:49:10 -07:00
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, origCustomCmd, "custom command", customCmd);
|
2020-06-22 08:49:23 -07:00
|
|
|
|
|
|
|
// For multi-line execs
|
|
|
|
customCmd.Replace('\n', '\v');
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (customCmd.IsWhiteSpace)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (mScriptManager == null)
|
|
|
|
{
|
2020-05-21 11:47:15 -07:00
|
|
|
mScriptManager = new .(mScriptContext);
|
2020-01-06 13:49:35 -08:00
|
|
|
mScriptManager.mIsBuildScript = true;
|
2019-08-27 08:04:41 -07:00
|
|
|
mScriptManager.mSoftFail = true;
|
|
|
|
mScriptManager.mVerbosity = gApp.mVerbosity;
|
|
|
|
didCommands = true;
|
|
|
|
}
|
|
|
|
|
2021-02-25 10:14:22 -08:00
|
|
|
let scriptCmd = new IDEApp.ScriptCmd();
|
|
|
|
scriptCmd.mCmd = new String(customCmd);
|
|
|
|
scriptCmd.mPath = new $"project {project.mProjectName}";
|
|
|
|
gApp.mExecutionQueue.Add(scriptCmd);
|
2019-08-27 08:04:41 -07:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-08-29 14:19:07 -07:00
|
|
|
return didCommands ? .HadCommands : .NoCommands;
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
|
|
|
|
2019-10-23 07:12:36 -07:00
|
|
|
bool QueueProjectGNUArchive(Project project, String targetPath, Workspace.Options workspaceOptions, Project.Options options, String objectsArg)
|
|
|
|
{
|
|
|
|
#if BF_PLATFORM_WINDOWS
|
|
|
|
String llvmDir = scope String(IDEApp.sApp.mInstallDir);
|
|
|
|
IDEUtils.FixFilePath(llvmDir);
|
|
|
|
llvmDir.Append("llvm/");
|
|
|
|
#else
|
2019-11-26 13:11:17 -08:00
|
|
|
//String llvmDir = "";
|
2019-10-23 07:12:36 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
//String error = scope String();
|
2020-09-27 22:20:26 -07:00
|
|
|
bool isTest = options.mBuildOptions.mBuildKind == .Test;
|
|
|
|
bool isExe = ((project.mGeneralOptions.mTargetType != Project.TargetType.BeefLib) && (project.mGeneralOptions.mTargetType != Project.TargetType.BeefTest)) || (isTest);
|
2019-10-23 07:12:36 -07:00
|
|
|
if (!isExe)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
String arCmds = scope String(""); //-O2 -Rpass=inline
|
|
|
|
//(doClangCPP ? "-lc++abi " : "") +
|
|
|
|
|
|
|
|
arCmds.AppendF("CREATE {}\n", targetPath);
|
|
|
|
|
|
|
|
for (let obj in objectsArg.Split(' '))
|
|
|
|
{
|
|
|
|
if (!obj.IsEmpty)
|
|
|
|
{
|
|
|
|
arCmds.AppendF("ADDMOD {}\n", obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
arCmds.AppendF("SAVE\n");
|
|
|
|
|
|
|
|
if (project.mNeedsTargetRebuild)
|
|
|
|
{
|
|
|
|
if (File.Delete(targetPath) case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputLine("Failed to delete {0}", targetPath);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
String arPath = scope .();
|
|
|
|
#if BF_PLATFORM_WINDOWS
|
|
|
|
arPath.Clear();
|
|
|
|
arPath.Append(gApp.mInstallDir);
|
|
|
|
arPath.Append(@"llvm\bin\llvm-ar.exe");
|
2019-10-29 05:01:04 -07:00
|
|
|
#elif BF_PLATFORM_MACOS
|
|
|
|
arPath.Append("llvm/bin/llvm-ar");
|
2019-10-23 07:12:36 -07:00
|
|
|
#else
|
|
|
|
arPath.Append("/usr/bin/ar");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
String workingDir = scope String();
|
|
|
|
workingDir.Append(gApp.mInstallDir);
|
|
|
|
|
|
|
|
String scriptPath = scope .();
|
|
|
|
if (Path.GetTempFileName(scriptPath) case .Err)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (File.WriteAllText(scriptPath, arCmds) case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputLine("Failed to write archive script {0}", scriptPath);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
String cmdLine = scope .();
|
|
|
|
cmdLine.AppendF("-M");
|
|
|
|
|
|
|
|
var runCmd = gApp.QueueRun(arPath, cmdLine, workingDir, .UTF8);
|
|
|
|
runCmd.mOnlyIfNotFailed = true;
|
|
|
|
runCmd.mStdInData = new .(arCmds);
|
|
|
|
var tagetCompletedCmd = new IDEApp.TargetCompletedCmd(project);
|
|
|
|
tagetCompletedCmd.mOnlyIfNotFailed = true;
|
|
|
|
gApp.mExecutionQueue.Add(tagetCompletedCmd);
|
|
|
|
|
|
|
|
project.mLastDidBuild = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-06-23 07:33:43 -07:00
|
|
|
void WSLPathFix(String str)
|
|
|
|
{
|
|
|
|
for (int i = 1; i < str.Length - 1; i++)
|
|
|
|
{
|
|
|
|
if (str[i] == ':')
|
|
|
|
{
|
|
|
|
if (str[i - 1].IsLetter)
|
|
|
|
{
|
|
|
|
int j = i;
|
|
|
|
for ( ; j < str.Length; j++)
|
|
|
|
{
|
|
|
|
char8 cj = str[j];
|
|
|
|
if (cj == '\\')
|
|
|
|
str[j] = '/';
|
|
|
|
if ((cj.IsWhiteSpace) || (cj == '"'))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
str.Remove(i);
|
|
|
|
str[i - 1] = str[i - 1].ToLower;
|
|
|
|
str.Insert(i - 1, "/mnt/");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
bool QueueProjectGNULink(Project project, String targetPath, Workspace.Options workspaceOptions, Project.Options options, String objectsArg)
|
|
|
|
{
|
|
|
|
bool isDebug = gApp.mConfigName.IndexOf("Debug", true) != -1;
|
2020-06-23 07:33:43 -07:00
|
|
|
|
|
|
|
bool isMinGW = false;
|
|
|
|
|
2019-10-23 07:12:36 -07:00
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
|
|
|
|
#if BF_PLATFORM_WINDOWS
|
2020-06-23 07:33:43 -07:00
|
|
|
bool isWSL = mPlatformType == .Linux;
|
2019-08-27 08:04:41 -07:00
|
|
|
String llvmDir = scope String(IDEApp.sApp.mInstallDir);
|
|
|
|
IDEUtils.FixFilePath(llvmDir);
|
|
|
|
llvmDir.Append("llvm/");
|
|
|
|
#else
|
|
|
|
String llvmDir = "";
|
2020-06-23 07:33:43 -07:00
|
|
|
bool isWSL = false;
|
2019-08-27 08:04:41 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
//String error = scope String();
|
|
|
|
|
2020-09-27 22:20:26 -07:00
|
|
|
bool isTest = options.mBuildOptions.mBuildKind == .Test;
|
|
|
|
bool isExe = ((project.mGeneralOptions.mTargetType != Project.TargetType.BeefLib) && (project.mGeneralOptions.mTargetType != Project.TargetType.BeefTest)) || (isTest);
|
2020-06-30 12:13:20 -07:00
|
|
|
bool isDynLib = project.mGeneralOptions.mTargetType == Project.TargetType.BeefDynLib;
|
|
|
|
|
2021-06-28 05:47:37 -07:00
|
|
|
if (options.mBuildOptions.mBuildKind == .StaticLib)
|
|
|
|
isExe = false;
|
|
|
|
|
2020-06-30 12:13:20 -07:00
|
|
|
if (isExe || isDynLib)
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
2019-10-15 17:27:09 -07:00
|
|
|
CopyLibFiles(targetPath, workspaceOptions, options);
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
String linkLine = scope String(isDebug ? "-g " : "-g -O2 "); //-O2 -Rpass=inline
|
|
|
|
//(doClangCPP ? "-lc++abi " : "") +
|
|
|
|
|
|
|
|
linkLine.Append("-o ");
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, targetPath);
|
|
|
|
linkLine.Append(" ");
|
|
|
|
|
|
|
|
/*if (options.mBuildOptions.mLinkerType == Project.LinkerType.GCC)
|
|
|
|
{
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
linkLine.Append("--target=");
|
|
|
|
GetTargetName(workspaceOptions, linkLine);
|
|
|
|
linkLine.Append(" ");
|
|
|
|
}*/
|
|
|
|
|
2020-06-30 12:13:20 -07:00
|
|
|
if (isDynLib)
|
|
|
|
{
|
|
|
|
linkLine.Append("-shared ");
|
|
|
|
}
|
|
|
|
|
2020-05-04 15:06:05 -07:00
|
|
|
if ((mPlatformType == .Windows) &&
|
|
|
|
((project.mGeneralOptions.mTargetType == Project.TargetType.BeefGUIApplication) ||
|
|
|
|
(project.mGeneralOptions.mTargetType == Project.TargetType.C_GUIApplication)))
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
|
|
|
linkLine.Append("-mwindows ");
|
|
|
|
}
|
|
|
|
|
2019-10-15 12:28:21 -07:00
|
|
|
if (mPlatformType == .Linux)
|
|
|
|
linkLine.Append("-no-pie ");
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2020-05-21 13:30:30 -07:00
|
|
|
if (mPlatformType == .macOS)
|
|
|
|
linkLine.Append("-Wl,-no_compact_unwind ");
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
linkLine.Append(objectsArg);
|
|
|
|
|
|
|
|
//var destDir = scope String();
|
|
|
|
//Path.GetDirectoryName();
|
|
|
|
|
|
|
|
//TODO: Make an option
|
|
|
|
if (options.mBuildOptions.mCLibType == Project.CLibType.Static)
|
|
|
|
{
|
2021-05-31 08:50:17 -07:00
|
|
|
if (mPlatformType != .macOS)
|
|
|
|
linkLine.Append("-static-libgcc ");
|
|
|
|
linkLine.Append("-static-libstdc++ ");
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-23 07:33:43 -07:00
|
|
|
if (isMinGW)
|
|
|
|
{
|
|
|
|
String[] mingwFiles;
|
|
|
|
String fromDir;
|
|
|
|
|
|
|
|
if (mPtrSize == 4)
|
|
|
|
{
|
|
|
|
fromDir = scope:: String(llvmDir, "i686-w64-mingw32/bin/");
|
2020-08-29 11:56:10 -07:00
|
|
|
mingwFiles = scope:: String[] ( "libgcc_s_dw2-1.dll", "libstdc++-6.dll" );
|
2020-06-23 07:33:43 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fromDir = scope:: String(llvmDir, "x86_64-w64-mingw32/bin/");
|
2020-08-29 11:56:10 -07:00
|
|
|
mingwFiles = scope:: String[] ( "libgcc_s_seh-1.dll", "libstdc++-6.dll", "libwinpthread-1.dll" );
|
2020-06-23 07:33:43 -07:00
|
|
|
}
|
|
|
|
for (var mingwFile in mingwFiles)
|
|
|
|
{
|
|
|
|
String fromPath = scope String(fromDir, mingwFile);
|
|
|
|
//string toPath = projectBuildDir + "/" + mingwFile;
|
|
|
|
String toPath = scope String();
|
|
|
|
Path.GetDirectoryPath(targetPath, toPath);
|
|
|
|
toPath.Append("/", mingwFile);
|
|
|
|
if (!File.Exists(toPath))
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
2020-06-23 07:33:43 -07:00
|
|
|
if (File.Copy(fromPath, toPath) case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputLineSmart("ERROR: Failed to copy mingw file {0}", fromPath);
|
|
|
|
return false;
|
|
|
|
}
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
2020-06-23 07:33:43 -07:00
|
|
|
}
|
|
|
|
}
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
|
|
|
|
2020-07-01 05:29:25 -07:00
|
|
|
List<String> libPaths = scope .();
|
|
|
|
defer ClearAndDeleteItems(libPaths);
|
|
|
|
List<String> depPaths = scope .();
|
|
|
|
defer ClearAndDeleteItems(depPaths);
|
|
|
|
AddLinkDeps(project, options, workspaceOptions, linkLine, libPaths, depPaths);
|
|
|
|
|
|
|
|
for (var libPath in libPaths)
|
|
|
|
{
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, libPath);
|
|
|
|
linkLine.Append(" ");
|
|
|
|
}
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2020-06-23 07:33:43 -07:00
|
|
|
String gccExePath;
|
|
|
|
String clangExePath;
|
|
|
|
if (isMinGW)
|
|
|
|
{
|
|
|
|
gccExePath = "c:/mingw/bin/g++.exe";
|
|
|
|
clangExePath = scope String(llvmDir, "bin/clang++.exe");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gccExePath = "/usr/bin/c++";
|
|
|
|
clangExePath = scope String("/usr/bin/c++");
|
|
|
|
|
|
|
|
if (File.Exists("/usr/bin/clang++"))
|
|
|
|
{
|
|
|
|
gccExePath = "/usr/bin/clang++";
|
|
|
|
clangExePath = scope String("/usr/bin/clang++");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gccExePath = "/usr/bin/c++";
|
|
|
|
clangExePath = scope String("/usr/bin/c++");
|
|
|
|
}
|
|
|
|
}
|
2019-08-27 08:04:41 -07:00
|
|
|
|
|
|
|
if (project.mNeedsTargetRebuild)
|
|
|
|
{
|
|
|
|
if (File.Delete(targetPath) case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputLine("Failed to delete {0}", targetPath);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (workspaceOptions.mToolsetType == .GNU)
|
|
|
|
{
|
2019-10-15 12:28:21 -07:00
|
|
|
if (mPtrSize == 4)
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-10-17 06:47:50 -07:00
|
|
|
/*IDEUtils.AppendWithOptionalQuotes(linkLine, scope String("-L", llvmDir, "/x86_64-w64-mingw32/lib"));
|
2019-08-27 08:04:41 -07:00
|
|
|
linkLine.Append(" ");
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, scope String("-L", llvmDir, "/lib/gcc/x86_64-w64-mingw32/5.2.0"));
|
2019-10-17 06:47:50 -07:00
|
|
|
linkLine.Append(" ");*/
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else // Microsoft
|
|
|
|
{
|
2019-10-15 12:28:21 -07:00
|
|
|
if (mPtrSize == 4)
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
|
|
|
//linkLine.Append("-L\"C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.10586.0\\ucrt\\x86\" ");
|
|
|
|
for (var libPath in gApp.mSettings.mVSSettings.mLib32Paths)
|
|
|
|
{
|
|
|
|
linkLine.AppendF("-L\"{0}\" ", libPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*linkLine.Append("-L\"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\lib\\amd64\" ");
|
|
|
|
linkLine.Append("-L\"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\atlmfc\\lib\\amd64\" ");
|
|
|
|
linkLine.Append("-L\"C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.14393.0\\ucrt\\x64\" ");
|
|
|
|
linkLine.Append("-L\"C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.14393.0\\um\\x64\" ");*/
|
|
|
|
for (var libPath in gApp.mSettings.mVSSettings.mLib64Paths)
|
|
|
|
{
|
|
|
|
linkLine.AppendF("-L\"{0}\" ", libPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.mBuildOptions.mOtherLinkFlags.Length != 0)
|
|
|
|
{
|
|
|
|
var linkFlags = scope String();
|
2019-10-14 17:49:10 -07:00
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, options.mBuildOptions.mOtherLinkFlags, "link flags", linkFlags);
|
2019-08-27 08:04:41 -07:00
|
|
|
linkLine.Append(linkFlags, " ");
|
|
|
|
}
|
|
|
|
|
|
|
|
String compilerExePath = (workspaceOptions.mToolsetType == .GNU) ? gccExePath : clangExePath;
|
|
|
|
String workingDir = scope String();
|
|
|
|
if (!llvmDir.IsEmpty)
|
|
|
|
{
|
|
|
|
workingDir.Append(llvmDir, "bin");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
workingDir.Append(gApp.mInstallDir);
|
|
|
|
}
|
|
|
|
|
2020-06-23 07:33:43 -07:00
|
|
|
if (isWSL)
|
|
|
|
{
|
|
|
|
linkLine.Insert(0, " ");
|
|
|
|
linkLine.Insert(0, compilerExePath);
|
|
|
|
compilerExePath = "wsl.exe";
|
|
|
|
WSLPathFix(linkLine);
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
var runCmd = gApp.QueueRun(compilerExePath, linkLine, workingDir, .UTF8);
|
|
|
|
runCmd.mOnlyIfNotFailed = true;
|
|
|
|
var tagetCompletedCmd = new IDEApp.TargetCompletedCmd(project);
|
|
|
|
tagetCompletedCmd.mOnlyIfNotFailed = true;
|
|
|
|
gApp.mExecutionQueue.Add(tagetCompletedCmd);
|
|
|
|
|
|
|
|
String logStr = scope String();
|
|
|
|
logStr.AppendF("IDE Process {0}\r\n", Platform.BfpProcess_GetCurrentId());
|
|
|
|
logStr.Append(linkLine);
|
|
|
|
String targetLogPath = scope String(targetPath, ".build.txt");
|
2020-06-16 08:30:02 -07:00
|
|
|
if (Utils.WriteTextFile(targetLogPath, logStr) case .Err)
|
|
|
|
gApp.OutputErrorLine("Failed to write {}", targetLogPath);
|
2019-08-27 08:04:41 -07:00
|
|
|
|
|
|
|
project.mLastDidBuild = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-08-06 09:24:37 -07:00
|
|
|
bool QueueProjectWasmLink(Project project, String targetPath, Workspace.Options workspaceOptions, Project.Options options, String objectsArg)
|
|
|
|
{
|
|
|
|
//bool isDebug = gApp.mConfigName.IndexOf("Debug", true) != -1;
|
|
|
|
|
|
|
|
//bool isMinGW = false;
|
|
|
|
|
|
|
|
//String error = scope String();
|
|
|
|
|
2020-09-27 22:20:26 -07:00
|
|
|
bool isTest = options.mBuildOptions.mBuildKind == .Test;
|
|
|
|
bool isExe = ((project.mGeneralOptions.mTargetType != Project.TargetType.BeefLib) && (project.mGeneralOptions.mTargetType != Project.TargetType.BeefTest)) || (isTest);
|
2020-08-06 09:24:37 -07:00
|
|
|
bool isDynLib = project.mGeneralOptions.mTargetType == Project.TargetType.BeefDynLib;
|
|
|
|
|
|
|
|
if (isExe || isDynLib)
|
|
|
|
{
|
|
|
|
String linkLine = scope String();
|
|
|
|
linkLine.Append("-o ");
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, targetPath);
|
|
|
|
linkLine.Append(" ");
|
|
|
|
|
|
|
|
linkLine.Append(objectsArg);
|
|
|
|
|
|
|
|
List<String> libPaths = scope .();
|
|
|
|
defer ClearAndDeleteItems(libPaths);
|
|
|
|
List<String> depPaths = scope .();
|
|
|
|
defer ClearAndDeleteItems(depPaths);
|
|
|
|
AddLinkDeps(project, options, workspaceOptions, linkLine, libPaths, depPaths);
|
|
|
|
|
|
|
|
for (var libPath in libPaths)
|
|
|
|
{
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, libPath);
|
|
|
|
linkLine.Append(" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (project.mNeedsTargetRebuild)
|
|
|
|
{
|
|
|
|
if (File.Delete(targetPath) case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputLine("Failed to delete {0}", targetPath);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.mBuildOptions.mOtherLinkFlags.Length != 0)
|
|
|
|
{
|
|
|
|
var linkFlags = scope String();
|
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, options.mBuildOptions.mOtherLinkFlags, "link flags", linkFlags);
|
|
|
|
linkLine.Append(linkFlags, " ");
|
|
|
|
}
|
|
|
|
|
2020-08-09 07:19:44 -07:00
|
|
|
|
2020-08-06 09:24:37 -07:00
|
|
|
String compilerExePath = scope String();
|
2020-08-09 07:19:44 -07:00
|
|
|
#if BF_PLATFORM_WINDOWS
|
2020-08-06 09:24:37 -07:00
|
|
|
String llvmDir = scope String(IDEApp.sApp.mInstallDir);
|
|
|
|
IDEUtils.FixFilePath(llvmDir);
|
|
|
|
llvmDir.Append("llvm/");
|
|
|
|
#else
|
2020-09-29 08:53:36 -07:00
|
|
|
String llvmDir = "";
|
2020-08-06 09:24:37 -07:00
|
|
|
#endif
|
|
|
|
if (!gApp.mSettings.mEmscriptenPath.IsEmpty)
|
|
|
|
{
|
|
|
|
compilerExePath.Append(gApp.mSettings.mEmscriptenPath);
|
|
|
|
if ((!compilerExePath.EndsWith('\\')) && (!compilerExePath.EndsWith('/')))
|
|
|
|
compilerExePath.Append("/");
|
|
|
|
}
|
2020-08-09 07:19:44 -07:00
|
|
|
compilerExePath.Append(@"/upstream/emscripten/emcc.bat");
|
2020-08-06 09:24:37 -07:00
|
|
|
//linkLine.Append(" c:\\Beef\\wasm\\BeefRT.a -s STRICT=1 -s USE_PTHREADS=1 -s ALIASING_FUNCTION_POINTERS=1 -s ASSERTIONS=0 -s DISABLE_EXCEPTION_CATCHING=0 -s DEMANGLE_SUPPORT=0 -s EVAL_CTORS=1 -s WASM=1 -s \"EXPORTED_FUNCTIONS=['_BeefMain','_BeefDone','_pthread_mutexattr_init','_pthread_mutex_init','_emscripten_futex_wake','_calloc','_sbrk']\"");
|
2020-08-09 07:19:44 -07:00
|
|
|
linkLine.Append(" ", gApp.mInstallDir);
|
|
|
|
linkLine.Append("..\\..\\wasm\\BeefRT.a -s STRICT=1 -s USE_PTHREADS=1 -s ALIASING_FUNCTION_POINTERS=1 -s ASSERTIONS=0 -s DISABLE_EXCEPTION_CATCHING=0 -s DEMANGLE_SUPPORT=0 -s EVAL_CTORS=1 -s WASM=1");
|
2020-08-06 09:24:37 -07:00
|
|
|
|
|
|
|
String workingDir = scope String();
|
|
|
|
if (!llvmDir.IsEmpty)
|
|
|
|
{
|
|
|
|
workingDir.Append(llvmDir, "bin");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
workingDir.Append(gApp.mInstallDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
//linkLine.Append(" --no-entry --export-all");
|
|
|
|
|
|
|
|
var runCmd = gApp.QueueRun(compilerExePath, linkLine, workingDir, .UTF8);
|
|
|
|
runCmd.mOnlyIfNotFailed = true;
|
|
|
|
var tagetCompletedCmd = new IDEApp.TargetCompletedCmd(project);
|
|
|
|
tagetCompletedCmd.mOnlyIfNotFailed = true;
|
|
|
|
gApp.mExecutionQueue.Add(tagetCompletedCmd);
|
|
|
|
|
|
|
|
String logStr = scope String();
|
|
|
|
logStr.AppendF("IDE Process {0}\r\n", Platform.BfpProcess_GetCurrentId());
|
|
|
|
logStr.Append(linkLine);
|
|
|
|
String targetLogPath = scope String(targetPath, ".build.txt");
|
|
|
|
if (Utils.WriteTextFile(targetLogPath, logStr) case .Err)
|
|
|
|
gApp.OutputErrorLine("Failed to write {}", targetLogPath);
|
|
|
|
|
|
|
|
project.mLastDidBuild = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
public static void GetPdbPath(String targetPath, Workspace.Options workspaceOptions, Project.Options options, String outPdbPath)
|
|
|
|
{
|
|
|
|
int lastDotPos = targetPath.LastIndexOf('.');
|
2019-09-18 13:02:01 -07:00
|
|
|
if (lastDotPos == -1)
|
|
|
|
return;
|
2019-08-27 08:04:41 -07:00
|
|
|
outPdbPath.Append(targetPath, 0, lastDotPos);
|
|
|
|
if (workspaceOptions.mToolsetType == .LLVM)
|
|
|
|
outPdbPath.Append("_lld");
|
|
|
|
outPdbPath.Append(".pdb");
|
|
|
|
}
|
|
|
|
|
2019-10-15 14:39:47 -07:00
|
|
|
public static void GetRtLibNames(Workspace.PlatformType platformType, Workspace.Options workspaceOptions, Project.Options options, bool dynName, String outRt, String outDbg)
|
2019-10-29 09:06:51 -07:00
|
|
|
{
|
|
|
|
if ((platformType == .Linux) || (platformType == .macOS) || (platformType == .iOS))
|
2019-10-15 14:39:47 -07:00
|
|
|
{
|
|
|
|
if (options.mBuildOptions.mBeefLibType == .DynamicDebug)
|
2019-10-29 05:01:04 -07:00
|
|
|
outRt.Append("libBeefRT_d.a");
|
2019-10-15 14:39:47 -07:00
|
|
|
else
|
2019-10-29 05:01:04 -07:00
|
|
|
outRt.Append("libBeefRT.a");
|
2019-10-15 14:39:47 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
if ((!dynName) || (options.mBuildOptions.mBeefLibType != .Static))
|
|
|
|
{
|
|
|
|
outRt.Append("Beef", IDEApp.sRTVersionStr, "RT");
|
2019-10-14 17:49:10 -07:00
|
|
|
outRt.Append((Workspace.PlatformType.GetPtrSizeByName(gApp.mPlatformName) == 4) ? "32" : "64");
|
2019-08-27 08:04:41 -07:00
|
|
|
switch (options.mBuildOptions.mBeefLibType)
|
|
|
|
{
|
|
|
|
case .Dynamic:
|
|
|
|
case .DynamicDebug: outRt.Append("_d");
|
|
|
|
case .Static:
|
|
|
|
switch (options.mBuildOptions.mCLibType)
|
|
|
|
{
|
|
|
|
case .None:
|
|
|
|
case .Dynamic, .SystemMSVCRT: outRt.Append("_s");
|
|
|
|
case .DynamicDebug: outRt.Append("_sd");
|
|
|
|
case .Static: outRt.Append("_ss");
|
|
|
|
case .StaticDebug: outRt.Append("_ssd");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
outRt.Append(dynName ? ".dll" : ".lib");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((workspaceOptions.mEnableObjectDebugFlags) || (workspaceOptions.mAllocType == .Debug))
|
|
|
|
{
|
|
|
|
outDbg.Append("Beef", IDEApp.sRTVersionStr, "Dbg");
|
2019-10-14 17:49:10 -07:00
|
|
|
outDbg.Append((Workspace.PlatformType.GetPtrSizeByName(gApp.mPlatformName) == 4) ? "32" : "64");
|
2019-08-27 08:04:41 -07:00
|
|
|
if (options.mBuildOptions.mBeefLibType == .DynamicDebug)
|
|
|
|
outDbg.Append("_d");
|
|
|
|
outDbg.Append(dynName ? ".dll" : ".lib");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-15 14:39:47 -07:00
|
|
|
bool CopyLibFiles(String targetPath, Workspace.Options workspaceOptions, Project.Options options)
|
|
|
|
{
|
|
|
|
List<String> stdLibFileNames = scope .(2);
|
|
|
|
String fromDir;
|
|
|
|
|
|
|
|
fromDir = scope String(gApp.mInstallDir);
|
|
|
|
|
|
|
|
bool AddLib(String dllName)
|
|
|
|
{
|
|
|
|
stdLibFileNames.Add(dllName);
|
|
|
|
|
|
|
|
String fromPath = scope String(fromDir, dllName);
|
|
|
|
String toPath = scope String();
|
|
|
|
Path.GetDirectoryPath(targetPath, toPath);
|
|
|
|
toPath.Append("/", dllName);
|
2019-10-15 17:27:09 -07:00
|
|
|
if (File.CopyIfNewer(fromPath, toPath) case .Err(let err))
|
2019-10-15 14:39:47 -07:00
|
|
|
{
|
2019-10-15 17:27:09 -07:00
|
|
|
gApp.OutputLine("Failed to copy lib file '{0}' to '{1}'", fromPath, toPath);
|
2019-10-15 14:39:47 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
String rtName = scope String();
|
|
|
|
String dbgName = scope String();
|
|
|
|
GetRtLibNames(mPlatformType, workspaceOptions, options, true, rtName, dbgName);
|
|
|
|
if (!rtName.IsEmpty)
|
|
|
|
if (!AddLib(rtName))
|
|
|
|
return false;
|
|
|
|
if (!dbgName.IsEmpty)
|
|
|
|
if (!AddLib(dbgName))
|
|
|
|
return false;
|
|
|
|
switch (workspaceOptions.mAllocType)
|
|
|
|
{
|
|
|
|
case .JEMalloc:
|
|
|
|
if (!AddLib("jemalloc.dll"))
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-07-01 05:29:25 -07:00
|
|
|
void AddLinkDeps(Project project, Project.Options options, Workspace.Options workspaceOptions, String linkLine, List<String> libPaths, List<String> depPaths)
|
|
|
|
{
|
|
|
|
void AddLibPath(StringView libPathIn, Project project, Project.Options projectOptions)
|
|
|
|
{
|
|
|
|
var libPath = new String();
|
|
|
|
if (gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, projectOptions, libPathIn, "lib paths", libPath))
|
|
|
|
{
|
|
|
|
IDEUtils.FixFilePath(libPath);
|
|
|
|
libPaths.Add(libPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
defer ClearAndDeleteItems(depPaths);
|
|
|
|
void AddDepPath(StringView depPathIn, Project project, Project.Options projectOptions)
|
|
|
|
{
|
|
|
|
var depPath = new String();
|
|
|
|
if (gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, projectOptions, depPathIn, "dep paths", depPath))
|
|
|
|
{
|
|
|
|
IDEUtils.FixFilePath(depPath);
|
|
|
|
depPaths.Add(depPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let libPath in options.mBuildOptions.mLibPaths)
|
|
|
|
AddLibPath(libPath, project, options);
|
|
|
|
for (let depPath in options.mBuildOptions.mLinkDependencies)
|
|
|
|
AddDepPath(depPath, project, options);
|
|
|
|
|
|
|
|
List<Project> depProjectList = scope List<Project>();
|
|
|
|
gApp.GetDependentProjectList(project, depProjectList);
|
|
|
|
if (depProjectList.Count > 0)
|
|
|
|
{
|
|
|
|
for (var depProject in depProjectList)
|
|
|
|
{
|
|
|
|
var depOptions = gApp.GetCurProjectOptions(depProject);
|
|
|
|
if (depOptions != null)
|
|
|
|
{
|
|
|
|
if (depOptions.mClangObjectFiles != null)
|
|
|
|
{
|
|
|
|
var argBuilder = scope IDEApp.ArgBuilder(linkLine, true);
|
|
|
|
|
|
|
|
for (var fileName in depOptions.mClangObjectFiles)
|
|
|
|
{
|
|
|
|
argBuilder.AddFileName(fileName);
|
|
|
|
argBuilder.AddSep();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (depProject.mGeneralOptions.mTargetType == .BeefDynLib)
|
|
|
|
{
|
|
|
|
if (mImpLibMap.TryGetValue(depProject, var libPath))
|
|
|
|
{
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, libPath);
|
|
|
|
linkLine.Append(" ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (depProject.mGeneralOptions.mTargetType == .BeefLib)
|
|
|
|
{
|
|
|
|
let depProjectOptions = gApp.GetCurProjectOptions(depProject);
|
|
|
|
var linkFlags = scope String();
|
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, depProject, depProjectOptions, depProjectOptions.mBuildOptions.mOtherLinkFlags, "link flags", linkFlags);
|
|
|
|
if (!linkFlags.IsWhiteSpace)
|
|
|
|
linkLine.Append(linkFlags, " ");
|
|
|
|
|
|
|
|
for (let libPath in depProjectOptions.mBuildOptions.mLibPaths)
|
|
|
|
AddLibPath(libPath, depProject, depProjectOptions);
|
|
|
|
for (let depPath in depProjectOptions.mBuildOptions.mLinkDependencies)
|
|
|
|
AddDepPath(depPath, depProject, depProjectOptions);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
bool QueueProjectMSLink(Project project, String targetPath, String configName, Workspace.Options workspaceOptions, Project.Options options, String objectsArg)
|
|
|
|
{
|
2019-10-15 12:28:21 -07:00
|
|
|
bool is64Bit = mPtrSize == 8;
|
2019-10-14 17:49:10 -07:00
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
String llvmDir = scope String(IDEApp.sApp.mInstallDir);
|
|
|
|
IDEUtils.FixFilePath(llvmDir);
|
|
|
|
llvmDir.Append("llvm/");
|
|
|
|
|
2020-09-27 22:20:26 -07:00
|
|
|
bool isTest = options.mBuildOptions.mBuildKind == .Test;
|
|
|
|
bool isExe = ((project.mGeneralOptions.mTargetType != Project.TargetType.BeefLib) && (project.mGeneralOptions.mTargetType != Project.TargetType.BeefTest)) || (isTest);
|
2021-06-28 05:47:37 -07:00
|
|
|
if (options.mBuildOptions.mBuildKind == .StaticLib)
|
|
|
|
isExe = false;
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
if (isExe)
|
|
|
|
{
|
|
|
|
String linkLine = scope String();
|
|
|
|
|
|
|
|
linkLine.Append("-out:");
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, targetPath);
|
|
|
|
linkLine.Append(" ");
|
|
|
|
|
2020-09-27 22:20:26 -07:00
|
|
|
if (isTest)
|
2019-08-27 08:04:41 -07:00
|
|
|
linkLine.Append("-subsystem:console ");
|
2020-03-21 07:10:16 -07:00
|
|
|
else if (project.mGeneralOptions.mTargetType == .BeefGUIApplication)
|
2019-08-27 08:04:41 -07:00
|
|
|
linkLine.Append("-subsystem:windows ");
|
2020-03-21 07:10:16 -07:00
|
|
|
else if (project.mGeneralOptions.mTargetType == .C_GUIApplication)
|
2019-08-27 08:04:41 -07:00
|
|
|
linkLine.Append("-subsystem:console ");
|
|
|
|
else if (project.mGeneralOptions.mTargetType == .BeefDynLib)
|
|
|
|
{
|
|
|
|
linkLine.Append("-dll ");
|
|
|
|
|
|
|
|
if (targetPath.EndsWith(".dll", .InvariantCultureIgnoreCase))
|
|
|
|
{
|
|
|
|
linkLine.Append("-implib:\"");
|
|
|
|
linkLine.Append(targetPath, 0, targetPath.Length - 4);
|
|
|
|
linkLine.Append(".lib\" ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
linkLine.Append(objectsArg);
|
|
|
|
|
2019-10-15 14:39:47 -07:00
|
|
|
CopyLibFiles(targetPath, workspaceOptions, options);
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2020-03-30 14:08:51 -07:00
|
|
|
List<String> libPaths = scope .();
|
|
|
|
defer ClearAndDeleteItems(libPaths);
|
|
|
|
List<String> depPaths = scope .();
|
|
|
|
defer ClearAndDeleteItems(depPaths);
|
2020-07-01 05:29:25 -07:00
|
|
|
AddLinkDeps(project, options, workspaceOptions, linkLine, libPaths, depPaths);
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
/*if (File.Delete(targetPath).Failed(true))
|
|
|
|
{
|
|
|
|
OutputLine("Failed to delete {0}", targetPath);
|
|
|
|
return false;
|
|
|
|
}*/
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
switch (options.mBuildOptions.mCLibType)
|
|
|
|
{
|
|
|
|
case .None:
|
|
|
|
linkLine.Append("-nodefaultlib ");
|
|
|
|
case .Dynamic:
|
|
|
|
//linkLine.Append((workspaceOptions.mMachineType == .x86) ? "-defaultlib:msvcprt " : "-defaultlib:msvcrt ");
|
|
|
|
linkLine.Append("-defaultlib:msvcrt ");
|
|
|
|
case .Static:
|
|
|
|
//linkLine.Append((workspaceOptions.mMachineType == .x86) ? "-defaultlib:libcpmt " : "-defaultlib:libcmt ");
|
|
|
|
linkLine.Append("-defaultlib:libcmt ");
|
|
|
|
case .DynamicDebug:
|
|
|
|
//linkLine.Append((workspaceOptions.mMachineType == .x86) ? "-defaultlib:msvcprtd " : "-defaultlib:msvcrtd ");
|
|
|
|
linkLine.Append("-defaultlib:msvcrtd ");
|
|
|
|
case .StaticDebug:
|
|
|
|
//linkLine.Append((workspaceOptions.mMachineType == .x86) ? "-defaultlib:libcpmtd " : "-defaultlib:libcmtd ");
|
|
|
|
linkLine.Append("-defaultlib:libcmtd ");
|
|
|
|
case .SystemMSVCRT:
|
|
|
|
linkLine.Append("-nodefaultlib ");
|
|
|
|
|
|
|
|
String minRTModName = scope String();
|
2020-03-21 07:10:16 -07:00
|
|
|
if ((project.mGeneralOptions.mTargetType == .BeefGUIApplication) ||
|
|
|
|
(project.mGeneralOptions.mTargetType == .C_GUIApplication))
|
2019-09-28 09:48:37 -07:00
|
|
|
minRTModName.Append("g");
|
|
|
|
if (options.mBuildOptions.mBeefLibType == .DynamicDebug)
|
|
|
|
minRTModName.Append("d");
|
|
|
|
if (!minRTModName.IsEmpty)
|
|
|
|
minRTModName.Insert(0, "_");
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-10-14 17:49:10 -07:00
|
|
|
if (!is64Bit)
|
2021-02-25 10:14:22 -08:00
|
|
|
linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x86\" \"", gApp.mInstallDir, "lib\\x86\\msvcrt.lib\" Beef", IDEApp.sRTVersionStr,"MinRT32", minRTModName, ".lib ");
|
2019-09-28 09:48:37 -07:00
|
|
|
else
|
2021-02-25 10:14:22 -08:00
|
|
|
linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x64\" \"", gApp.mInstallDir, "lib\\x64\\msvcrt.lib\" Beef", IDEApp.sRTVersionStr,"MinRT64", minRTModName, ".lib ");
|
2021-02-03 09:00:49 -08:00
|
|
|
linkLine.Append("ntdll.lib user32.lib kernel32.lib gdi32.lib winmm.lib shell32.lib ole32.lib rpcrt4.lib version.lib comdlg32.lib -ignore:4049 -ignore:4217 ");
|
2019-09-28 09:48:37 -07:00
|
|
|
}
|
2020-03-30 14:08:51 -07:00
|
|
|
|
|
|
|
for (var libPath in libPaths)
|
|
|
|
{
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, libPath);
|
|
|
|
linkLine.Append(" ");
|
|
|
|
}
|
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
linkLine.Append("-nologo ");
|
2020-07-18 07:05:22 -07:00
|
|
|
|
|
|
|
if ((project.mGeneralOptions.mTargetType == .BeefDynLib) && (workspaceOptions.mAllowHotSwapping) && (is64Bit))
|
2020-07-01 12:46:04 -07:00
|
|
|
{
|
2020-07-18 07:05:22 -07:00
|
|
|
// This helps to ensure that DLLs have enough hot swapping space after them
|
2020-07-01 12:46:04 -07:00
|
|
|
int nameHash = targetPath.GetHashCode();
|
|
|
|
int64 wantAddress = (((nameHash & 0x3FFFF) + 0x10) << 28);
|
|
|
|
linkLine.AppendF("-base:0x{0:X} -dynamicbase:no ", wantAddress);
|
|
|
|
}
|
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
// Incremental just seems to be slower for Beef. Test on larger projects to verify
|
|
|
|
linkLine.Append("-incremental:no ");
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
if (options.mBuildOptions.mStackSize > 0)
|
|
|
|
linkLine.AppendF("-stack:{} ", options.mBuildOptions.mStackSize);
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
linkLine.Append("-pdb:");
|
|
|
|
let pdbName = scope String();
|
|
|
|
GetPdbPath(targetPath, workspaceOptions, options, pdbName);
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, pdbName);
|
|
|
|
linkLine.Append(" ");
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
//TODO: Only add -debug if we have some debug info?
|
|
|
|
//if (isDebug)
|
|
|
|
if (workspaceOptions.mEmitDebugInfo != .No)
|
|
|
|
linkLine.Append("-debug ");
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
if (workspaceOptions.mBfOptimizationLevel.IsOptimized())
|
|
|
|
//linkLine.Append("-opt:ref -verbose ");
|
|
|
|
linkLine.Append("-opt:ref ");
|
|
|
|
else
|
|
|
|
linkLine.Append("-opt:noref ");
|
|
|
|
|
2019-10-14 17:49:10 -07:00
|
|
|
if (!is64Bit)
|
2019-09-28 09:48:37 -07:00
|
|
|
{
|
|
|
|
for (var libPath in gApp.mSettings.mVSSettings.mLib32Paths)
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
2019-09-28 09:48:37 -07:00
|
|
|
linkLine.AppendF("-libpath:\"{0}\" ", libPath);
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
2019-09-28 09:48:37 -07:00
|
|
|
linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x86\" ");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (var libPath in gApp.mSettings.mVSSettings.mLib64Paths)
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
2019-09-28 09:48:37 -07:00
|
|
|
linkLine.AppendF("-libpath:\"{0}\" ", libPath);
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
2019-09-28 09:48:37 -07:00
|
|
|
linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x64\" ");
|
|
|
|
}
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
String targetDir = scope String();
|
|
|
|
Path.GetDirectoryPath(targetPath, targetDir);
|
|
|
|
linkLine.Append("-libpath:");
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, targetDir);
|
|
|
|
linkLine.Append(" ");
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
if (options.mBuildOptions.mOtherLinkFlags.Length != 0)
|
|
|
|
{
|
|
|
|
var linkFlags = scope String();
|
2019-10-14 17:49:10 -07:00
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, options.mBuildOptions.mOtherLinkFlags, "link flags", linkFlags);
|
2019-09-28 09:48:37 -07:00
|
|
|
linkLine.Append(linkFlags, " ");
|
|
|
|
}
|
|
|
|
|
|
|
|
let winOptions = project.mWindowsOptions;
|
|
|
|
|
|
|
|
String cacheStr = scope String();
|
|
|
|
|
2019-12-21 05:48:44 -08:00
|
|
|
void AddBuildFileDependency(StringView filePath, bool resolveString = false)
|
2019-09-28 09:48:37 -07:00
|
|
|
{
|
2019-12-21 05:48:44 -08:00
|
|
|
var filePath;
|
|
|
|
|
|
|
|
if ((resolveString) && (filePath.Contains('$')))
|
|
|
|
{
|
|
|
|
String resolvedFilePath = scope:: String();
|
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, filePath, "link flags", resolvedFilePath);
|
|
|
|
filePath = resolvedFilePath;
|
|
|
|
}
|
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
int64 fileTime = 0;
|
|
|
|
if (!filePath.IsEmpty)
|
|
|
|
fileTime = File.GetLastWriteTime(filePath).GetValueOrDefault().ToFileTime();
|
|
|
|
cacheStr.AppendF("{}\t{}\n", filePath, fileTime);
|
|
|
|
}
|
2019-08-27 08:04:41 -07:00
|
|
|
|
2019-09-28 09:48:37 -07:00
|
|
|
cacheStr.AppendF("Args\t{}\n", linkLine);
|
|
|
|
cacheStr.AppendF("Toolset\t{}\n", workspaceOptions.mToolsetType);
|
|
|
|
AddBuildFileDependency(project.mWindowsOptions.mIconFile);
|
|
|
|
AddBuildFileDependency(project.mWindowsOptions.mManifestFile);
|
|
|
|
cacheStr.AppendF("Description\t{}\n", project.mWindowsOptions.mDescription);
|
|
|
|
cacheStr.AppendF("Comments\t{}\n", project.mWindowsOptions.mComments);
|
|
|
|
cacheStr.AppendF("Company\t{}\n", project.mWindowsOptions.mCompany);
|
|
|
|
cacheStr.AppendF("Product\t{}\n", project.mWindowsOptions.mProduct);
|
|
|
|
cacheStr.AppendF("Copyright\t{}\n", project.mWindowsOptions.mCopyright);
|
|
|
|
cacheStr.AppendF("FileVersion\t{}\n", project.mWindowsOptions.mFileVersion);
|
|
|
|
cacheStr.AppendF("ProductVersion\t{}\n", project.mWindowsOptions.mProductVersion);
|
2020-03-30 14:08:51 -07:00
|
|
|
for (var linkDep in depPaths)
|
|
|
|
AddBuildFileDependency(linkDep, true);
|
|
|
|
for (var linkDep in libPaths)
|
2019-12-21 05:48:44 -08:00
|
|
|
AddBuildFileDependency(linkDep, true);
|
2019-09-28 09:48:37 -07:00
|
|
|
|
2020-07-01 05:29:25 -07:00
|
|
|
String projectBuildDir = scope String();
|
|
|
|
gApp.GetProjectBuildDir(project, projectBuildDir);
|
2019-09-28 09:48:37 -07:00
|
|
|
String prevCacheStr = scope .();
|
|
|
|
gApp.mBfBuildCompiler.GetBuildValue(projectBuildDir, "Link", prevCacheStr);
|
|
|
|
if (prevCacheStr != cacheStr)
|
|
|
|
{
|
|
|
|
project.mNeedsTargetRebuild = true;
|
|
|
|
gApp.mBfBuildCompiler.SetBuildValue(projectBuildDir, "Link", cacheStr);
|
|
|
|
gApp.mBfBuildCompiler.WriteBuildCache(projectBuildDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (project.mNeedsTargetRebuild)
|
|
|
|
{
|
2019-08-27 08:04:41 -07:00
|
|
|
if ((!String.IsNullOrWhiteSpace(project.mWindowsOptions.mIconFile)) ||
|
|
|
|
(!String.IsNullOrWhiteSpace(project.mWindowsOptions.mManifestFile)) ||
|
|
|
|
(winOptions.HasVersionInfo()))
|
2019-09-28 09:48:37 -07:00
|
|
|
{
|
2019-08-27 08:04:41 -07:00
|
|
|
String resOutPath = scope String();
|
|
|
|
resOutPath.Append(projectBuildDir, "\\Resource.res");
|
|
|
|
|
|
|
|
String iconPath = scope String();
|
2019-10-14 17:49:10 -07:00
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, winOptions.mIconFile, "icon file", iconPath);
|
2019-08-27 08:04:41 -07:00
|
|
|
|
|
|
|
// Generate resource
|
|
|
|
Result<void> CreateResourceFile()
|
|
|
|
{
|
|
|
|
ResourceGen resGen = scope ResourceGen();
|
|
|
|
if (resGen.Start(resOutPath) case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputErrorLine("Failed to create resource file '{0}'", resOutPath);
|
|
|
|
return .Err;
|
|
|
|
}
|
|
|
|
if (!iconPath.IsWhiteSpace)
|
|
|
|
{
|
|
|
|
Path.GetAbsolutePath(scope String(iconPath), project.mProjectDir, iconPath..Clear());
|
|
|
|
if (resGen.AddIcon(iconPath) case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputErrorLine("Failed to add icon");
|
|
|
|
return .Err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let targetFileName = scope String();
|
|
|
|
Path.GetFileName(targetPath, targetFileName);
|
|
|
|
|
|
|
|
if (resGen.AddVersion(winOptions.mDescription, winOptions.mComments, winOptions.mCompany, winOptions.mProduct,
|
|
|
|
winOptions.mCopyright, winOptions.mFileVersion, winOptions.mProductVersion, targetFileName) case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputErrorLine("Failed to add version");
|
|
|
|
return .Err;
|
|
|
|
}
|
|
|
|
|
|
|
|
String manifestPath = scope String();
|
2019-10-14 17:49:10 -07:00
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, winOptions.mManifestFile, "manifest file", manifestPath);
|
2019-08-27 08:04:41 -07:00
|
|
|
if (!manifestPath.IsWhiteSpace)
|
|
|
|
{
|
|
|
|
Path.GetAbsolutePath(scope String(manifestPath), project.mProjectDir, manifestPath..Clear());
|
|
|
|
if (resGen.AddManifest(manifestPath) case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputErrorLine("Failed to add manifest file");
|
|
|
|
return .Err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Try!(resGen.Finish());
|
|
|
|
return .Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CreateResourceFile() case .Err)
|
|
|
|
{
|
|
|
|
gApp.OutputErrorLine("Failed to generate resource file: {0}", resOutPath);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, resOutPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
String linkerPath = scope String();
|
|
|
|
if (workspaceOptions.mToolsetType == .LLVM)
|
|
|
|
{
|
|
|
|
linkerPath.Clear();
|
|
|
|
linkerPath.Append(gApp.mInstallDir);
|
|
|
|
linkerPath.Append(@"llvm\bin\lld-link.exe");
|
|
|
|
//linkerPath = @"C:\Program Files\LLVM\bin\lld-link.exe";
|
|
|
|
|
|
|
|
var ltoType = workspaceOptions.mLTOType;
|
|
|
|
if (options.mBeefOptions.mLTOType != null)
|
|
|
|
ltoType = options.mBeefOptions.mLTOType.Value;
|
|
|
|
|
|
|
|
if (ltoType == .Thin)
|
|
|
|
{
|
|
|
|
linkLine.Append(" /lldltocache:");
|
|
|
|
|
|
|
|
String ltoPath = scope String();
|
|
|
|
Path.GetDirectoryPath(targetPath, ltoPath);
|
|
|
|
ltoPath.Append("/ltocache");
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(linkLine, ltoPath);
|
|
|
|
}
|
2020-10-30 14:57:53 -07:00
|
|
|
|
|
|
|
if ((mPlatformType == .Windows) && (!is64Bit))
|
|
|
|
linkLine.Append(" /safeseh:no");
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
2021-02-25 10:14:22 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
let binPath = (!is64Bit) ? gApp.mSettings.mVSSettings.mBin32Path : gApp.mSettings.mVSSettings.mBin64Path;
|
|
|
|
if (binPath.IsWhiteSpace)
|
|
|
|
{
|
|
|
|
gApp.OutputErrorLine("Visual Studio tool path not configured. Check Visual Studio configuration in File\\Preferences\\Settings.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
linkerPath.Append(binPath);
|
|
|
|
linkerPath.Append("/link.exe");
|
|
|
|
}
|
2020-05-15 17:01:56 -07:00
|
|
|
|
|
|
|
if (options.mBuildOptions.mBeefLibType != .DynamicDebug)
|
|
|
|
{
|
|
|
|
linkLine.Append(" /ignore:4099");
|
|
|
|
}
|
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
var runCmd = gApp.QueueRun(linkerPath, linkLine, gApp.mInstallDir, .UTF16WithBom);
|
2021-01-03 06:24:49 -08:00
|
|
|
runCmd.mEnvVars = new .() { (new String("VSLANG"), new String("1033")) };
|
2019-08-27 08:04:41 -07:00
|
|
|
runCmd.mOnlyIfNotFailed = true;
|
|
|
|
var tagetCompletedCmd = new IDEApp.TargetCompletedCmd(project);
|
|
|
|
tagetCompletedCmd.mOnlyIfNotFailed = true;
|
|
|
|
gApp.mExecutionQueue.Add(tagetCompletedCmd);
|
|
|
|
|
|
|
|
String logStr = scope String();
|
|
|
|
logStr.AppendF("IDE Process {0}\r\n", Platform.BfpProcess_GetCurrentId());
|
|
|
|
logStr.Append(linkLine);
|
|
|
|
String targetLogPath = scope String(targetPath, ".build.txt");
|
2020-06-16 08:30:02 -07:00
|
|
|
if (Utils.WriteTextFile(targetLogPath, logStr) case .Err)
|
|
|
|
gApp.OutputErrorLine("Failed to write {}", targetLogPath);
|
2019-08-27 08:04:41 -07:00
|
|
|
|
|
|
|
project.mLastDidBuild = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-05-13 12:28:20 -07:00
|
|
|
public bool QueueProjectCompile(Project project, Project hotProject, IDEApp.BuildCompletedCmd completedCompileCmd, List<String> hotFileNames, CompileKind compileKind)
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
|
|
|
project.mLastDidBuild = false;
|
|
|
|
|
|
|
|
TestManager.ProjectInfo testProjectInfo = null;
|
|
|
|
if (gApp.mTestManager != null)
|
|
|
|
testProjectInfo = gApp.mTestManager.GetProjectInfo(project);
|
|
|
|
|
|
|
|
var configSelection = gApp.GetCurConfigSelection(project);
|
|
|
|
Project.Options options = gApp.GetCurProjectOptions(project);
|
|
|
|
if (options == null)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
Workspace.Options workspaceOptions = gApp.GetCurWorkspaceOptions();
|
2019-10-05 10:26:26 -07:00
|
|
|
BfCompiler bfCompiler = gApp.mBfBuildCompiler;
|
2019-08-27 08:04:41 -07:00
|
|
|
var bfProject = gApp.mBfBuildSystem.mProjectMap[project];
|
2019-10-05 10:26:26 -07:00
|
|
|
bool bfHadOutputChanges = false;
|
2019-08-27 08:04:41 -07:00
|
|
|
List<String> bfFileNames = scope List<String>();
|
2020-02-21 06:52:08 -08:00
|
|
|
if (hotProject == null)
|
|
|
|
{
|
|
|
|
if (project.mCurBfOutputFileNames == null)
|
|
|
|
{
|
|
|
|
project.mCurBfOutputFileNames = new .();
|
|
|
|
bfCompiler.GetOutputFileNames(bfProject, true, out bfHadOutputChanges, project.mCurBfOutputFileNames);
|
|
|
|
}
|
|
|
|
for (var fileName in project.mCurBfOutputFileNames)
|
|
|
|
bfFileNames.Add(fileName);
|
|
|
|
}
|
|
|
|
else
|
2019-10-05 10:26:26 -07:00
|
|
|
{
|
2020-02-21 06:52:08 -08:00
|
|
|
bfCompiler.GetOutputFileNames(bfProject, true, out bfHadOutputChanges, bfFileNames);
|
|
|
|
defer:: ClearAndDeleteItems(bfFileNames);
|
2019-10-05 10:26:26 -07:00
|
|
|
}
|
2019-08-27 08:04:41 -07:00
|
|
|
if (bfHadOutputChanges)
|
|
|
|
project.mNeedsTargetRebuild = true;
|
|
|
|
|
|
|
|
List<ProjectSource> allFileNames = scope List<ProjectSource>();
|
|
|
|
List<String> clangAllObjNames = scope List<String>();
|
2019-10-05 10:26:26 -07:00
|
|
|
|
2019-08-27 08:04:41 -07:00
|
|
|
gApp.GetClangFiles(project.mRootFolder, allFileNames);
|
|
|
|
|
|
|
|
String workspaceBuildDir = scope String();
|
|
|
|
gApp.GetWorkspaceBuildDir(workspaceBuildDir);
|
|
|
|
String projectBuildDir = scope String();
|
|
|
|
gApp.GetProjectBuildDir(project, projectBuildDir);
|
|
|
|
if (!projectBuildDir.IsEmpty)
|
|
|
|
Directory.CreateDirectory(projectBuildDir).IgnoreError();
|
|
|
|
|
|
|
|
String targetPath = scope String();
|
|
|
|
|
|
|
|
String outputDir = scope String();
|
|
|
|
String absOutputDir = scope String();
|
|
|
|
|
|
|
|
if (testProjectInfo != null)
|
|
|
|
{
|
|
|
|
absOutputDir.Append(projectBuildDir);
|
|
|
|
outputDir = absOutputDir;
|
|
|
|
targetPath.Append(outputDir, "/", project.mProjectName);
|
2020-06-30 12:13:20 -07:00
|
|
|
if (mPlatformType == .Windows)
|
|
|
|
targetPath.Append(".exe");
|
2019-08-27 08:04:41 -07:00
|
|
|
Debug.Assert(testProjectInfo.mTestExePath == null);
|
|
|
|
testProjectInfo.mTestExePath = new String(targetPath);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-10-14 17:49:10 -07:00
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, options.mBuildOptions.mTargetDirectory, "target directory", outputDir);
|
2019-08-27 08:04:41 -07:00
|
|
|
Path.GetAbsolutePath(project.mProjectDir, outputDir, absOutputDir);
|
|
|
|
outputDir = absOutputDir;
|
2019-10-14 17:49:10 -07:00
|
|
|
gApp.ResolveConfigString(gApp.mPlatformName, workspaceOptions, project, options, "$(TargetPath)", "target path", targetPath);
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
|
|
|
IDEUtils.FixFilePath(targetPath);
|
|
|
|
if (!File.Exists(targetPath))
|
|
|
|
{
|
|
|
|
project.mNeedsTargetRebuild = true;
|
|
|
|
|
|
|
|
String targetDir = scope String();
|
2020-04-26 08:46:45 -07:00
|
|
|
Path.GetDirectoryPath(targetPath, targetDir).IgnoreError();
|
2019-08-27 08:04:41 -07:00
|
|
|
if (!targetDir.IsEmpty)
|
|
|
|
Directory.CreateDirectory(targetDir).IgnoreError();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (project.mGeneralOptions.mTargetType == .BeefDynLib)
|
|
|
|
{
|
|
|
|
if (targetPath.EndsWith(".dll", .InvariantCultureIgnoreCase))
|
|
|
|
{
|
|
|
|
String libPath = new .();
|
|
|
|
libPath.Append(targetPath, 0, targetPath.Length - 4);
|
|
|
|
libPath.Append(".lib");
|
|
|
|
mImpLibMap.Add(project, libPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-25 10:14:22 -08:00
|
|
|
mTargetPathMap[project] = new String(targetPath);
|
|
|
|
|
2019-08-29 14:19:07 -07:00
|
|
|
if (hotProject == null)
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
2020-05-13 12:28:20 -07:00
|
|
|
switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPreBuildCmds))
|
2019-08-29 14:19:07 -07:00
|
|
|
{
|
|
|
|
case .NoCommands:
|
|
|
|
case .HadCommands:
|
|
|
|
case .Failed:
|
|
|
|
completedCompileCmd.mFailed = true;
|
|
|
|
}
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (project.mGeneralOptions.mTargetType == .CustomBuild)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if IDE_C_SUPPORT
|
|
|
|
bool buildAll = false;
|
|
|
|
String buildStringFilePath = scope String();
|
|
|
|
mDepClang.GetBuildStringFileName(projectBuildDir, project, buildStringFilePath);
|
|
|
|
String newBuildString = scope String();
|
|
|
|
GetClangBuildString(project, options, workspaceOptions, true, newBuildString);
|
|
|
|
String clangBuildString = scope String();
|
|
|
|
GetClangBuildString(project, options, workspaceOptions, false, clangBuildString);
|
|
|
|
newBuildString.Append("|", clangBuildString);
|
|
|
|
|
|
|
|
if (mDepClang.mDoDependencyCheck)
|
|
|
|
{
|
|
|
|
String prependStr = scope String();
|
|
|
|
options.mCOptions.mCompilerType.ToString(prependStr);
|
|
|
|
prependStr.Append("|");
|
|
|
|
newBuildString.Insert(0, prependStr);
|
|
|
|
String oldBuildString;
|
|
|
|
mDepClang.mProjectBuildString.TryGetValue(project, out oldBuildString);
|
|
|
|
|
|
|
|
if (oldBuildString == null)
|
|
|
|
{
|
|
|
|
oldBuildString = new String();
|
|
|
|
File.ReadAllText(buildStringFilePath, oldBuildString).IgnoreError();
|
|
|
|
mDepClang.mProjectBuildString[project] = oldBuildString;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (newBuildString != oldBuildString)
|
|
|
|
{
|
|
|
|
buildAll = true;
|
|
|
|
|
|
|
|
if (case .Err = File.WriteAllText(buildStringFilePath, newBuildString))
|
|
|
|
OutputLine("Failed to write {0}", buildStringFilePath);
|
|
|
|
|
|
|
|
delete oldBuildString;
|
|
|
|
mDepClang.mProjectBuildString[project] = new String(newBuildString);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
using (mDepClang.mMonitor.Enter())
|
|
|
|
{
|
|
|
|
if (options.mClangObjectFiles == null)
|
|
|
|
options.mClangObjectFiles = new List<String>();
|
|
|
|
else
|
|
|
|
ClearAndDeleteItems(options.mClangObjectFiles);
|
|
|
|
|
|
|
|
for (var projectSource in allFileNames)
|
|
|
|
{
|
|
|
|
var fileEntry = mDepClang.GetProjectEntry(projectSource);
|
|
|
|
Debug.Assert((fileEntry != null) || (!mDepClang.mCompileWaitsForQueueEmpty));
|
|
|
|
|
|
|
|
String filePath = scope String();
|
|
|
|
projectSource.GetFullImportPath(filePath);
|
|
|
|
String baseName = scope String();
|
|
|
|
Path.GetFileNameWithoutExtension(filePath, baseName);
|
|
|
|
String objName = stack String();
|
|
|
|
objName.Append(projectBuildDir, "/", baseName, (options.mCOptions.mGenerateLLVMAsm ? ".ll" : ".obj"));
|
|
|
|
|
|
|
|
if (filePath.Contains("test2.cpp"))
|
|
|
|
{
|
2020-10-30 14:57:53 -07:00
|
|
|
\ NOP!();
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
bool needsRebuild = true;
|
|
|
|
if ((!buildAll) && (fileEntry != null))
|
|
|
|
{
|
|
|
|
mDepClang.SetEntryObjFileName(fileEntry, objName);
|
|
|
|
mDepClang.SetEntryBuildStringFileName(fileEntry, buildStringFilePath);
|
|
|
|
needsRebuild = mDepClang.DoesEntryNeedRebuild(fileEntry);
|
|
|
|
}
|
|
|
|
if (needsRebuild)
|
|
|
|
{
|
|
|
|
if (hotProject != null)
|
|
|
|
{
|
|
|
|
OutputLine("Hot swap detected disallowed C/C++ change: {0}", filePath);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
project.mNeedsTargetRebuild = true;
|
|
|
|
var runCmd = CompileSource(project, workspaceOptions, options, filePath);
|
|
|
|
runCmd.mParallelGroup = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
options.mClangObjectFiles.Add(new String(objName));
|
|
|
|
|
|
|
|
if (hotProject != null)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
clangAllObjNames.Add(objName);
|
|
|
|
|
|
|
|
IdSpan sourceCharIdData;
|
|
|
|
String sourceCode = scope String();
|
|
|
|
FindProjectSourceContent(projectSource, out sourceCharIdData, true, sourceCode);
|
|
|
|
mWorkspace.ProjectSourceCompiled(projectSource, sourceCode, sourceCharIdData);
|
|
|
|
sourceCharIdData.Dispose();
|
|
|
|
|
|
|
|
String* fileEntryPtr;
|
|
|
|
if (completedCompileCmd.mClangCompiledFiles.Add(filePath, out fileEntryPtr))
|
|
|
|
*fileEntryPtr = new String(filePath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
String llvmDir = scope String(IDEApp.sApp.mInstallDir);
|
|
|
|
IDEUtils.FixFilePath(llvmDir);
|
|
|
|
llvmDir.Append("llvm/");
|
|
|
|
|
|
|
|
if (hotProject != null)
|
|
|
|
{
|
|
|
|
if ((hotProject == project) || (hotProject.HasDependency(project.mProjectName)))
|
|
|
|
{
|
|
|
|
for (var fileName in bfFileNames)
|
|
|
|
hotFileNames.Add(new String(fileName));
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
String objectsArg = scope String();
|
|
|
|
var argBuilder = scope IDEApp.ArgBuilder(objectsArg, workspaceOptions.mToolsetType != .GNU);
|
|
|
|
for (var bfFileName in bfFileNames)
|
|
|
|
{
|
|
|
|
argBuilder.AddFileName(bfFileName);
|
|
|
|
argBuilder.AddSep();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var objName in clangAllObjNames)
|
|
|
|
{
|
|
|
|
IDEUtils.AppendWithOptionalQuotes(objectsArg, objName);
|
|
|
|
objectsArg.Append(" ");
|
|
|
|
}
|
|
|
|
|
2020-08-06 09:24:37 -07:00
|
|
|
if (mPlatformType == .Wasm)
|
|
|
|
{
|
|
|
|
if (!QueueProjectWasmLink(project, targetPath, workspaceOptions, options, objectsArg))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (workspaceOptions.mToolsetType == .GNU)
|
2019-08-27 08:04:41 -07:00
|
|
|
{
|
2019-10-23 07:12:36 -07:00
|
|
|
if ((options.mBuildOptions.mBuildKind == .StaticLib) || (options.mBuildOptions.mBuildKind == .DynamicLib))
|
|
|
|
{
|
|
|
|
if (!QueueProjectGNUArchive(project, targetPath, workspaceOptions, options, objectsArg))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (!QueueProjectGNULink(project, targetPath, workspaceOptions, options, objectsArg))
|
2019-08-27 08:04:41 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else // MS
|
|
|
|
{
|
2019-10-15 12:28:21 -07:00
|
|
|
if (mPlatformType != .Windows)
|
|
|
|
{
|
|
|
|
gApp.OutputErrorLine("Project '{}' cannot be linked with the Windows Toolset for platform '{}'", project.mProjectName, mPlatformType);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (!QueueProjectMSLink(project, targetPath, configSelection.mConfig, workspaceOptions, options, objectsArg))
|
2019-08-27 08:04:41 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2021-02-25 10:14:22 -08:00
|
|
|
|
|
|
|
public bool QueueProjectPostBuild(Project project, Project hotProject, IDEApp.BuildCompletedCmd completedCompileCmd, List<String> hotFileNames, CompileKind compileKind)
|
|
|
|
{
|
|
|
|
if (hotProject != null)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
Project.Options options = gApp.GetCurProjectOptions(project);
|
|
|
|
if (options == null)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
String targetPath = null;
|
|
|
|
mTargetPathMap.TryGetValue(project, out targetPath);
|
|
|
|
if (targetPath == null)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPostBuildCmds))
|
|
|
|
{
|
|
|
|
case .NoCommands:
|
|
|
|
case .HadCommands:
|
|
|
|
case .Failed:
|
|
|
|
completedCompileCmd.mFailed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2019-08-27 08:04:41 -07:00
|
|
|
}
|
|
|
|
}
|