public MakefileVar(MakefileVar var) { this.extra = new List <string> (var.Extra); this.Sync = var.Sync; this.Name = var.Name; this.Prefix = var.Prefix; this.SaveEnabled = var.SaveEnabled; }
public MakefileVar (MakefileVar var) { this.extra = new List<string> (var.Extra); this.Sync = var.Sync; this.Name = var.Name; this.Prefix = var.Prefix; this.SaveEnabled = var.SaveEnabled; }
bool CheckNonEmptyFileVar(MakefileVar var, string id) { if (var.Sync && String.IsNullOrEmpty(var.Name.Trim())) { MessageService.ShowError(parentDialog, GettextCatalog.GetString( "File variable ({0}) is set for sync'ing, but no valid variable is selected. Either disable the sync'ing or select a variable name.", id)); return(false); } return(true); }
//FIXME: change return type to bool, on false, extra.Add (reference) void ParseReference (string reference, bool usePrefix, MakefileVar refVar, int len, ReferenceType refType, DotNetProject project) { string rname = reference; // .StartsWith "$(" if (rname.Length > 3 && rname [0] == '$' && rname [1] == '(' && rname [rname.Length - 1] == ')') { if (!UseAutotools) { refVar.Extra.Add (reference); return; } // Autotools based project if (!rname.EndsWith ("_LIBS)")) { //Not a pkgconfig *_LIBS var refVar.Extra.Add (reference); return; } string pkgVarName = rname.Substring (2, rname.Length - 3).Replace ("_LIBS", String.Empty); List<PackageContent> pkgNames = ConfiguredPackages.GetPackageContentFromVarName (pkgVarName); if (pkgNames == null) { LoggingService.LogWarning ("Package named '{0}' not found in configure.in. Ignoring reference to '{1}'.", pkgVarName, rname); refVar.Extra.Add (reference); return; } bool added = false; foreach (PackageContent packageContent in pkgNames) { if (ReferencedPackages.Contains (packageContent.Name)) { added = true; continue; } // Add all successfully added packages to ReferencedPackages foreach (string referencedName in packageContent.AllReferencedNames) { if (LoadPackageReference (referencedName, project, refVar.Prefix)) { ReferencedPackages.Add (referencedName); added = true; } } } // none of the packages could be added if (!added) refVar.Extra.Add (reference); return; } // .StartsWith "-pkg:" if (rname.Length >= 5 && rname [0] == '-' && rname [1] == 'p' && rname [2] == 'k' && rname [3] == 'g' && rname [4] == ':') { string pkgName = rname.Substring (5); //-pkg:foo,bar foreach (string s in pkgName.Split (new char [] {','}, StringSplitOptions.RemoveEmptyEntries)) { if (ReferencedPackages.Contains (s)) continue; if (LoadPackageReference (s, project, refVar.Prefix)) ReferencedPackages.Add (s); else refVar.Extra.Add ("-pkg:" + s); } return; } if (usePrefix && String.Compare (refVar.Prefix, 0, rname, 0, len) == 0) rname = rname.Substring (len); //FIXME: try/catch around the split refs ? bool varFound = false; foreach (string r in rname.Split (new char [] {','}, StringSplitOptions.RemoveEmptyEntries)) { string refname = r; if (refname.Length >= 2 && refname [0] == '$' && refname [1] == '(' && !UseAutotools) { //Eg. -r:$(top_builddir)/foo.dll refVar.Extra.Add (reference); continue; } varFound = false; refname = ResolveBuildVars (refname, ref varFound); EncodeValues [refVar.Name] |= varFound; string fullpath = Path.GetFullPath (Path.Combine (BaseDirectory, refname)); // if refname is part of a package then add as gac // but don't do it if the refname exactly matches a file name in the project dir if (refname.IndexOf (Path.DirectorySeparatorChar) < 0 && !File.Exists (fullpath) && ParseReferenceAsGac (refname, project) != null) continue; if (TryGetExistingGacRef (fullpath) != null) continue; if (refname.IndexOf (Path.DirectorySeparatorChar) < 0) { // Check that its a valid assembly string fullname = null; try { fullname = AssemblyName.GetAssemblyName (fullpath).FullName; } catch (FileNotFoundException) { } catch (BadImageFormatException) { } // Valid assembly, From a package, add as Gac SystemPackage pkg = assemblyContext.GetPackageFromPath (fullpath); if (fullname != null && pkg != null) { SystemAssembly sa = assemblyContext.GetAssemblyFromFullName (fullname, pkg.Name, project.TargetFramework); if (sa != null) { AddNewGacReference (project, sa); continue; } } } //Else add to unresolved project refs, avoid repeats if (!UnresolvedReferences.ContainsKey (fullpath)) UnresolvedReferences [fullpath] = fullpath; } }
void ReadReferences (MakefileVar refVar, ReferenceType refType, string id, DotNetProject project) { if (String.IsNullOrEmpty (refVar.Name) || project == null) return; //All filenames are treated as relative to the Makefile path List<string> references = Makefile.GetListVariable (refVar.Name); if (references == null) { string msg = GettextCatalog.GetString ( "Makefile variable '{0}' not found. Skipping syncing of all '{1}' references for project {2}.", refVar.Name, id, project.Name); LoggingService.LogWarning (msg); monitor.ReportWarning (msg); SaveReferences = false; return; } //FIXME: Trim? bool usePrefix = !String.IsNullOrEmpty (refVar.Prefix); int len = 0; if (refVar.Prefix != null) len = refVar.Prefix.Length; ReferencedPackages.Clear (); foreach (string r in references) { //Handle -r:System,System.Data also try { ParseReference (r, usePrefix, refVar, len, refType, project); } catch (Exception e) { string msg = GettextCatalog.GetString ("Unable to parse reference '{0}' for project '{1}'. Ignoring.", r, project.Name); LoggingService.LogWarning (msg, e); monitor.ReportWarning (msg); refVar.Extra.Add (r); } } referencedPackages = null; }
void ReadFilesActual (MakefileVar fileVar, string buildAction, string id, bool promptForRemoval) { fileVar.Extra.Clear (); if (!fileVar.Sync || String.IsNullOrEmpty (fileVar.Name)) return; //All filenames are treated as relative to the Makefile path List<string> files = Makefile.GetListVariable (fileVar.Name); if (files == null) { //FIXME: Move this to the caller, try-catch there string msg = GettextCatalog.GetString ( "Makefile variable '{0}' not found. Skipping syncing of '{1}' file list for project '{2}'.", fileVar.Name, id, ownerProject.Name); LoggingService.LogWarning (msg); monitor.ReportWarning (msg); fileVar.SaveEnabled = false; return; } //FIXME: Trim? bool usePrefix = !String.IsNullOrEmpty (fileVar.Prefix); int len = 0; if (fileVar.Prefix != null) len = fileVar.Prefix.Length; Dictionary<string, ProjectFile> existingFiles = new Dictionary<string, ProjectFile> (); foreach (ProjectFile pf in ownerProject.Files) { if (pf.BuildAction == buildAction) existingFiles [ownerProject.GetAbsoluteChildPath (pf.FilePath)] = pf; } // True if the user has been warned that filenames contain Variables // but no configure.in path is set bool autotoolsWarned = false; bool varFound = false; foreach (string f in files) { string fname = f.Trim (); try { if (usePrefix && String.Compare (fileVar.Prefix, 0, fname, 0, len) == 0) //FIXME: If it doesn't match, then? fname = fname.Substring (len); fname = FromMakefilePath (fname); string resourceId = null; if (buildAction == BuildAction.EmbeddedResource && fname.IndexOf (',') >= 0) { string [] tmp = fname.Split (new char [] {','}, 2); fname = tmp [0]; if (tmp.Length > 1) resourceId = tmp [1]; } if ((fname.Length > 2 && fname [0] == '$' && fname [1] == '(') && !UseAutotools) { fileVar.Extra.Add (f); if (!autotoolsWarned) { string msg = GettextCatalog.GetString ( "Files in variable '{0}' contains variables which cannot be parsed without the path " + "to configure.in being set. Ignoring such files.", fileVar.Name); LoggingService.LogWarning (msg); monitor.ReportWarning (msg); autotoolsWarned = true; } continue; } varFound = false; fname = ResolveBuildVars (fname, ref varFound); EncodeValues [fileVar.Name] |= varFound; //File path in the makefile are relative to the makefile, //but have to be added to the project as relative to project.BaseDirectory string absPath = Path.GetFullPath (Path.Combine (BaseDirectory, fname)); if (existingFiles.ContainsKey (absPath)) { existingFiles.Remove (absPath); continue; } if (!File.Exists (absPath)) { //Invalid file, maybe we couldn't parse it correctly! string msg = GettextCatalog.GetString ( "Ignoring invalid file '{0}' found in '{1}' for project '{2}'.", f, relativeMakefileName, OwnerProject.Name); LoggingService.LogWarning (msg); monitor.ReportWarning (msg); fileVar.Extra.Add (f); continue; } ProjectFile pf = ownerProject.AddFile (absPath, buildAction); if (buildAction == BuildAction.EmbeddedResource && resourceId != null) pf.ResourceId = resourceId; } catch (Exception e) { LoggingService.LogError (e.ToString ()); fileVar.Extra.Add (f); } } if (existingFiles.Count > 0) { foreach (ProjectFile file in existingFiles.Values) { if (!IsFileExcluded (file.FilePath)) ownerProject.Files.Remove (file); } } }
void ReadFiles (MakefileVar fileVar, string buildAction, string id, bool promptForRemoval) { try { fileVar.SaveEnabled = true; ReadFilesActual (fileVar, buildAction, id, promptForRemoval); } catch (Exception e) { string msg = GettextCatalog.GetString ("Error in loading files for '{0}'. Skipping.", id); LoggingService.LogError (msg, e); monitor.ReportWarning (msg); fileVar.SaveEnabled = false; } }
string ProjectRefToString (ProjectReference pr, MakefileVar refVar) { string [] tmp = pr.GetReferencedFileNames (ConfigurationSelector.Default); if (tmp == null || tmp.Length == 0) //Reference not found, ignoring return null; return AsmRefToString (tmp [0], refVar, true); }
string AsmRefToString (string reference, MakefileVar refVar, bool isBuiltAssembly) { if (EncodeValues [refVar.Name]) { if (!isBuiltAssembly) return ToMakefilePath (EncodeFileName (reference, "top_srcdir", true)); else if (!reference.StartsWith (BaseDirectory)) //Reference is external to this project return ToMakefilePath (EncodeFileName (reference, "top_builddir", true)); } // !external and !encode return ToMakefilePath (GetRelativePath (reference)); }
string GacRefToString (ProjectReference pr, Dictionary<string, bool> hasAcSubstPackages, MakefileVar refVar) { //Gac ref can be a full name OR a path! //FIXME: Use GetReferencedFileName and GetPackageFromPath ? string fullname = pr.Reference; SystemPackage pkg = pr.Package; if (pkg == null) { //reference could be a path pkg = assemblyContext.GetPackageFromPath (Path.GetFullPath (pr.Reference)); if (pkg != null) { //Path try { fullname = AssemblyName.GetAssemblyName (pr.Reference).FullName; //If this throws : Invalid assembly! //let it fall through and be emitted as a asm ref } catch (FileNotFoundException) { pkg = null; } catch (BadImageFormatException) { pkg = null; } } } if (pkg == null) return AsmRefToString (pr.GetReferencedFileNames (ConfigurationSelector.Default) [0], refVar, false); // Reference is from a package if (pkg.IsCorePackage) //pkg:mono, Eg. System, System.Data etc return fullname.Split (new char [] {','}, 2) [0]; //Ref is from a non-core package string varname = null; if (UseAutotools) //Check whether ref'ed in configure.in varname = ConfiguredPackages.GetVarNameFromName (pkg.Name); if (varname == null) { //Package not referenced in configure.in //Or not a autotools based project, //so emit -pkg: if (!hasAcSubstPackages.ContainsKey (pkg.Name)) { if (UseAutotools) { //Warn only if UseAutotools string msg = GettextCatalog.GetString ( "A reference to the pkg-config package '{0}' is being emitted to the Makefile, " + "because at least one assembly from the package is used in the project '{1}'. However, " + "this dependency is not specified in the configure.in file, so you might need to " + "add it to ensure that the project builds successfully on other systems.", pkg.Name, pr.OwnerProject.Name); LoggingService.LogWarning (msg); monitor.ReportWarning (msg); } hasAcSubstPackages [pkg.Name] = false; } } else { // If the package as AC_SUBST(FOO_LIBS) defined, then // emit FOO_LIBS, else emit -pkg:foo if (ConfiguredPackages.HasAcSubst (varname + "_LIBS")) { hasAcSubstPackages [varname] = true; } else { hasAcSubstPackages [pkg.Name] = false; } } return null; }
bool WriteReferences (MakefileVar refVar, ReferenceType refType, bool makeRelative, string id) { //Reference vars can be shared too, so use existing list //Eg. REF for both Gac and Asm ref List<string> references = Makefile.GetListVariable (refVar.Name); if (references == null) { //Var not found, skip string msg = GettextCatalog.GetString ( "Makefile variable '{0}' not found. Skipping syncing of '{1}' references.", refVar.Name, id); LoggingService.LogWarning (msg); monitor.ReportWarning (msg); return false; } //if .Value is true // key -> Varname, Emit as $key_LIBS //if .Value is false // key -> pkgname, emit as -pkg:$key Dictionary<string, bool> hasAcSubstPackages = new Dictionary<string, bool> (); foreach (ProjectReference pr in ((DotNetProject)OwnerProject).References) { if (pr.ReferenceType != refType) continue; string refstr = String.Empty; switch (refType) { case ReferenceType.Gac: //Assemblies coming from packages are always added as Gac refstr = GacRefToString (pr, hasAcSubstPackages, refVar); if (refstr == null) continue; break; case ReferenceType.Assembly: refstr = AsmRefToString (pr.Reference, refVar, false); break; case ReferenceType.Project: refstr = ProjectRefToString (pr, refVar); if (refstr == null) continue; break; default: //not supported continue; } references.Add (String.Format ("{0}{1}", refVar.Prefix, refstr)); } //Add packages foreach (KeyValuePair<string, bool> pair in hasAcSubstPackages) { if (pair.Value) references.Add (String.Format ("$({0}_LIBS)", pair.Key)); else references.Add (String.Format ("-pkg:{0}", pair.Key)); } foreach (string s in refVar.Extra) references.Add (s); Makefile.SetListVariable (refVar.Name, references); return true; }
bool WriteFiles (MakefileVar fileVar, string buildAction, bool makeRelative, string id) { if (!fileVar.Sync || !fileVar.SaveEnabled) return false; if (Makefile.GetListVariable (fileVar.Name) == null) { //Var not found, skip string msg = GettextCatalog.GetString ( "Makefile variable '{0}' not found. Skipping writing of '{1}' files to the Makefile.", fileVar.Name, id); LoggingService.LogWarning (msg); monitor.ReportWarning (msg); return false; } List<string> files = new List<string> (); foreach (ProjectFile pf in OwnerProject.Files) { if (pf.Subtype != Subtype.Code) continue; if (IsFileExcluded (pf.FilePath)) continue; if (pf.BuildAction == buildAction) { string str = null; if (makeRelative) //Files are relative to the Makefile str = GetRelativePath (pf.FilePath); else str = pf.FilePath.ToRelative (pf.Project.BaseDirectory); string unescapedFileName = Path.GetFileName (str); if (EncodeValues [fileVar.Name]) { if (pf.IsExternalToProject) str = EncodeFileName (str, "top_srcdir", false); else str = EncodeFileName (str, "srcdir", false); } str = ToMakefilePath (str); // Emit the resource ID only when it is different from the file name if (pf.BuildAction == BuildAction.EmbeddedResource && pf.ResourceId != null && pf.ResourceId.Length > 0 && pf.ResourceId != unescapedFileName) str = String.Format ("{0}{1},{2}", fileVar.Prefix, str, EscapeString (pf.ResourceId)); else str = String.Format ("{0}{1}", fileVar.Prefix, str); str = NormalizeFileName (str); files.Add (str); } } foreach (string s in fileVar.Extra) files.Add (s); // Keep the file list sorted in the makefile files.Sort (System.StringComparer.InvariantCulture); Makefile.SetListVariable (fileVar.Name, files); return true; }
bool CheckNonEmptyFileVar (MakefileVar var, string id) { if (var.Sync && String.IsNullOrEmpty (var.Name.Trim ())) { MessageService.ShowError (parentDialog,GettextCatalog.GetString ( "File variable ({0}) is set for sync'ing, but no valid variable is selected. Either disable the sync'ing or select a variable name.", id)); return false; } return true; }