// xcPlat: Cross compile for a particular platform // 0.3.0 - breaking change - changed 'call []string' to 'workingDirectory string'. func xcPlat(dest platforms.Platform, tp TaskParams, exeName string, packagePath string) (string, error) { log.Printf("building %s for platform %v.", exeName, dest) args := []string{} absoluteBin, err := core.GetAbsoluteBin(dest.Os, dest.Arch, tp.Settings.AppName, exeName, tp.WorkingDirectory, tp.Settings.GetFullVersionName(), tp.Settings.OutPath, tp.Settings.ArtifactsDest) if err != nil { return "", err } outDir := filepath.Dir(absoluteBin) err = os.MkdirAll(outDir, 0755) if err != nil { return "", err } args = append(args, "-o", absoluteBin, ".") //log.Printf("building %s", exeName) //v0.8.5 no longer using CGO_ENABLED envExtra := []string{"GOOS=" + dest.Os, "GOARCH=" + dest.Arch} if dest.Os == platforms.LINUX && dest.Arch == platforms.ARM { // see http://dave.cheney.net/2012/09/08/an-introduction-to-cross-compilation-with-go goarm := tp.Settings.GetTaskSettingString(TASK_XC, "GOARM") if goarm != "" { envExtra = append(envExtra, "GOARM="+goarm) } } err = executils.InvokeGo(packagePath, "build", args, envExtra, tp.Settings) return absoluteBin, err }
func archivePlat(goos, arch string, mainDirs []string, workingDirectory, outDestRoot string, settings *config.Settings, ending string, archiver archive.Archiver, includeTopLevelDir bool) error { resources := core.ParseIncludeResources(workingDirectory, settings.ResourcesInclude, settings.ResourcesExclude, !settings.IsQuiet()) //log.Printf("Resources: %v", resources) exes := []string{} for _, mainDir := range mainDirs { var exeName string if len(mainDirs) == 1 { exeName = settings.AppName } else { exeName = filepath.Base(mainDir) } binPath, err := core.GetAbsoluteBin(goos, arch, settings.AppName, exeName, workingDirectory, settings.GetFullVersionName(), settings.OutPath, settings.ArtifactsDest) if err != nil { return err } exes = append(exes, binPath) } outDir := filepath.Join(outDestRoot, settings.GetFullVersionName()) err := os.MkdirAll(outDir, 0777) if err != nil { return err } archivePath, err := archive.ArchiveBinariesAndResources(outDir, goos+"_"+arch, exes, settings.AppName, resources, *settings, archiver, ending, includeTopLevelDir) if err != nil { log.Printf("ZIP error: %s", err) return err } else { if !settings.IsQuiet() { log.Printf("Artifact(s) archived to %s", archivePath) } } return nil }
func setupXc(tp TaskParams) ([]platforms.Platform, error) { if len(tp.DestPlatforms) == 0 { return []platforms.Platform{}, errors.New("No valid platforms specified") } isValidateToolchain := tp.Settings.GetTaskSettingBool(TASK_XC, "validateToolchain") goroot := tp.Settings.GoRoot for _, dest := range tp.DestPlatforms { if isValidateToolchain { err := validateToolchain(dest, goroot, tp.Settings.IsVerbose()) if err != nil { log.Printf("Toolchain not ready for %v. Re-building toolchain. (%v)", dest, err) isAutoToolchain := tp.Settings.GetTaskSettingBool(TASK_XC, "autoRebuildToolchain") if isAutoToolchain { err = buildToolchain(dest.Os, dest.Arch, tp.Settings) } if err != nil { return nil, err } } } } //check for duplicate exePaths exePaths := []string{} for _, mainDir := range tp.MainDirs { var exeName string if len(tp.MainDirs) == 1 { exeName = tp.Settings.AppName } else { exeName = filepath.Base(mainDir) } for _, dest := range tp.DestPlatforms { absoluteBin, err := core.GetAbsoluteBin(dest.Os, dest.Arch, tp.Settings.AppName, exeName, tp.WorkingDirectory, tp.Settings.GetFullVersionName(), tp.Settings.OutPath, tp.Settings.ArtifactsDest) if err != nil { return nil, err } for _, existingPath := range exePaths { if existingPath == absoluteBin { return []platforms.Platform{}, errors.New("The xc task will attempt to compile multiple binaries to the same path (" + absoluteBin + "). Please make sure {{.Os}} and {{.Arch}} variables are used in the OutPath. Currently the template is " + tp.Settings.OutPath) } } exePaths = append(exePaths, absoluteBin) } } return tp.DestPlatforms, nil }
func rmBinPlat(dest platforms.Platform, tp TaskParams, exeName string) error { binPath, err := core.GetAbsoluteBin(dest.Os, dest.Arch, tp.Settings.AppName, exeName, tp.WorkingDirectory, tp.Settings.GetFullVersionName(), tp.Settings.OutPath, tp.Settings.ArtifactsDest) if err != nil { return err } err = os.Remove(binPath) if err != nil { return err } //if empty, remove dir binDir := filepath.Dir(binPath) files, err := ioutil.ReadDir(binDir) if err != nil { return err } if len(files) < 1 { err = os.Remove(binDir) } return err }
func runTaskCodesign(tp TaskParams) (err error) { for _, dest := range tp.DestPlatforms { for _, mainDir := range tp.MainDirs { var exeName string if len(tp.MainDirs) == 1 { exeName = tp.Settings.AppName } else { exeName = filepath.Base(mainDir) } binPath, err := core.GetAbsoluteBin(dest.Os, dest.Arch, tp.Settings.AppName, exeName, tp.WorkingDirectory, tp.Settings.GetFullVersionName(), tp.Settings.OutPath, tp.Settings.ArtifactsDest) if err != nil { return err } err = codesignPlat(dest.Os, dest.Arch, binPath, tp.Settings) } } //TODO return error return err }
func debBuild(dest platforms.Platform, tp TaskParams) (err error) { metadata := tp.Settings.GetTaskSettingMap(TASK_PKG_BUILD, "metadata") armArchName := getArmArchName(tp.Settings) metadataDeb := tp.Settings.GetTaskSettingMap(TASK_PKG_BUILD, "metadata-deb") rmtemp := tp.Settings.GetTaskSettingBool(TASK_PKG_BUILD, "rmtemp") debDir := filepath.Join(tp.OutDestRoot, tp.Settings.GetFullVersionName()) //v0.8.1 dont use platform dir tmpDir := filepath.Join(debDir, ".goxc-temp") if rmtemp { defer os.RemoveAll(tmpDir) } os.MkdirAll(tmpDir, 0755) err = ioutil.WriteFile(filepath.Join(tmpDir, "debian-binary"), []byte("2.0\n"), 0644) if err != nil { return err } description := "?" if desc, keyExists := metadata["description"]; keyExists { description, err = typeutils.ToString(desc, "description") if err != nil { return err } } maintainer := "?" if maint, keyExists := metadata["maintainer"]; keyExists { maintainer, err = typeutils.ToString(maint, "maintainer") if err != nil { return err } } controlContent := getDebControlFileContent(tp.AppName, maintainer, tp.Settings.GetFullVersionName(), dest.Arch, armArchName, description, metadataDeb) if tp.Settings.IsVerbose() { log.Printf("Control file:\n%s", string(controlContent)) } err = ioutil.WriteFile(filepath.Join(tmpDir, "control"), controlContent, 0644) if err != nil { return err } err = archive.TarGz(filepath.Join(tmpDir, "control.tar.gz"), []archive.ArchiveItem{archive.ArchiveItem{FileSystemPath: filepath.Join(tmpDir, "control"), ArchivePath: "control"}}) if err != nil { return err } //build items := []archive.ArchiveItem{} for _, mainDir := range tp.MainDirs { var exeName string if len(tp.MainDirs) == 1 { exeName = tp.Settings.AppName } else { exeName = filepath.Base(mainDir) } binPath, err := core.GetAbsoluteBin(dest.Os, dest.Arch, tp.Settings.AppName, exeName, tp.WorkingDirectory, tp.Settings.GetFullVersionName(), tp.Settings.OutPath, tp.Settings.ArtifactsDest) if err != nil { return err } items = append(items, archive.ArchiveItem{FileSystemPath: binPath, ArchivePath: "/usr/bin/" + exeName}) } //TODO add resources to /usr/share/appName/ err = archive.TarGz(filepath.Join(tmpDir, "data.tar.gz"), items) if err != nil { return err } targetFile := filepath.Join(debDir, fmt.Sprintf("%s_%s_%s.deb", tp.AppName, tp.Settings.GetFullVersionName(), getDebArch(dest.Arch, armArchName))) //goxc_0.5.2_i386.deb") inputs := [][]string{ []string{filepath.Join(tmpDir, "debian-binary"), "debian-binary"}, []string{filepath.Join(tmpDir, "control.tar.gz"), "control.tar.gz"}, []string{filepath.Join(tmpDir, "data.tar.gz"), "data.tar.gz"}} err = ar.ArForDeb(targetFile, inputs) return }
func debBuild(dest platforms.Platform, tp TaskParams) error { metadata := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "metadata") armArchName := getArmArchName(tp.Settings) //maintain support for old configs ... metadataDebX := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "metadata-deb") otherMappedFilesFromSetting := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "other-mapped-files") otherMappedFiles, err := calcOtherMappedFiles(otherMappedFilesFromSetting) if err != nil { return err } if tp.Settings.IsVerbose() { log.Printf("other mapped files: %+v", otherMappedFiles) } metadataDeb := map[string]string{} for k, v := range metadataDebX { val, ok := v.(string) if ok { metadataDeb[k] = val } } rmtemp := tp.Settings.GetTaskSettingBool(TASK_DEB_GEN, "rmtemp") debDir := filepath.Join(tp.OutDestRoot, tp.Settings.GetFullVersionName()) //v0.8.1 dont use platform dir tmpDir := filepath.Join(debDir, ".goxc-temp") shortDescription := "?" if desc, keyExists := metadata["description"]; keyExists { var err error shortDescription, err = typeutils.ToString(desc, "description") if err != nil { return err } } longDescription := " " if ldesc, keyExists := metadata["long-description"]; keyExists { var err error longDescription, err = typeutils.ToString(ldesc, "long-description") if err != nil { return err } } maintainerName := "?" if maint, keyExists := metadata["maintainer"]; keyExists { var err error maintainerName, err = typeutils.ToString(maint, "maintainer") if err != nil { return err } } maintainerEmail := "*****@*****.**" if maintEmail, keyExists := metadata["maintainer-email"]; keyExists { var err error maintainerEmail, err = typeutils.ToString(maintEmail, "maintainer-email") if err != nil { return err } } //'dev' Package should be a separate task addDevPackage := false /* pkg := deb.NewPackage(tp.AppName, tp.Settings.GetFullVersionName(), maintainer, description) pkg.AdditionalControlData = metadataDeb*/ build := debgen.NewBuildParams() build.DestDir = debDir build.TmpDir = tmpDir build.Init() build.IsRmtemp = rmtemp var ctrl *deb.Control //Read control data. If control file doesnt exist, use parameters ... fi, err := os.Open(filepath.Join(build.DebianDir, "control")) if os.IsNotExist(err) { log.Printf("WARNING - no debian 'control' file found. Use `debber` to generate proper debian metadata") ctrl = deb.NewControlDefault(tp.AppName, maintainerName, maintainerEmail, shortDescription, longDescription, addDevPackage) } else if err != nil { return fmt.Errorf("%v", err) } else { cfr := deb.NewControlFileReader(fi) ctrl, err = cfr.Parse() if err != nil { return fmt.Errorf("%v", err) } } debArch := getDebArch(dest.Arch, armArchName) build.Arches = []deb.Architecture{debArch} build.Version = tp.Settings.GetFullVersionName() dgens, err := debgen.PrepareBasicDebGen(ctrl, build) if err != nil { return fmt.Errorf("Error preparing deb generator: %v", err) } //there should only be one for this platform. // Anyway this part maps all binaries. for _, dgen := range dgens { // -dev paragraphs handled by 'deb-dev' task. if !strings.HasSuffix(dgen.DebWriter.Control.Get(deb.PackageFName), "-dev") { for _, mainDir := range tp.MainDirs { var exeName string if len(tp.MainDirs) == 1 { exeName = tp.Settings.AppName } else { exeName = filepath.Base(mainDir) } binPath, err := core.GetAbsoluteBin(dest.Os, dest.Arch, tp.Settings.AppName, exeName, tp.WorkingDirectory, tp.Settings.GetFullVersionName(), tp.Settings.OutPath, tp.Settings.ArtifactsDest) if err != nil { return err } if dgen.DataFiles == nil { dgen.DataFiles = map[string]string{} } dgen.DataFiles["./usr/bin/"+exeName] = binPath } for k, v := range otherMappedFiles { dgen.DataFiles[k] = v } err = dgen.GenerateAllDefault() if err != nil { return fmt.Errorf("Error generating deb: %v", err) } if !tp.Settings.IsQuiet() { log.Printf("Wrote deb to %s", filepath.Join(build.DestDir, dgen.DebWriter.Filename)) } } } return err }