private void MakeStaticLibrary(Project project, ProjectFileCollection projectFiles, CProjectConfiguration configuration, ProjectPackageCollection packages, CompilerResults cr, ProgressMonitor monitor, string outputName) { if (!NeedsUpdate(projectFiles, configuration, outputName)) { return; } string objectFiles = string.Join(" ", ObjectFiles(projectFiles, configuration, true)); string args = string.Format("rcs \"{0}\" {1}", outputName, objectFiles); monitor.BeginTask(GettextCatalog.GetString("Generating static library {0} from object files", Path.GetFileName(outputName)), 1); string errorOutput; int exitCode = ExecuteCommand("ar", args, Path.GetDirectoryName(outputName), monitor, out errorOutput); if (exitCode == 0) { monitor.Step(1); } monitor.EndTask(); ParseCompilerOutput(errorOutput, cr); ParseLinkerOutput(errorOutput, cr); CheckReturnCode(exitCode, cr); }
private void PrecompileHeaders(ProjectFileCollection projectFiles, CProjectConfiguration configuration, string args) { foreach (ProjectFile file in projectFiles) { if (file.Subtype == Subtype.Code && CProject.IsHeaderFile(file.Name)) { string precomp = Path.Combine(configuration.SourceDirectory, ".prec"); precomp = Path.Combine(precomp, configuration.Name); precomp = Path.Combine(precomp, Path.GetFileName(file.Name) + ".ghc"); if (!File.Exists(precomp)) { DoPrecompileHeader(file, precomp, args); continue; } if (configuration.UseCcache || File.GetLastWriteTime(file.Name) > File.GetLastWriteTime(precomp)) { DoPrecompileHeader(file, precomp, args); } } } }
/// <summary> /// Checks whether a library can be linked with -lbasename /// </summary> /// <remarks> /// This should return true iff directory is empty or in /// the configured library paths, and library is of the form blah /// or libblah.(a|so|dll|dylib), /// </remarks> internal bool IsStandardLibrary(CProjectConfiguration configuration, string directory, string library, ref string std_lib) { std_lib = library; if (!(String.IsNullOrEmpty(directory) || configuration.LibPaths.Contains(directory))) { return(false); } string libraryExtension = Path.GetExtension(library); foreach (string extension in libraryExtensions) { if (libraryExtension.Equals(extension, StringComparison.OrdinalIgnoreCase)) { if (library.StartsWith("lib", StringComparison.OrdinalIgnoreCase)) { std_lib = std_lib.Substring(3); return(true); } else { return(false); } } } return(true); }
/// <summary> /// Gets the files that get compiled into object code. /// </summary> /// <param name="projectFiles"> /// A <see cref="ProjectFileCollection"/> /// The project's files, extracts from here the files that get compiled into object code. /// </param> /// <param name="configuration"> /// A <see cref="CProjectConfiguration"/> /// The configuration to get the object files for... /// </param> /// <param name="withQuotes"> /// A <see cref="System.Boolean"/> /// If true, it will surround each object file with quotes /// so that gcc has no problem with paths that contain spaces. /// </param> /// <returns> /// An array of strings, each string is the name of a file /// that will get compiled into object code. The file name /// will already have the .o extension. /// </returns> private string[] ObjectFiles(ProjectFileCollection projectFiles, CProjectConfiguration configuration, bool withQuotes) { if (projectFiles.Count == 0) { return new string[] {} } ; List <string> objectFiles = new List <string> (); foreach (ProjectFile f in projectFiles) { if (f.BuildAction == BuildAction.Compile) { string PathName = Path.Combine(configuration.OutputDirectory, Path.GetFileNameWithoutExtension(f.Name) + ".o"); if (File.Exists(PathName) == false) { continue; } if (!withQuotes) { objectFiles.Add(PathName); } else { objectFiles.Add("\"" + PathName + "\""); } } } return(objectFiles.ToArray()); }
/// <summary> /// This is the pkg-config package that gets deployed. /// <returns>The pkg-config package's filename</returns> /// </summary> private string WriteDeployablePgkPackage(Project project, CProjectConfiguration config) { // FIXME: This should probably be grabed from somewhere. string prefix = "/usr/local"; string pkgfile = Path.Combine(BaseDirectory, Name + ".pc"); using (StreamWriter writer = new StreamWriter(pkgfile)) { writer.WriteLine("prefix={0}", prefix); writer.WriteLine("exec_prefix=${prefix}"); writer.WriteLine("libdir=${exec_prefix}/lib"); writer.WriteLine("includedir=${prefix}/include"); writer.WriteLine(); writer.WriteLine("Name: {0}", Name); writer.WriteLine("Description: {0}", Description); writer.WriteLine("Version: {0}", Version); writer.WriteLine("Requires: {0}", string.Join(" ", Packages.ToStringArray())); // TODO: How should I get this? writer.WriteLine("Conflicts: {0}", string.Empty); writer.Write("Libs: -L${libdir} "); writer.WriteLine("-l{0}", config.Output.StartsWith("lib", StringComparison.OrdinalIgnoreCase)? config.Output.Substring(3): config.Output); writer.Write("Cflags: -I${includedir}/"); writer.WriteLine("{0} {1}", Name, Compiler.GetDefineFlags(project, config)); } return(pkgfile); }
protected override bool OnGetCanExecute(ExecutionContext context, ConfigurationSelector solutionConfiguration) { CProjectConfiguration conf = (CProjectConfiguration)GetConfiguration(solutionConfiguration); ExecutionCommand cmd = CreateExecutionCommand(conf); return((target == CBinding.CompileTarget.Bin) && context.ExecutionHandler.CanExecute(cmd)); }
public override SolutionItemConfiguration CreateConfiguration(string name) { CProjectConfiguration conf = new CProjectConfiguration(); conf.Name = name; return(conf); }
protected override SolutionItemConfiguration OnCreateConfiguration(string name, ConfigurationKind kind) { CProjectConfiguration conf = new CProjectConfiguration(); conf.Name = name; return(conf); }
public override string GetCompilerFlags(CProjectConfiguration configuration) { StringBuilder args = new StringBuilder(); string precdir = Path.Combine(configuration.SourceDirectory, ".prec"); CCompilationParameters cp = (CCompilationParameters)configuration.CompilationParameters; if (configuration.DebugMode) { args.Append("-g "); } if (configuration.CompileTarget == CBinding.CompileTarget.SharedLibrary) { args.Append("-fPIC "); } switch (cp.WarningLevel) { case WarningLevel.None: args.Append("-w "); break; case WarningLevel.Normal: // nothing break; case WarningLevel.All: args.Append("-Wall "); break; } args.Append("-O" + cp.OptimizationLevel + " "); if (cp.ExtraCompilerArguments != null && cp.ExtraCompilerArguments.Length > 0) { string extraCompilerArgs = cp.ExtraCompilerArguments.Replace('\n', ' '); args.Append(extraCompilerArgs + " "); } if (cp.DefineSymbols != null && cp.DefineSymbols.Length > 0) { args.Append(ProcessDefineSymbols(cp.DefineSymbols) + " "); } if (configuration.Includes != null) { foreach (string inc in configuration.Includes) { args.Append("-I" + inc + " "); } } args.Append("-I" + precdir); return(args.ToString()); }
protected override void Clean(IProgressMonitor monitor, SolutionEntityItem entry, ConfigurationSelector configuration) { base.Clean(monitor, entry, configuration); CProject project = (CProject)entry; CProjectConfiguration conf = (CProjectConfiguration)project.GetConfiguration(configuration); project.Compiler.Clean(project.Files, conf, monitor); }
public override IConfiguration CreateConfiguration(string name) { CProjectConfiguration conf = new CProjectConfiguration(); conf.Name = name; conf.CompilationParameters = new CCompilationParameters(); return(conf); }
public override ICompilerResult Compile ( ProjectFileCollection projectFiles, ProjectPackageCollection packages, CProjectConfiguration configuration, IProgressMonitor monitor) { CompilerResults cr = new CompilerResults (new TempFileCollection ()); bool res = true; string args = GetCompilerFlags (configuration); string outputName = Path.Combine (configuration.OutputDirectory, configuration.CompiledOutputName); // Precompile header files and place them in .prec/<config_name>/ string precdir = Path.Combine (configuration.SourceDirectory, ".prec"); if (!Directory.Exists (precdir)) Directory.CreateDirectory (precdir); precdir = Path.Combine (precdir, configuration.Name); if (!Directory.Exists (precdir)) Directory.CreateDirectory (precdir); PrecompileHeaders (projectFiles, configuration, args); foreach (ProjectFile f in projectFiles) { if (f.Subtype == Subtype.Directory) continue; if (f.BuildAction == BuildAction.Compile) { if (configuration.UseCcache || NeedsCompiling (f)) res = DoCompilation (f, args, packages, monitor, cr, configuration.UseCcache); } else res = true; if (!res) break; } if (res) { switch (configuration.CompileTarget) { case CBinding.CompileTarget.Bin: MakeBin ( projectFiles, packages, configuration, cr, monitor, outputName); break; case CBinding.CompileTarget.StaticLibrary: MakeStaticLibrary ( projectFiles, monitor, outputName); break; case CBinding.CompileTarget.SharedLibrary: MakeSharedLibrary ( projectFiles, packages, configuration, cr, monitor, outputName); break; } } return new DefaultCompilerResult (cr, ""); }
protected virtual ExecutionCommand CreateExecutionCommand(CProjectConfiguration conf) { string app = Path.Combine(conf.OutputDirectory, conf.Output); NativeExecutionCommand cmd = new NativeExecutionCommand(app); cmd.Arguments = conf.CommandLineParameters; cmd.WorkingDirectory = Path.GetFullPath(conf.OutputDirectory); cmd.EnvironmentVariables = conf.EnvironmentVariables; return(cmd); }
protected override BuildResult DoBuild(IProgressMonitor monitor, ConfigurationSelector configuration) { CProjectConfiguration pc = (CProjectConfiguration)GetConfiguration(configuration); pc.SourceDirectory = BaseDirectory; return(compiler_manager.Compile(this, Files, packages, pc, monitor)); }
protected override ICompilerResult DoBuild(IProgressMonitor monitor) { CProjectConfiguration pc = (CProjectConfiguration)ActiveConfiguration; pc.SourceDirectory = BaseDirectory; return(compiler_manager.Compile( ProjectFiles, packages, (CProjectConfiguration)ActiveConfiguration, monitor)); }
protected override BuildResult Build(IProgressMonitor monitor, SolutionEntityItem entry, ConfigurationSelector configuration) { CProject project = (CProject)entry; CProjectConfiguration conf = (CProjectConfiguration)project.GetConfiguration(configuration); if (conf.CompileTarget != CompileTarget.Bin) { project.WriteMDPkgPackage(configuration); } return(base.Build(monitor, entry, configuration)); }
public DeployFileCollection GetDeployFiles(ConfigurationSelector configuration) { DeployFileCollection deployFiles = new DeployFileCollection(); CProjectConfiguration conf = (CProjectConfiguration)GetConfiguration(configuration); CompileTarget target = conf.CompileTarget; // Headers and resources foreach (ProjectFile f in Files) { if (f.BuildAction == BuildAction.Content) { string targetDirectory = (IsHeaderFile(f.Name) ? TargetDirectory.Include : TargetDirectory.ProgramFiles); deployFiles.Add(new DeployFile(this, f.FilePath, f.ProjectVirtualPath, targetDirectory)); } } // Output string output = GetOutputFileName(configuration); if (!string.IsNullOrEmpty(output)) { string targetDirectory = string.Empty; switch (target) { case CompileTarget.Bin: targetDirectory = TargetDirectory.ProgramFiles; break; case CompileTarget.SharedLibrary: targetDirectory = TargetDirectory.ProgramFiles; break; case CompileTarget.StaticLibrary: targetDirectory = TargetDirectory.ProgramFiles; break; } deployFiles.Add(new DeployFile(this, output, Path.GetFileName(output), targetDirectory)); } // PkgPackage if (target != CompileTarget.Bin) { string pkgfile = WriteDeployablePgkPackage(this, conf); deployFiles.Add(new DeployFile(this, Path.Combine(BaseDirectory, pkgfile), pkgfile, LinuxTargetDirectory.PkgConfig)); } return(deployFiles); }
/// <summary> /// Ths pkg-config package is for internal MonoDevelop use only, it is not deployed. /// </summary> public void WriteMDPkgPackage(ConfigurationSelector configuration) { string pkgfile = Path.Combine(BaseDirectory, Name + ".md.pc"); CProjectConfiguration config = (CProjectConfiguration)GetConfiguration(configuration); while (config == null) { Thread.Sleep(20); config = (CProjectConfiguration)GetConfiguration(configuration); } List <string> headerDirectories = new List <string> (); foreach (ProjectFile f in Files) { if (IsHeaderFile(f.Name)) { string dir = Path.GetDirectoryName(f.FilePath); if (!headerDirectories.Contains(dir)) { headerDirectories.Add(dir); } } } using (StreamWriter writer = new StreamWriter(pkgfile)) { writer.WriteLine("Name: {0}", Name); writer.WriteLine("Description: {0}", Description); writer.WriteLine("Version: {0}", Version); writer.WriteLine("Libs: -L\"{0}\" -l{1}", config.OutputDirectory, config.Output.StartsWith("lib", StringComparison.OrdinalIgnoreCase)? config.Output.Substring(3): config.Output); // writer.WriteLine ("Cflags: -I{0}", BaseDirectory); writer.WriteLine("Cflags: -I\"{0}\"", string.Join("\" -I\"", headerDirectories.ToArray())); } // If this project compiles into a shared object we need to // export the output path to the LD_LIBRARY_PATH string literal = "LD_LIBRARY_PATH"; string ld_library_path = Environment.GetEnvironmentVariable(literal); if (string.IsNullOrEmpty(ld_library_path)) { Environment.SetEnvironmentVariable(literal, config.OutputDirectory); } else if (!ld_library_path.Contains(config.OutputDirectory)) { ld_library_path = string.Format("{0}:{1}", config.OutputDirectory, ld_library_path); Environment.SetEnvironmentVariable(literal, ld_library_path); } }
public void Load (CProjectConfiguration config) { configuration = config; switch (configuration.WarningLevel) { case WarningLevel.None: noWarningRadio.Active = true; break; case WarningLevel.Normal: normalWarningRadio.Active = true; break; case WarningLevel.All: allWarningRadio.Active = true; break; } warningsAsErrorsCheckBox.Active = configuration.WarningsAsErrors; optimizationSpinButton.Value = configuration.OptimizationLevel; switch (configuration.CompileTarget) { case CBinding.CompileTarget.Bin: targetComboBox.Active = 0; break; case CBinding.CompileTarget.StaticLibrary: targetComboBox.Active = 1; break; case CBinding.CompileTarget.SharedLibrary: targetComboBox.Active = 2; break; } extraCompilerTextView.Buffer.Text = configuration.ExtraCompilerArguments; extraLinkerTextView.Buffer.Text = configuration.ExtraLinkerArguments; defineSymbolsTextEntry.Text = configuration.DefineSymbols; libStore.Clear (); foreach (string lib in configuration.Libs) libStore.AppendValues (lib); libPathStore.Clear (); foreach (string libPath in configuration.LibPaths) libPathStore.AppendValues (libPath); includePathStore.Clear (); foreach (string includePath in configuration.Includes) includePathStore.AppendValues (includePath); }
protected override void DoExecute(IProgressMonitor monitor, ExecutionContext context) { CProjectConfiguration conf = (CProjectConfiguration)ActiveConfiguration; string command = conf.Output; string args = conf.CommandLineParameters; string dir = Path.GetFullPath(conf.OutputDirectory); string platform = "Native"; bool pause = conf.PauseConsoleOutput; IConsole console; if (conf.CompileTarget != CBinding.CompileTarget.Bin) { IdeApp.Services.MessageService.ShowMessage("Compile target is not an executable!"); return; } monitor.Log.WriteLine("Running project..."); if (conf.ExternalConsole) { console = context.ExternalConsoleFactory.CreateConsole(!pause); } else { console = context.ConsoleFactory.CreateConsole(!pause); } AggregatedOperationMonitor operationMonitor = new AggregatedOperationMonitor(monitor); try { IExecutionHandler handler = context.ExecutionHandlerFactory.CreateExecutionHandler(platform); if (handler == null) { monitor.ReportError("Cannot execute \"" + command + "\". The selected execution mode is not supported in the " + platform + " platform.", null); return; } IProcessAsyncOperation op = handler.Execute(Path.Combine(dir, command), args, dir, console); operationMonitor.AddOperation(op); op.WaitForCompleted(); monitor.Log.WriteLine("The operation exited with code: {0}", op.ExitCode); } catch (Exception ex) { monitor.ReportError("Cannot execute \"" + command + "\"", ex); } finally { operationMonitor.Dispose(); console.Dispose(); } }
protected override void DoExecute(IProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration) { CProjectConfiguration conf = (CProjectConfiguration)GetConfiguration(configuration); bool pause = conf.PauseConsoleOutput; IConsole console; if (conf.CompileTarget != CBinding.CompileTarget.Bin) { MessageService.ShowMessage("Compile target is not an executable!"); return; } monitor.Log.WriteLine("Running project..."); if (conf.ExternalConsole) { console = context.ExternalConsoleFactory.CreateConsole(!pause); } else { console = context.ConsoleFactory.CreateConsole(!pause); } AggregatedOperationMonitor operationMonitor = new AggregatedOperationMonitor(monitor); try { ExecutionCommand cmd = CreateExecutionCommand(conf); if (!context.ExecutionHandler.CanExecute(cmd)) { monitor.ReportError("Cannot execute \"" + conf.Output + "\". The selected execution mode is not supported for C projects.", null); return; } IProcessAsyncOperation op = context.ExecutionHandler.Execute(cmd, console); operationMonitor.AddOperation(op); op.WaitForCompleted(); monitor.Log.WriteLine("The operation exited with code: {0}", op.ExitCode); } catch (Exception ex) { monitor.ReportError("Cannot execute \"" + conf.Output + "\"", ex); } finally { operationMonitor.Dispose(); console.Dispose(); } }
public void Load (CProjectConfiguration configuration) { this.configuration = configuration; outputNameTextEntry.Text = configuration.Output; outputEntry.Path = configuration.OutputDirectory; parametersTextEntry.Text = configuration.CommandLineParameters; if (externalConsoleCheckbox.Active) pauseCheckbox.Sensitive = true; externalConsoleCheckbox.Active = configuration.ExternalConsole; pauseCheckbox.Active = configuration.PauseConsoleOutput; }
void CleanPrecompiledHeaders(CProjectConfiguration configuration) { if (string.IsNullOrEmpty(configuration.IntermediateOutputDirectory)) { return; } string precDir = Path.Combine(configuration.IntermediateOutputDirectory, "prec"); if (Directory.Exists(precDir)) { Directory.Delete(precDir, true); } }
public OutputOptionsPanel (Properties customizationObject) { this.Build (); table1.RowSpacing = 3; configuration = customizationObject.Get<CProjectConfiguration> ("Config"); outputNameTextEntry.Text = configuration.Output; outputPathTextEntry.Text = configuration.OutputDirectory; parametersTextEntry.Text = configuration.CommandLineParameters; externalConsoleCheckbox.Active = configuration.ExternalConsole; pauseCheckbox.Active = configuration.PauseConsoleOutput; }
public OutputOptionsPanel(Properties customizationObject) { this.Build(); table1.RowSpacing = 3; configuration = customizationObject.Get <CProjectConfiguration> ("Config"); outputNameTextEntry.Text = configuration.Output; outputPathTextEntry.Text = configuration.OutputDirectory; parametersTextEntry.Text = configuration.CommandLineParameters; externalConsoleCheckbox.Active = configuration.ExternalConsole; pauseCheckbox.Active = configuration.PauseConsoleOutput; }
protected async override Task <BuildResult> OnClean(ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext operationContext) { CProjectConfiguration conf = (CProjectConfiguration)GetConfiguration(configuration); var res = await base.OnClean(monitor, configuration, operationContext); if (res.HasErrors) { return(res); } await Task.Run(() => Compiler.Clean(Files, conf, monitor)); return(res); }
public void Load(CProjectConfiguration configuration) { this.configuration = configuration; outputNameTextEntry.Text = configuration.Output; outputEntry.Path = configuration.OutputDirectory; parametersTextEntry.Text = configuration.CommandLineParameters; if (externalConsoleCheckbox.Active) { pauseCheckbox.Sensitive = true; } externalConsoleCheckbox.Active = configuration.ExternalConsole; pauseCheckbox.Active = configuration.PauseConsoleOutput; }
private bool NeedsUpdate(ProjectFileCollection projectFiles, CProjectConfiguration configuration, string target) { if (!File.Exists(target)) { return(true); } foreach (string obj in ObjectFiles(projectFiles, configuration, false)) { if (File.GetLastWriteTime(obj) > File.GetLastWriteTime(target)) { return(true); } } return(false); }
protected override Task <BuildResult> DoBuild(ProgressMonitor monitor, ConfigurationSelector configuration) { CProjectConfiguration pc = (CProjectConfiguration)GetConfiguration(configuration); pc.SourceDirectory = BaseDirectory; return(Task <BuildResult> .Factory.StartNew(delegate { if (pc.CompileTarget != CompileTarget.Bin) { WriteMDPkgPackage(configuration); } return compiler_manager.Compile(this, Files, packages, pc, monitor); })); }
private bool PrecompileHeaders(ProjectFileCollection projectFiles, CProjectConfiguration configuration, string args, ProgressMonitor monitor, CompilerResults cr) { monitor.BeginTask(GettextCatalog.GetString("Precompiling headers"), 1); bool success = true; foreach (ProjectFile file in projectFiles) { if (file.Subtype == Subtype.Code && CProject.IsHeaderFile(file.Name)) { string precomp = Path.Combine(configuration.IntermediateOutputDirectory, "prec"); precomp = Path.Combine(precomp, configuration.Id); precomp = Path.Combine(precomp, Path.GetFileName(file.Name) + ".ghc"); if (file.BuildAction == BuildAction.Compile) { if (!File.Exists(precomp) || configuration.UseCcache || File.GetLastWriteTime(file.Name) > File.GetLastWriteTime(precomp)) { if (DoPrecompileHeader(file, precomp, args, monitor, cr) == false) { success = false; break; } } } else { //remove old files or they'll interfere with the build if (File.Exists(precomp)) { File.Delete(precomp); } } } } if (success) { monitor.Step(1); } monitor.EndTask(); return(success); }
/// <summary> /// Compiles a single source file into object code /// and creates a file with it's dependencies. /// </summary> private bool DoCompilation(ProjectFile file, CProjectConfiguration configuration, string args, ProgressMonitor monitor, CompilerResults cr, bool use_ccache) { string outputName = Path.Combine(configuration.OutputDirectory, Path.GetFileName(Path.ChangeExtension(file.Name, ".o"))); string compiler_args = string.Format("{0} -MMD \"{1}\" {2} -c -o \"{3}\"", (use_ccache ? compilerCommand : string.Empty), file.Name, args, outputName); string errorOutput; int exitCode = ExecuteCommand((use_ccache ? "ccache" : compilerCommand), compiler_args, configuration.OutputDirectory, monitor, out errorOutput); ParseCompilerOutput(errorOutput, cr); CheckReturnCode(exitCode, cr); return(exitCode == 0); }
protected async override Task DoExecute(ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration) { CProjectConfiguration conf = (CProjectConfiguration)GetConfiguration(configuration); bool pause = conf.PauseConsoleOutput; OperationConsole console; if (conf.CompileTarget != CBinding.CompileTarget.Bin) { MessageService.ShowMessage("Compile target is not an executable!"); return; } monitor.Log.WriteLine("Running project..."); if (conf.ExternalConsole) { console = context.ExternalConsoleFactory.CreateConsole(!pause, monitor.CancellationToken); } else { console = context.ConsoleFactory.CreateConsole(monitor.CancellationToken); } try { ExecutionCommand cmd = CreateExecutionCommand(conf); if (!context.ExecutionHandler.CanExecute(cmd)) { monitor.ReportError("Cannot execute \"" + conf.Output + "\". The selected execution mode is not supported for C projects.", null); return; } ProcessAsyncOperation op = context.ExecutionHandler.Execute(cmd, console); using (var t = monitor.CancellationToken.Register(op.Cancel)) await op.Task; monitor.Log.WriteLine("The operation exited with code: {0}", op.ExitCode); } catch (Exception ex) { LoggingService.LogError(string.Format("Cannot execute \"{0}\"", conf.Output), ex); monitor.ReportError("Cannot execute \"" + conf.Output + "\"", ex); } finally { console.Dispose(); } }
protected override void OnCopyFrom(ItemConfiguration configuration, bool isRename) { base.OnCopyFrom(configuration, isRename); CProjectConfiguration conf = (CProjectConfiguration)configuration; output = conf.output; target = conf.target; includes = conf.includes; libpaths = conf.libpaths; libs = conf.libs; source_directory_path = conf.source_directory_path; use_ccache = conf.use_ccache; warning_level = conf.warning_level; warnings_as_errors = conf.warnings_as_errors; optimization = conf.optimization; extra_compiler_args = conf.extra_compiler_args; extra_linker_args = conf.extra_linker_args; define_symbols = conf.define_symbols; }
private ProjectPackageCollection ProjectPackages(Project project) { ProjectPackageCollection packages = new ProjectPackageCollection(); foreach (CombineEntry c in project.ParentCombine.Entries) { if (c is CProject) { CProject cproj = (CProject)c; CProjectConfiguration conf = (CProjectConfiguration)cproj.ActiveConfiguration; if (conf.CompileTarget != CBinding.CompileTarget.Bin) { cproj.WriteMDPkgPackage(); packages.Add(new ProjectPackage(cproj)); } } } return(packages); }
public abstract string GetCompilerFlags (Project project, CProjectConfiguration configuration);
public override string GetCompilerFlags (Project project, CProjectConfiguration configuration) { StringBuilder args = new StringBuilder (); if (configuration.DebugMode) args.Append ("-g "); if (configuration.CompileTarget == CBinding.CompileTarget.SharedLibrary) args.Append ("-fPIC "); switch (configuration.WarningLevel) { case WarningLevel.None: args.Append ("-w "); break; case WarningLevel.Normal: // nothing break; case WarningLevel.All: args.Append ("-Wall "); break; } if (configuration.WarningsAsErrors) args.Append ("-Werror "); args.Append ("-O" + configuration.OptimizationLevel + " "); if (configuration.ExtraCompilerArguments != null && configuration.ExtraCompilerArguments.Length > 0) { string extraCompilerArgs = ExpandBacktickedParameters(configuration.ExtraCompilerArguments.Replace ('\n', ' ')); args.Append (extraCompilerArgs + " "); } if (configuration.DefineSymbols != null && configuration.DefineSymbols.Length > 0) args.Append (ProcessDefineSymbols (configuration.DefineSymbols) + " "); if (configuration.Includes != null) foreach (string inc in configuration.Includes) args.Append ("-I\"" + StringParserService.Parse (inc, GetStringTags (project)) + "\" "); if (configuration.PrecompileHeaders) { string precdir = Path.Combine (configuration.SourceDirectory, ".prec"); precdir = Path.Combine (precdir, configuration.Id); args.Append ("-I\"" + precdir + "\""); } return args.ToString (); }
private bool NeedsUpdate (ProjectFileCollection projectFiles, CProjectConfiguration configuration, string target) { if (!File.Exists (target)) return true; foreach (string obj in ObjectFiles (projectFiles, configuration, false)) if (File.GetLastWriteTime (obj) > File.GetLastWriteTime (target)) return true; return false; }
public override string GetDefineFlags (CProjectConfiguration configuration) { string defines = ((CCompilationParameters)configuration.CompilationParameters).DefineSymbols; return ProcessDefineSymbols (defines); }
/// <summary> /// This is the pkg-config package that gets deployed. /// <returns>The pkg-config package's filename</returns> /// </summary> private string WriteDeployablePgkPackage (Project project, CProjectConfiguration config) { // FIXME: This should probably be grabed from somewhere. string prefix = "/usr/local"; string pkgfile = Path.Combine (BaseDirectory, Name + ".pc"); using (StreamWriter writer = new StreamWriter (pkgfile)) { writer.WriteLine ("prefix={0}", prefix); writer.WriteLine ("exec_prefix=${prefix}"); writer.WriteLine ("libdir=${exec_prefix}/lib"); writer.WriteLine ("includedir=${prefix}/include"); writer.WriteLine (); writer.WriteLine ("Name: {0}", Name); writer.WriteLine ("Description: {0}", Description); writer.WriteLine ("Version: {0}", Version); writer.WriteLine ("Requires: {0}", string.Join (" ", Packages.ToStringArray ())); // TODO: How should I get this? writer.WriteLine ("Conflicts: {0}", string.Empty); writer.Write ("Libs: -L${libdir} "); writer.WriteLine ("-l{0}", config.Output.StartsWith ("lib", StringComparison.OrdinalIgnoreCase)? config.Output.Substring (3): config.Output); writer.Write ("Cflags: -I${includedir}/"); writer.WriteLine ("{0} {1}", Name, Compiler.GetDefineFlags (project, config)); } return pkgfile; }
public abstract void Clean (ProjectFileCollection projectFiles, CProjectConfiguration configuration, IProgressMonitor monitor);
public override SolutionItemConfiguration CreateConfiguration (string name) { CProjectConfiguration conf = new CProjectConfiguration (); conf.Name = name; return conf; }
private void MakeStaticLibrary (Project project, ProjectFileCollection projectFiles, CProjectConfiguration configuration, ProjectPackageCollection packages, CompilerResults cr, IProgressMonitor monitor, string outputName) { if (!NeedsUpdate (projectFiles, configuration, outputName)) return; string objectFiles = string.Join (" ", ObjectFiles (projectFiles, configuration, true)); string args = string.Format ("rcs \"{0}\" {1}", outputName, objectFiles); monitor.BeginTask (GettextCatalog.GetString ("Generating static library {0} from object files", Path.GetFileName (outputName)), 1); string errorOutput; int exitCode = ExecuteCommand ("ar", args, Path.GetDirectoryName (outputName), monitor, out errorOutput); if (exitCode == 0) monitor.Step (1); monitor.EndTask (); ParseCompilerOutput (errorOutput, cr); ParseLinkerOutput (errorOutput, cr); CheckReturnCode (exitCode, cr); }
public override IConfiguration CreateConfiguration (string name) { CProjectConfiguration conf = new CProjectConfiguration (); conf.Name = name; conf.CompilationParameters = new CCompilationParameters (); return conf; }
private bool PrecompileHeaders (ProjectFileCollection projectFiles, CProjectConfiguration configuration, string args, IProgressMonitor monitor, CompilerResults cr) { monitor.BeginTask (GettextCatalog.GetString ("Precompiling headers"), 1); bool success = true; foreach (ProjectFile file in projectFiles) { if (file.Subtype == Subtype.Code && CProject.IsHeaderFile (file.Name)) { string precomp = Path.Combine (configuration.SourceDirectory, ".prec"); precomp = Path.Combine (precomp, configuration.Id); precomp = Path.Combine (precomp, Path.GetFileName (file.Name) + ".ghc"); if (file.BuildAction == BuildAction.Compile) { if (!File.Exists (precomp) || configuration.UseCcache || File.GetLastWriteTime (file.Name) > File.GetLastWriteTime (precomp)) { if (DoPrecompileHeader (file, precomp, args, monitor, cr) == false) { success = false; break; } } } else { //remove old files or they'll interfere with the build if (File.Exists (precomp)) File.Delete (precomp); } } } if (success) monitor.Step (1); monitor.EndTask (); return success; }
/// <summary> /// Checks whether a library can be linked with -lbasename /// </summary> /// <remarks> /// This should return true iff directory is empty or in /// the configured library paths, and library is of the form blah /// or libblah.(a|so|dll|dylib), /// </remarks> internal bool IsStandardLibrary(CProjectConfiguration configuration, string directory, string library, ref string std_lib) { std_lib = library; if(!(String.IsNullOrEmpty(directory) || configuration.LibPaths.Contains(directory))) return false; string libraryExtension = Path.GetExtension (library); foreach (string extension in libraryExtensions) { if (libraryExtension.Equals (extension, StringComparison.OrdinalIgnoreCase)) { if (library.StartsWith("lib", StringComparison.OrdinalIgnoreCase)) { std_lib = std_lib.Substring(3); return true; } else { return false; } } } return true; }
/// <summary> /// Returns an array of depended on files or null if the /// file containing the depended on files (.d) does does not exist. /// </summary> private string[] DependedOnFiles (ProjectFile file, CProjectConfiguration configuration) { List<string> dependencies = new List<string> (); string dependenciesFile = Path.Combine(configuration.OutputDirectory, Path.GetFileName(file.Name)); dependenciesFile = Path.ChangeExtension(dependenciesFile, ".d"); if (!File.Exists (dependenciesFile)) return null; // It always depends on itself ;) dependencies.Add (file.Name); string temp; using (StreamReader reader = new StreamReader (dependenciesFile)) { while ((temp = reader.ReadLine ()) != null) { // TODO: We really should be using a regex here, // this will have issues with pathnames containing double spaces. string depfile = temp.Replace(" \\", String.Empty).Trim(); // Ignore empty strings & object files... if(String.IsNullOrEmpty(depfile) || depfile.EndsWith(".o:") || depfile.EndsWith(".o")) continue; dependencies.Add(depfile.Replace(@"\ ", " ")); } } return dependencies.ToArray(); }
private bool NeedsCompiling (ProjectFile file, CProjectConfiguration configuration) { string objectFile = Path.Combine(configuration.OutputDirectory, Path.GetFileName(file.Name)); objectFile = Path.ChangeExtension(objectFile, ".o"); if (!File.Exists (objectFile)) return true; string[] dependedOnFiles = DependedOnFiles (file, configuration); if (dependedOnFiles == null) { return true; } DateTime lastObjectTime = File.GetLastWriteTime (objectFile); try { foreach (string depfile in dependedOnFiles) { if (File.GetLastWriteTime (depfile) > lastObjectTime) { return true; } } } catch (IOException e) { // This means the dependency file is telling us our source file // depends on a file that no longer exists, all this means is that // the dependency file is outdated. We should just ignore this // since the dependency file will be automatically updated when // the source file is compiled. e.ToString (); // suppress warning. } return false; }
public override string GetDefineFlags (Project project, CProjectConfiguration configuration) { return ProcessDefineSymbols (configuration.DefineSymbols); }
public abstract string GetDefineFlags (Project project, CProjectConfiguration configuration);
public override BuildResult Compile ( Project project, ProjectFileCollection projectFiles, ProjectPackageCollection packages, CProjectConfiguration configuration, IProgressMonitor monitor) { if (!appsChecked) { appsChecked = true; compilerFound = CheckApp (compilerCommand); linkerFound = CheckApp (linkerCommand); } if (!compilerFound) { BuildResult cres = new BuildResult (); cres.AddError ("Compiler not found: " + compilerCommand); return cres; } if (!linkerFound) { BuildResult cres = new BuildResult (); cres.AddError ("Linker not found: " + linkerCommand); return cres; } CompilerResults cr = new CompilerResults (new TempFileCollection ()); bool success = true; string compilerArgs = GetCompilerFlags (project, configuration) + " " + GeneratePkgCompilerArgs (packages); string outputName = Path.Combine (configuration.OutputDirectory, configuration.CompiledOutputName); // Precompile header files and place them in .prec/<config_name>/ if (configuration.PrecompileHeaders) { string precDir = Path.Combine (configuration.SourceDirectory, ".prec"); string precConfigDir = Path.Combine (precDir, configuration.Id); if (!Directory.Exists (precDir)) Directory.CreateDirectory (precDir); if (!Directory.Exists (precConfigDir)) Directory.CreateDirectory (precConfigDir); if (!PrecompileHeaders (projectFiles, configuration, compilerArgs, monitor, cr)) success = false; } else { //old headers could interfere with the build CleanPrecompiledHeaders (configuration); } //compile source to object files monitor.BeginTask (GettextCatalog.GetString ("Compiling source to object files"), 1); foreach (ProjectFile f in projectFiles) { if (!success) break; if (f.Subtype == Subtype.Directory || f.BuildAction != BuildAction.Compile || CProject.IsHeaderFile (f.FilePath)) continue; if (configuration.UseCcache || NeedsCompiling (f, configuration)) success = DoCompilation (f, configuration, compilerArgs, monitor, cr, configuration.UseCcache); } if (success) monitor.Step (1); monitor.EndTask (); if (success) { switch (configuration.CompileTarget) { case CBinding.CompileTarget.Bin: MakeBin (project, projectFiles, configuration, packages, cr, monitor, outputName); break; case CBinding.CompileTarget.StaticLibrary: MakeStaticLibrary (project, projectFiles, configuration, packages, cr, monitor, outputName); break; case CBinding.CompileTarget.SharedLibrary: MakeSharedLibrary (project, projectFiles, configuration, packages, cr, monitor, outputName); break; } } return new BuildResult (cr, ""); }
public abstract BuildResult Compile ( Project project, ProjectFileCollection projectFiles, ProjectPackageCollection packages, CProjectConfiguration configuration, IProgressMonitor monitor);
/// <summary> /// Compiles a single source file into object code /// and creates a file with it's dependencies. /// </summary> private bool DoCompilation (ProjectFile file, CProjectConfiguration configuration, string args, IProgressMonitor monitor, CompilerResults cr, bool use_ccache) { string outputName = Path.Combine(configuration.OutputDirectory, Path.GetFileName(Path.ChangeExtension (file.Name, ".o"))); string compiler_args = string.Format ("{0} -MMD \"{1}\" {2} -c -o \"{3}\"", (use_ccache ? compilerCommand : string.Empty), file.Name, args, outputName); string errorOutput; int exitCode = ExecuteCommand ((use_ccache ? "ccache" : compilerCommand), compiler_args, configuration.OutputDirectory, monitor, out errorOutput); ParseCompilerOutput (errorOutput, cr); CheckReturnCode (exitCode, cr); return exitCode == 0; }
private void PrecompileHeaders (ProjectFileCollection projectFiles, CProjectConfiguration configuration, string args) { foreach (ProjectFile file in projectFiles) { if (file.Subtype == Subtype.Code && CProject.IsHeaderFile (file.Name)) { string precomp = Path.Combine (configuration.SourceDirectory, ".prec"); precomp = Path.Combine (precomp, configuration.Name); precomp = Path.Combine (precomp, Path.GetFileName (file.Name) + ".ghc"); if (!File.Exists (precomp)) { DoPrecompileHeader (file, precomp, args); continue; } if (configuration.UseCcache || File.GetLastWriteTime (file.Name) > File.GetLastWriteTime (precomp)) { DoPrecompileHeader (file, precomp, args); } } } }
/// <summary> /// Gets the files that get compiled into object code. /// </summary> /// <param name="projectFiles"> /// A <see cref="ProjectFileCollection"/> /// The project's files, extracts from here the files that get compiled into object code. /// </param> /// <param name="configuration"> /// A <see cref="CProjectConfiguration"/> /// The configuration to get the object files for... /// </param> /// <param name="withQuotes"> /// A <see cref="System.Boolean"/> /// If true, it will surround each object file with quotes /// so that gcc has no problem with paths that contain spaces. /// </param> /// <returns> /// An array of strings, each string is the name of a file /// that will get compiled into object code. The file name /// will already have the .o extension. /// </returns> private string[] ObjectFiles (ProjectFileCollection projectFiles, CProjectConfiguration configuration, bool withQuotes) { if(projectFiles.Count == 0) return new string[] {}; List<string> objectFiles = new List<string> (); foreach (ProjectFile f in projectFiles) { if (f.BuildAction == BuildAction.Compile) { string PathName = Path.Combine(configuration.OutputDirectory, Path.GetFileNameWithoutExtension(f.Name) + ".o"); if(File.Exists(PathName) == false) continue; if (!withQuotes) objectFiles.Add (PathName); else objectFiles.Add ("\"" + PathName + "\""); } } return objectFiles.ToArray (); }
protected virtual ExecutionCommand CreateExecutionCommand (CProjectConfiguration conf) { string app = Path.Combine (conf.OutputDirectory, conf.Output); NativeExecutionCommand cmd = new NativeExecutionCommand (app); cmd.Arguments = conf.CommandLineParameters; cmd.WorkingDirectory = Path.GetFullPath (conf.OutputDirectory); cmd.EnvironmentVariables = conf.EnvironmentVariables; return cmd; }
public override void Clean (ProjectFileCollection projectFiles, CProjectConfiguration configuration, IProgressMonitor monitor) { //clean up object files foreach (string oFile in ObjectFiles(projectFiles, configuration, false)) { if (File.Exists (oFile)) File.Delete (oFile); string dFile = Path.ChangeExtension (oFile, ".d"); if (File.Exists (dFile)) File.Delete (dFile); } CleanPrecompiledHeaders (configuration); }
public override string GetCompilerFlags (CProjectConfiguration configuration) { StringBuilder args = new StringBuilder (); string precdir = Path.Combine (configuration.SourceDirectory, ".prec"); CCompilationParameters cp = (CCompilationParameters)configuration.CompilationParameters; if (configuration.DebugMode) args.Append ("-g "); if (configuration.CompileTarget == CBinding.CompileTarget.SharedLibrary) args.Append ("-fPIC "); switch (cp.WarningLevel) { case WarningLevel.None: args.Append ("-w "); break; case WarningLevel.Normal: // nothing break; case WarningLevel.All: args.Append ("-Wall "); break; } args.Append ("-O" + cp.OptimizationLevel + " "); if (cp.ExtraCompilerArguments != null && cp.ExtraCompilerArguments.Length > 0) { string extraCompilerArgs = cp.ExtraCompilerArguments.Replace ('\n', ' '); args.Append (extraCompilerArgs + " "); } if (cp.DefineSymbols != null && cp.DefineSymbols.Length > 0) args.Append (ProcessDefineSymbols (cp.DefineSymbols) + " "); if (configuration.Includes != null) foreach (string inc in configuration.Includes) args.Append ("-I" + inc + " "); args.Append ("-I" + precdir); return args.ToString (); }
void CleanPrecompiledHeaders (CProjectConfiguration configuration) { if (string.IsNullOrEmpty (configuration.SourceDirectory)) return; string precDir = Path.Combine (configuration.SourceDirectory, ".prec"); if (Directory.Exists (precDir)) Directory.Delete (precDir, true); }
private void MakeSharedLibrary(Project project, ProjectFileCollection projectFiles, CProjectConfiguration configuration, ProjectPackageCollection packages, CompilerResults cr, IProgressMonitor monitor, string outputName) { if (!NeedsUpdate (projectFiles, configuration, outputName)) return; string objectFiles = string.Join (" ", ObjectFiles (projectFiles, configuration, true)); string pkgargs = GeneratePkgLinkerArgs (packages); StringBuilder args = new StringBuilder (); if (configuration.ExtraLinkerArguments != null && configuration.ExtraLinkerArguments.Length > 0) { string extraLinkerArgs = ExpandBacktickedParameters(configuration.ExtraLinkerArguments.Replace ('\n', ' ')); args.Append (extraLinkerArgs + " "); } if (configuration.LibPaths != null) foreach (string libpath in configuration.LibPaths) args.Append ("-L\"" + StringParserService.Parse (libpath, GetStringTags (project)) + "\" "); if (configuration.Libs != null) { foreach (string lib in configuration.Libs) { string directory = Path.GetDirectoryName(lib); string library = Path.GetFileName(lib); // Is this a 'standard' (as in, uses an orthodox naming convention) library..? string link_lib = String.Empty; if(IsStandardLibrary(configuration, directory, library, ref link_lib)) args.Append ("-l\"" + link_lib + "\" "); // If not, reference the library by it's full pathname. else args.Append ("\"" + lib + "\" "); } } string linker_args = string.Format ("-shared -o \"{0}\" {1} {2} {3}", outputName, pkgargs, objectFiles, args.ToString ()); monitor.BeginTask (GettextCatalog.GetString ("Generating shared object \"{0}\" from object files", Path.GetFileName (outputName)), 1); string errorOutput; int exitCode = ExecuteCommand (linkerCommand , linker_args, Path.GetDirectoryName (outputName), monitor, out errorOutput); if (exitCode == 0) monitor.Step (1); monitor.EndTask (); ParseCompilerOutput (errorOutput, cr); ParseLinkerOutput (errorOutput, cr); CheckReturnCode (exitCode, cr); }
private void MakeSharedLibrary(ProjectFileCollection projectFiles, ProjectPackageCollection packages, CProjectConfiguration configuration, CompilerResults cr, IProgressMonitor monitor, string outputName) { if (!NeedsUpdate (projectFiles, outputName)) return; string objectFiles = StringArrayToSingleString (ObjectFiles (projectFiles)); string pkgargs = GeneratePkgLinkerArgs (packages); StringBuilder args = new StringBuilder (); CCompilationParameters cp = (CCompilationParameters)configuration.CompilationParameters; if (cp.ExtraLinkerArguments != null && cp.ExtraLinkerArguments.Length > 0) { string extraLinkerArgs = cp.ExtraLinkerArguments.Replace ('\n', ' '); args.Append (extraLinkerArgs + " "); } if (configuration.LibPaths != null) foreach (string libpath in configuration.LibPaths) args.Append ("-L" + libpath + " "); if (configuration.Libs != null) foreach (string lib in configuration.Libs) args.Append ("-l" + lib + " "); monitor.Log.WriteLine ("Generating shared object..."); string linker_args = string.Format ("-shared -o {0} {1} {2} {3}", outputName, objectFiles, args.ToString (), pkgargs); monitor.Log.WriteLine ("using: " + linkerCommand + " " + linker_args); ProcessWrapper p = Runtime.ProcessService.StartProcess (linkerCommand, linker_args, null, null); p.WaitForExit (); string line; StringWriter error = new StringWriter (); while ((line = p.StandardError.ReadLine ()) != null) error.WriteLine (line); monitor.Log.WriteLine (error.ToString ()); ParseCompilerOutput (error.ToString (), cr); error.Close (); p.Close (); ParseLinkerOutput (error.ToString (), cr); }