예제 #1
0
파일: UEBuildTarget.cs 프로젝트: mymei/UE4
        /// <summary>
        /// Adds a binary for the given module. Does not check whether a binary already exists, or whether a binary should be created for this build configuration.
        /// </summary>
        /// <param name="ModuleName">Name of the binary</param>
        /// <param name="BinaryType">Type of binary to be created</param>
        /// <param name="bAllowCompilation">Whether this binary can be compiled. The function will check whether plugin binaries can be compiled.</param>
        /// <param name="bIsCrossTarget">True if module is for supporting a different target-platform</param>
        /// <returns>The new binary</returns>
        private UEBuildBinaryCPP AddBinaryForModule(string ModuleName, UEBuildBinaryType BinaryType, bool bAllowCompilation, bool bIsCrossTarget)
        {
            // Get the plugin info for this module
            PluginInfo Plugin = FindPluginForModule(ModuleName);

            // Get the root output directory and base name (target name/app name) for this binary
            string BaseOutputDirectory;
            if(Plugin != null)
            {
                BaseOutputDirectory = Path.GetFullPath(Plugin.Directory);
            }
            else if(RulesCompiler.IsGameModule(ModuleName) || !bUseSharedBuildEnvironment)
            {
                BaseOutputDirectory = Path.GetFullPath(ProjectDirectory);
            }
            else
            {
                BaseOutputDirectory = Path.GetFullPath(BuildConfiguration.RelativeEnginePath);
            }

            // Get the configuration that this module will be built in. Engine modules compiled in DebugGame will use Development.
            UnrealTargetConfiguration ModuleConfiguration = Configuration;
            if(Configuration == UnrealTargetConfiguration.DebugGame && !RulesCompiler.IsGameModule(ModuleName))
            {
                ModuleConfiguration = UnrealTargetConfiguration.Development;
            }

            // Get the output and intermediate directories for this module
            string OutputDirectory = Path.Combine(BaseOutputDirectory, "Binaries", Platform.ToString());
             			string IntermediateDirectory = Path.Combine(BaseOutputDirectory, BuildConfiguration.PlatformIntermediateFolder, AppName, ModuleConfiguration.ToString());

            // Append a subdirectory if the module rules specifies one
            ModuleRules ModuleRules;
            if(RulesCompiler.TryCreateModuleRules(ModuleName, TargetInfo, out ModuleRules) && !String.IsNullOrEmpty(ModuleRules.BinariesSubFolder))
            {
                OutputDirectory = Path.Combine(OutputDirectory, ModuleRules.BinariesSubFolder);
                IntermediateDirectory = Path.Combine(IntermediateDirectory, ModuleRules.BinariesSubFolder);
            }

            // Get the output filenames
            string BaseBinaryPath = Path.Combine(OutputDirectory, MakeBinaryFileName(AppName + "-" + ModuleName, Platform, ModuleConfiguration, Rules.UndecoratedConfiguration, BinaryType));
            string[] OutputFilePaths = UEBuildPlatform.GetBuildPlatform(Platform).FinalizeBinaryPaths(BaseBinaryPath);

            // Prepare the configuration object
            UEBuildBinaryConfiguration Config = new UEBuildBinaryConfiguration(BinaryType);
            Config.OutputFilePaths = OutputFilePaths;
            Config.IntermediateDirectory = IntermediateDirectory;
            Config.bHasModuleRules = (ModuleRules != null);
            Config.bAllowExports = (BinaryType == UEBuildBinaryType.DynamicLinkLibrary);
            Config.bAllowCompilation = bAllowCompilation;
            Config.bIsCrossTarget = bIsCrossTarget;
            Config.ModuleNames.Add(ModuleName);

            // Create the new binary
            UEBuildBinaryCPP Binary = new UEBuildBinaryCPP(this, Config);
            AppBinaries.Add(Binary);
            return Binary;
        }
