diff --git a/SamplesDef.json b/SamplesDef.json index 941ce2d04..ca806929e 100644 --- a/SamplesDef.json +++ b/SamplesDef.json @@ -143,6 +143,20 @@ "&'./{testFolder}/projects/output/win64/{configuration}/fastbuildsimpleexecutable.exe'" ] }, + { + "Name": "FastBuildDuplicateFile", + "CIs": [ "github", "gitlab" ], + "OSs": [ "windows-2019", "windows-2022" ], + "Frameworks": [ "net6.0" ], + "Configurations": [ "debug", "release" ], + "TestFolder": "samples/FastBuildDuplicateFile", + "Commands": + [ + "./RunSharpmake.ps1 -workingDirectory {testFolder} -sharpmakeFile \"FastBuildDuplicateFile.sharpmake.cs\" -framework {framework}", + "./Compile.ps1 -slnOrPrjFile \"fastbuildsample_{VsVersionSuffix}_win64_fastbuild.sln\" -configuration {configuration} -platform \"x64\" -WorkingDirectory \"{testFolder}/projects\" -VsVersion {os} -compiler MsBuild", + "&'./{testFolder}/projects/output/win64/{configuration}/duplicatefileproject.exe'" + ] + }, { "Name": "HelloAndroid", "CIs": [], diff --git a/Sharpmake.Generators/FastBuild/Bff.Template.cs b/Sharpmake.Generators/FastBuild/Bff.Template.cs index b8536eda7..9056b8cdd 100644 --- a/Sharpmake.Generators/FastBuild/Bff.Template.cs +++ b/Sharpmake.Generators/FastBuild/Bff.Template.cs @@ -290,6 +290,7 @@ public static class ConfigurationFile .CompilerInputPattern = [fastBuildCompilerInputPattern] .CompilerInputExcludedFiles = [fastBuildInputExcludedFiles] .CompilerInputFiles = [fastBuildSourceFiles] + .CompilerInputFilesRoot = '[fastBuildInputFilesRootPath]' "; diff --git a/Sharpmake.Generators/FastBuild/Bff.cs b/Sharpmake.Generators/FastBuild/Bff.cs index b92b6863a..ae8815c75 100644 --- a/Sharpmake.Generators/FastBuild/Bff.cs +++ b/Sharpmake.Generators/FastBuild/Bff.cs @@ -1130,6 +1130,13 @@ List skipFiles fastBuildProjectDependencies.Add("[fastBuildOutputFileShortName]_objects"); string fastBuildObjectListEmbeddedResources = FormatListPartForTag(embeddedResourceFilesSections, 32, true); + string fastBuildInputFilesRootPath = FileGeneratorUtilities.RemoveLineTag; + + if (conf.FastBuildInputFilesRootPath != null) + { + fastBuildInputFilesRootPath = CurrentBffPathKeyCombine(Util.PathGetRelative(context.ProjectDirectory, conf.FastBuildInputFilesRootPath)); + } + using (bffGenerator.Declare("conf", conf)) using (bffGenerator.Declare("project", project)) using (bffGenerator.Declare("target", conf.Target)) @@ -1170,6 +1177,7 @@ List skipFiles using (bffGenerator.Declare("fastBuildLibrarianAdditionalInputs", librarianAdditionalInputs)) using (bffGenerator.Declare("fastBuildCompileAsC", fastBuildCompileAsC)) using (bffGenerator.Declare("fastBuildUnityName", fastBuildUnityName ?? FileGeneratorUtilities.RemoveLineTag)) + using (bffGenerator.Declare("fastBuildInputFilesRootPath", fastBuildInputFilesRootPath)) using (bffGenerator.Declare("fastBuildClangFileLanguage", clangFileLanguage)) using (bffGenerator.Declare("fastBuildDeoptimizationWritableFiles", fastBuildDeoptimizationWritableFiles)) using (bffGenerator.Declare("fastBuildDeoptimizationWritableFilesWithToken", fastBuildDeoptimizationWritableFilesWithToken)) diff --git a/Sharpmake.Platforms/Sharpmake.CommonPlatforms/Apple/BaseApplePlatform.cs b/Sharpmake.Platforms/Sharpmake.CommonPlatforms/Apple/BaseApplePlatform.cs index 1edd2423f..0f3c32d12 100644 --- a/Sharpmake.Platforms/Sharpmake.CommonPlatforms/Apple/BaseApplePlatform.cs +++ b/Sharpmake.Platforms/Sharpmake.CommonPlatforms/Apple/BaseApplePlatform.cs @@ -191,7 +191,25 @@ public void SetupExtraLinkerSettings(IFileGenerator fileGenerator, Project.Confi fileGenerator.Write(_linkerOptionsTemplate); } + public IEnumerable GetExtraStampEvents(Project.Configuration configuration, string fastBuildOutputFile) + { + if (FastBuildSettings.FastBuildSupportLinkerStampList) + { + foreach (var step in GetStripDebugSymbolsSteps(configuration, fastBuildOutputFile, asStampSteps: true)) + yield return step; + } + } + public IEnumerable GetExtraPostBuildEvents(Project.Configuration configuration, string fastBuildOutputFile) + { + if (!FastBuildSettings.FastBuildSupportLinkerStampList) + { + foreach (var step in GetStripDebugSymbolsSteps(configuration, fastBuildOutputFile, asStampSteps: false)) + yield return step; + } + } + + private IEnumerable GetStripDebugSymbolsSteps(Project.Configuration configuration, string fastBuildOutputFile, bool asStampSteps) { if (Util.GetExecutingPlatform() == Platform.mac) { @@ -207,22 +225,38 @@ public void SetupExtraLinkerSettings(IFileGenerator fileGenerator, Project.Confi if (debugFormat == Options.XCode.Compiler.DebugInformationFormat.DwarfWithDSym) { string outputPath = Path.Combine(configuration.TargetPath, configuration.TargetFileFullNameWithExtension + ".dSYM"); + string dsymutilSentinelFile = Path.Combine(configuration.IntermediatePath, configuration.TargetFileName + ".dsymdone"); yield return new Project.Configuration.BuildStepExecutable( "/usr/bin/dsymutil", - fastBuildOutputFile, - Path.Combine(configuration.IntermediatePath, configuration.TargetFileName + ".dsymdone"), + asStampSteps ? string.Empty : fastBuildOutputFile, + asStampSteps ? string.Empty : dsymutilSentinelFile, $"{fastBuildOutputFile} -o {outputPath}", useStdOutAsOutput: true); + + var stripDebugSymbols = Options.GetObject(configuration); + if (stripDebugSymbols == Options.XCode.Linker.StripLinkedProduct.Enable) + { + string strippedSentinelFile = Path.Combine(configuration.IntermediatePath, configuration.TargetFileName + ".stripped"); + yield return new Project.Configuration.BuildStepExecutable( + "/usr/bin/strip", + asStampSteps ? string.Empty : dsymutilSentinelFile, + asStampSteps ? string.Empty : strippedSentinelFile, + // From MacOS strip manual page: + // -r : Save all symbols referenced dynamically. + // -S : Remove the debuging symbol table entries (those created by the -g optin to cc and other compilers). + // -T : The intent of this flag is to remove Swift symbols from the Mach-O symbol table, + // It removes the symbols whose names begin with '_$S' or '_$s' only when it finds an __objc_imageinfo section with and it has non-zero swift version. + // In the future the implementation of this flag may change to match the intent. + // -x : Remove all local symbols (saving only global symbols) + $"-rSTx {fastBuildOutputFile}", + useStdOutAsOutput: true + ); + } } } } } - public IEnumerable GetExtraStampEvents(Project.Configuration configuration, string fastBuildOutputFile) - { - return Enumerable.Empty(); - } - public string GetOutputFilename(Project.Configuration.OutputType outputType, string fastBuildOutputFile) => fastBuildOutputFile; public enum CompilerFlavor diff --git a/Sharpmake/ExtensionMethods.cs b/Sharpmake/ExtensionMethods.cs index d1de6f2eb..1b631c6d9 100644 --- a/Sharpmake/ExtensionMethods.cs +++ b/Sharpmake/ExtensionMethods.cs @@ -104,6 +104,8 @@ public static string ToVersionString(this DotNetFramework framework) return "net7.0"; case DotNetFramework.net8_0: return "net8.0"; + case DotNetFramework.net9_0: + return "net9.0"; case DotNetFramework.all_netframework: case DotNetFramework.all_netcore: case DotNetFramework.all_netstandard: @@ -157,6 +159,8 @@ public static string ToFolderName(this DotNetFramework framework) return "net7.0"; case DotNetFramework.net8_0: return "net8.0"; + case DotNetFramework.net9_0: + return "net9.0"; case DotNetFramework.netstandard1_0: return "netstandard1.0"; case DotNetFramework.netstandard1_1: diff --git a/Sharpmake/Project.Configuration.cs b/Sharpmake/Project.Configuration.cs index b0a6cb580..382653671 100644 --- a/Sharpmake/Project.Configuration.cs +++ b/Sharpmake/Project.Configuration.cs @@ -1544,6 +1544,8 @@ public string FastBuildUnityPath set { _fastBuildUnityPath = value; } } + public string FastBuildInputFilesRootPath = null; + /// /// If specified, overrides Project.DefaultBlobWorkFileHeader. /// diff --git a/Sharpmake/Target.cs b/Sharpmake/Target.cs index cf8eb3a4d..e3fda0e2c 100644 --- a/Sharpmake/Target.cs +++ b/Sharpmake/Target.cs @@ -243,10 +243,12 @@ public enum DotNetFramework netstandard2_0 = 1 << 28, netstandard2_1 = 1 << 29, + net9_0 = 1 << 30, + [CompositeFragment] all_netframework = v3_5 | v3_5clientprofile | v4_5_2 | v4_6 | v4_6_1 | v4_6_2 | v4_7 | v4_7_1 | v4_7_2 | v4_8, [CompositeFragment] - all_netcore = netcore1_0 | netcore1_1 | netcore2_0 | netcore2_1 | netcore3_0 | netcore3_1 | net5_0 | net6_0 | net7_0 | net8_0, + all_netcore = netcore1_0 | netcore1_1 | netcore2_0 | netcore2_1 | netcore3_0 | netcore3_1 | net5_0 | net6_0 | net7_0 | net8_0 | net9_0, [CompositeFragment] all_netstandard = netstandard1_0 | netstandard1_1 | netstandard1_2 | netstandard1_3 | netstandard1_4 | netstandard1_5 | netstandard1_6 | netstandard2_0 | netstandard2_1, diff --git a/samples/FastBuildDuplicateFile/FastBuildDuplicateFile.sharpmake.cs b/samples/FastBuildDuplicateFile/FastBuildDuplicateFile.sharpmake.cs new file mode 100644 index 000000000..2f5d2afdf --- /dev/null +++ b/samples/FastBuildDuplicateFile/FastBuildDuplicateFile.sharpmake.cs @@ -0,0 +1,124 @@ +// Copyright (c) Ubisoft. All Rights Reserved. +// Licensed under the Apache 2.0 License. See LICENSE.md in the project root for license information. + +using System.IO; +using Sharpmake; + +namespace FastBuildDuplicateFile +{ + public static class Globals + { + // branch root path relative to current sharpmake file location + public const string RelativeRootPath = @".\codebase"; + public static string RootDirectory; + } + + [Sharpmake.Generate] + public class DuplicateFileProject : Project + { + public DuplicateFileProject() + { + Name = "DuplicateFileProject"; + + StripFastBuildSourceFiles = false; + + AddTargets(new Target( + Platform.win64, + DevEnv.vs2019 | DevEnv.vs2022, + Optimization.Debug | Optimization.Release, + OutputType.Lib, + Blob.NoBlob, + BuildSystem.FastBuild | BuildSystem.MSBuild + )); + + SourceRootPath = @"[project.SharpmakeCsPath]\codebase"; + } + + [Configure()] + public void ConfigureAll(Configuration conf, Target target) + { + conf.ProjectFileName = "[project.Name]_[target.DevEnv]_[target.Platform]_[target.BuildSystem]"; + conf.ProjectPath = @"[project.SharpmakeCsPath]\projects"; + conf.Options.Add(Options.Vc.Compiler.Exceptions.Enable); + } + + [Configure(BuildSystem.FastBuild)] + public void ConfigureFastBuild(Configuration conf, Target target) + { + conf.IsFastBuild = true; + conf.FastBuildBlobbed = target.Blob == Blob.FastBuildUnitys; + conf.FastBuildInputFilesRootPath = SourceRootPath; + + // Force writing to pdb from different cl.exe process to go through the pdb server + conf.AdditionalCompilerOptions.Add("/FS"); + } + + [Configure(Optimization.Release)] + public virtual void ConfigureRelease(Configuration conf, Target target) + { + // Testing generation of what is needed for working fastbuild deoptimization when using non-exposed compiler optimization options. + conf.AdditionalCompilerOptimizeOptions.Add("/O2"); // This switch is known but for the purpose of this test we will put in in this field. + conf.AdditionalCompilerOptimizeOptions.Add("/Os"); // This switch is known but for the purpose of this test we will put in in this field. + conf.AdditionalCompilerOptions.Add("/bigobj"); + conf.FastBuildDeoptimization = Configuration.DeoptimizationWritableFiles.DeoptimizeWritableFiles; + } + } + + [Sharpmake.Generate] + public class DuplicateFileSolution : Sharpmake.Solution + { + public DuplicateFileSolution() + { + Name = "FastBuildSample"; + + AddTargets(new Target( + Platform.win64, + DevEnv.vs2019 | DevEnv.vs2022, + Optimization.Debug | Optimization.Release, + OutputType.Lib, + Blob.NoBlob, + BuildSystem.FastBuild | BuildSystem.MSBuild + )); + } + + [Configure()] + public void ConfigureAll(Configuration conf, Target target) + { + conf.SolutionFileName = "[solution.Name]_[target.DevEnv]_[target.Platform]_[target.BuildSystem]"; + conf.SolutionPath = @"[solution.SharpmakeCsPath]\projects"; + + conf.AddProject(target); + } + } + + public static class Main + { + private static void ConfigureRootDirectory() + { + FileInfo fileInfo = Util.GetCurrentSharpmakeFileInfo(); + string rootDirectory = Path.Combine(fileInfo.DirectoryName, Globals.RelativeRootPath); + Globals.RootDirectory = Util.SimplifyPath(rootDirectory); + } + + [Sharpmake.Main] + public static void SharpmakeMain(Sharpmake.Arguments arguments) + { + ConfigureRootDirectory(); + + // for the purpose of this sample, we'll reuse the FastBuild executable that live in the sharpmake source repo + string sharpmakeFastBuildDir = Util.PathGetAbsolute(Globals.RootDirectory, @"..\..\..\tools\FastBuild"); + FastBuildSettings.FastBuildMakeCommand = Path.Combine(sharpmakeFastBuildDir, "Windows-x64", "FBuild.exe"); + + // This is necessary since there is no rc.exe in the same directory than link.exe + FastBuildSettings.SetPathToResourceCompilerInEnvironment = true; + + // Add an additional environment variable for fastbuild for testing + FastBuildSettings.AdditionalGlobalEnvironmentVariables.Add("KEY", "VALUE"); + + KitsRootPaths.SetUseKitsRootForDevEnv(DevEnv.vs2019, KitsRootEnum.KitsRoot10, Options.Vc.General.WindowsTargetPlatformVersion.v10_0_19041_0); + KitsRootPaths.SetUseKitsRootForDevEnv(DevEnv.vs2022, KitsRootEnum.KitsRoot10, Options.Vc.General.WindowsTargetPlatformVersion.v10_0_19041_0); + + arguments.Generate(); + } + } +} diff --git a/samples/FastBuildDuplicateFile/codebase/main.cpp b/samples/FastBuildDuplicateFile/codebase/main.cpp new file mode 100644 index 000000000..a577c11dd --- /dev/null +++ b/samples/FastBuildDuplicateFile/codebase/main.cpp @@ -0,0 +1,10 @@ +#include + +#include "test1/test.h" +#include "test2/test.h" + +int main(int, char**) +{ + std::cout << "I have two files named test.h. test1 makes " << test1() << ". test2 makes " << test2() << "." << std::endl; + return 0; +} diff --git a/samples/FastBuildDuplicateFile/codebase/test1/test.cpp b/samples/FastBuildDuplicateFile/codebase/test1/test.cpp new file mode 100644 index 000000000..087d52e37 --- /dev/null +++ b/samples/FastBuildDuplicateFile/codebase/test1/test.cpp @@ -0,0 +1,3 @@ +#include "test.h" + +int test1() { return 1; } diff --git a/samples/FastBuildDuplicateFile/codebase/test1/test.h b/samples/FastBuildDuplicateFile/codebase/test1/test.h new file mode 100644 index 000000000..39a74fa7f --- /dev/null +++ b/samples/FastBuildDuplicateFile/codebase/test1/test.h @@ -0,0 +1,3 @@ +#pragma once + +int test1(); diff --git a/samples/FastBuildDuplicateFile/codebase/test2/test.cpp b/samples/FastBuildDuplicateFile/codebase/test2/test.cpp new file mode 100644 index 000000000..e426e6690 --- /dev/null +++ b/samples/FastBuildDuplicateFile/codebase/test2/test.cpp @@ -0,0 +1,3 @@ +#include "test.h" + +int test2() { return 2; } diff --git a/samples/FastBuildDuplicateFile/codebase/test2/test.h b/samples/FastBuildDuplicateFile/codebase/test2/test.h new file mode 100644 index 000000000..512b315e3 --- /dev/null +++ b/samples/FastBuildDuplicateFile/codebase/test2/test.h @@ -0,0 +1,3 @@ +#pragma once + +int test2(); diff --git a/samples/Properties/launchSettings.json b/samples/Properties/launchSettings.json index 23f49d383..3decf803c 100644 --- a/samples/Properties/launchSettings.json +++ b/samples/Properties/launchSettings.json @@ -54,6 +54,12 @@ "commandLineArgs": "/sources(@'FastBuildSimpleExecutable.sharpmake.cs')", "workingDirectory": "$(ProjectDir)\\FastBuildSimpleExecutable" }, + "Sample (FastBuildDuplicateFile)": { + "commandName": "Executable", + "executablePath": "$(ProjectDir)\\..\\Sharpmake.Application\\bin\\$(Configuration)\\$(TargetFramework)\\Sharpmake.Application.exe", + "commandLineArgs": "/sources(@'FastBuildDuplicateFile.sharpmake.cs')", + "workingDirectory": "$(ProjectDir)\\FastBuildDuplicateFile" + }, "Sample (HelloAndroid)": { "commandName": "Executable", "executablePath": "$(ProjectDir)\\..\\Sharpmake.Application\\bin\\$(Configuration)\\$(TargetFramework)\\Sharpmake.Application.exe",