Esempio n. 1
0
		protected string GeneratePkgLinkerArgs (ProjectPackageCollection packages)
		{
			if (packages == null || packages.Count < 1)
				return string.Empty;
			
			StringBuilder libs = new StringBuilder ();
			
			foreach (ProjectPackage p in packages)
				libs.Append (p.File + " ");
			
			string args = string.Format ("--libs {0}", libs.ToString ().Trim ());
			
			StringWriter output = new StringWriter ();			
			ProcessWrapper proc = new ProcessWrapper ();
			
			try {			
				proc = Runtime.ProcessService.StartProcess ("pkg-config", args, null, null);
				proc.WaitForExit ();
				
				string line;
				while ((line = proc.StandardOutput.ReadLine ()) != null)
					output.WriteLine (line);
			} catch (Exception ex) {
				IdeApp.Services.MessageService.ShowError (ex, "You need to have pkg-config installed");
			} finally {
				proc.Close ();
			}
			
			return output.ToString ();
		}
Esempio n. 2
0
		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, "");
		}
Esempio n. 3
0
		protected static string GeneratePkgConfigArgs (ProjectPackageCollection packages, string pkgConfigArg)
		{
			if (packages == null || packages.Count < 1)
				return string.Empty;
			string originalPkgConfigPath = Environment.GetEnvironmentVariable ("PKG_CONFIG_PATH");
			string pkgConfigPath = originalPkgConfigPath;
			
			StringBuilder libs = new StringBuilder ();
			
			foreach (Package p in packages) {
				if (Path.IsPathRooted (p.File)) {
					pkgConfigPath = string.Format ("{0}{1}{2}", pkgConfigPath, Path.PathSeparator, Path.GetDirectoryName (p.File));
					libs.Append (Path.GetFileNameWithoutExtension (p.File) + " ");
				} else {
					libs.Append (p.File + " ");
				}
			}
			
			string args = string.Format ("{0} \"{1}\"", pkgConfigArg, libs.ToString ().Trim ());
			
			StringWriter output = new StringWriter ();			
			ProcessWrapper proc = new ProcessWrapper ();
			
			try {			
				Environment.SetEnvironmentVariable ("PKG_CONFIG_PATH", pkgConfigPath);
				proc = Runtime.ProcessService.StartProcess ("pkg-config", args, null, null);
				proc.WaitForExit ();
				
				string line;
				while ((line = proc.StandardOutput.ReadLine ()) != null)
					output.WriteLine (line);
			} catch (Exception ex) {
				MessageService.ShowError ("You need to have pkg-config installed");
			} finally {
				proc.Close ();
				Environment.SetEnvironmentVariable ("PKG_CONFIG_PATH", originalPkgConfigPath);
			}
			
			return output.ToString ();
		}
Esempio n. 4
0
		protected string GeneratePkgCompilerArgs (ProjectPackageCollection packages)
		{
			return GeneratePkgConfigArgs (packages, "--cflags");
		}
Esempio n. 5
0
		protected string GeneratePkgLinkerArgs (ProjectPackageCollection packages)
		{
			return GeneratePkgConfigArgs (packages, "--libs");
		}
Esempio n. 6
0
		public abstract BuildResult Compile (
		    Project project,
		    ProjectFileCollection projectFiles,
		    ProjectPackageCollection packages,
		    CProjectConfiguration configuration,
		    IProgressMonitor monitor);
Esempio n. 7
0
		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, "");
		}
Esempio n. 8
0
		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);
		}