예제 #2
0
        public override void RecursivelyProcessUnboundModules(UEBuildTarget Target, ref Dictionary<string, UEBuildBinary> Binaries, UEBuildBinary ExecutableBinary)
        {
            // Make sure this module is bound to a binary
            if( !bIncludedInTarget )
            {
                throw new BuildException( "Module '{0}' should already have been bound to a binary!", Name );
            }

            var AllModuleNames = new List<string>();
            AllModuleNames.AddRange( PrivateDependencyModuleNames );
            AllModuleNames.AddRange( PublicDependencyModuleNames );
            AllModuleNames.AddRange( DynamicallyLoadedModuleNames );
            AllModuleNames.AddRange( PlatformSpecificDynamicallyLoadedModuleNames );

            foreach( var DependencyName in AllModuleNames )
            {
                var DependencyModule = Target.FindOrCreateModuleByName(DependencyName);

                // Skip modules that are included with the target (externals)
                if( !DependencyModule.bIncludedInTarget )
                {
                    if( !Binaries.ContainsKey( DependencyModule.Name ) )
                    {
                        UEBuildBinary BinaryToBindTo;
                        if (Target.ShouldCompileMonolithic())
                        {
                            // When linking monolithically, any unbound modules will be linked into the main executable
                            BinaryToBindTo = ExecutableBinary;
                        }
                        else
                        {
                            // Is this a Rocket module?
                            bool bIsRocketModule = RulesCompiler.IsRocketProjectModule(DependencyName);

                            // Is this a plugin module?
                            var PluginInfo = Plugins.GetPluginInfoForModule( DependencyName );

                            string OutputFilePath = Target.MakeBinaryPath(DependencyModule.Name, Target.GetAppName() + "-" + DependencyModule.Name, UEBuildBinaryType.DynamicLinkLibrary, Target.Rules.Type, bIsRocketModule, PluginInfo, "");

                            // If it's an engine module, output intermediates to the engine intermediates directory.
                            string IntermediateDirectory = Binary.Config.IntermediateDirectory;
                            if (PluginInfo == null && IntermediateDirectory != Target.EngineIntermediateDirectory && Path.GetFullPath(DependencyModule.ModuleDirectory).StartsWith(Path.GetFullPath(BuildConfiguration.RelativeEnginePath)))
                            {
                                IntermediateDirectory = Target.EngineIntermediateDirectory;
                            }

                            // When using modular linkage, unbound modules will be linked into their own DLL files
                            UEBuildBinaryConfiguration Config = new UEBuildBinaryConfiguration( InType: UEBuildBinaryType.DynamicLinkLibrary,
                                                                                                InOutputFilePath: OutputFilePath,
                                                                                                InIntermediateDirectory: IntermediateDirectory,
                                                                                                bInAllowExports: true,
                                                                                                InModuleNames: new List<string> { DependencyModule.Name },
                                                                                                InTargetName: Target.GetAppName(),
                                                                                                bInIsCrossTarget: PlatformSpecificDynamicallyLoadedModuleNames.Contains(DependencyName) && !DynamicallyLoadedModuleNames.Contains(DependencyName),
                                                                                                InTargetConfiguration: Target.Configuration,
                                                                                                bInCompileMonolithic: Target.ShouldCompileMonolithic() );

                            // Fix up the binary path if this is module specifies an alternate output directory
                            Config.OutputFilePath = DependencyModule.FixupOutputPath(Config.OutputFilePath);

                            BinaryToBindTo = new UEBuildBinaryCPP( Target, Config );
                        }

                        Binaries[ DependencyModule.Name ] = BinaryToBindTo;

                        // Bind this module
                        DependencyModule.Binary = BinaryToBindTo;
                        DependencyModule.bIncludedInTarget = true;

                        // Also add binaries for this module's dependencies
                        DependencyModule.RecursivelyProcessUnboundModules( Target, ref Binaries, ExecutableBinary );
                    }
                }

                if (Target.ShouldCompileMonolithic() == false)
                {
                    // Check to see if there is a circular relationship between the module and it's referencer
                    if( DependencyModule.Binary != null )
                    {
                        if( CircularlyReferencedDependentModules.Contains( DependencyName ) )
                        {
                            DependencyModule.Binary.SetCreateImportLibrarySeparately( true );
                        }
                    }
                }
            }

            // Also make sure module entries are created for any module that is pulled in as an "include path" module.
            // These modules are never linked in unless they were referenced as an actual dependency of a different module,
            // but we still need to keep track of them so that we can find their include paths when setting up our
            // module's include paths.
            RecursivelyAddIncludePathModules( Target, bPublicIncludesOnly:false );
        }