Esempio n. 9
0
		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 void AddRange (ProjectPackageCollection packages)
		{
			foreach (ProjectPackage p in packages)
				List.Add (p);
		}
		public ProjectPackageEnumerator (ProjectPackageCollection packages)
		{
			temp = (IEnumerable)packages;
			enumerator = temp.GetEnumerator ();
		}
		public EditPackagesDialog(CProject project)
		{
			this.Build();
			
			this.project = project;
			
			selectedPackages.AddRange (project.Packages);
			
			Gtk.CellRendererText textRenderer = new Gtk.CellRendererText ();
			
			Gtk.CellRendererPixbuf pixbufRenderer = new Gtk.CellRendererPixbuf ();
			pixbufRenderer.StockId = "md-package";
			
			// <!-- Normal packages -->
			
			Gtk.CellRendererToggle normalPackageToggleRenderer = new Gtk.CellRendererToggle ();
			normalPackageToggleRenderer.Activatable = true;
			normalPackageToggleRenderer.Toggled += OnNormalPackageToggled;
			normalPackageToggleRenderer.Xalign = 0;
			
			Gtk.TreeViewColumn normalPackageColumn = new Gtk.TreeViewColumn ();
			normalPackageColumn.Title = "Package";
			normalPackageColumn.PackStart (pixbufRenderer, false);
			normalPackageColumn.PackStart (textRenderer, true);
			normalPackageColumn.AddAttribute (textRenderer, "text", 1);
			
			normalPackageTreeView.Model = normalPackageListStore;
			normalPackageTreeView.HeadersVisible = true;
			normalPackageTreeView.AppendColumn ("", normalPackageToggleRenderer, "active", 0);
			normalPackageTreeView.AppendColumn (normalPackageColumn);
			normalPackageTreeView.AppendColumn ("Version", textRenderer, "text", 2);
			
			// <!-- Project packages -->
			
			Gtk.CellRendererToggle projectPackageToggleRenderer = new Gtk.CellRendererToggle ();
			projectPackageToggleRenderer.Activatable = true;
			projectPackageToggleRenderer.Toggled += OnProjectPackageToggled;
			projectPackageToggleRenderer.Xalign = 0;
			
			Gtk.TreeViewColumn projectPackageColumn = new Gtk.TreeViewColumn ();
			projectPackageColumn.Title = "Package";
			projectPackageColumn.PackStart (pixbufRenderer, false);
			projectPackageColumn.PackStart (textRenderer, true);
			projectPackageColumn.AddAttribute (textRenderer, "text", 1);
			
			projectPackageTreeView.Model = projectPackageListStore;
			projectPackageTreeView.HeadersVisible = true;
			projectPackageTreeView.AppendColumn ("", projectPackageToggleRenderer, "active", 0);
			projectPackageTreeView.AppendColumn (projectPackageColumn);
			projectPackageTreeView.AppendColumn ("Version", textRenderer, "text", 2);
			
			
			// <!-- Selected packages -->
			
			Gtk.TreeViewColumn selectedPackageColumn = new Gtk.TreeViewColumn ();
			selectedPackageColumn.Title = "Package";
			selectedPackageColumn.PackStart (pixbufRenderer, false);
			selectedPackageColumn.PackStart (textRenderer, true);
			selectedPackageColumn.AddAttribute (textRenderer, "text", 0);
			
			selectedPackagesTreeView.Model = selectedPackagesListStore;
			selectedPackagesTreeView.HeadersVisible = true;
			selectedPackagesTreeView.AppendColumn (selectedPackageColumn);
			selectedPackagesTreeView.AppendColumn ("Version", textRenderer, "text", 1);
			
			// Fill up the project tree view
			projectPackages = ProjectPackages (project);
			
			foreach (ProjectPackage p in projectPackages) {
				if (p.Name == project.Name) continue;
				string version = GetPackageVersion (p.File);
				bool inProject = IsInProject (p.File);
				projectPackageListStore.AppendValues (inProject, p.Name, version);
				
				if (inProject)
					selectedPackagesListStore.AppendValues (p.Name, version);
			}
			
			// Fill up the normal tree view
			foreach (string dir in ScanDirs ()) {
				if (Directory.Exists (dir)) {	
					DirectoryInfo di = new DirectoryInfo (dir);
					FileInfo[] availablePackages = di.GetFiles ("*.pc");
					
					foreach (FileInfo f in availablePackages) {
						if (!IsValidPackage (f.FullName)) { 
							continue;
						}
						string name = f.Name.Substring (0, f.Name.LastIndexOf ('.'));
						string version = GetPackageVersion (f.FullName);
						bool inProject = IsInProject (name);
						normalPackageListStore.AppendValues (inProject, name, version);
						
						if (inProject)
							selectedPackagesListStore.AppendValues (name, version);
					}
				}
			}
		}
		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;
		}
Esempio n. 14
0
		/// <summary>
		/// Compiles a single source file into object code
		/// and creates a file with it's dependencies.
		/// </summary>
		private bool DoCompilation (ProjectFile file, string args,
		                            ProjectPackageCollection packages,
		                            IProgressMonitor monitor,
		                            CompilerResults cr,
		                            bool use_ccache)
		{			
			string outputName = Path.ChangeExtension (file.Name, ".o");
			string pkgargs = GeneratePkgCompilerArgs (packages);
			
			string compiler_args = string.Format ("{0} -MMD {1} {2} -c -o {3} {4}",
			    (use_ccache ? compilerCommand : string.Empty), file.Name, args, outputName, pkgargs);
			
			monitor.Log.WriteLine ("using: " + compilerCommand + " " + compiler_args);
			
			ProcessWrapper p = Runtime.ProcessService.StartProcess (
			    (use_ccache ? "ccache" : compilerCommand), compiler_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 ();
			
			bool result = p.ExitCode == 0;
			p.Close ();
			
			return result;
		}
Esempio n. 15
0
		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);
		}