Windows下载AOSP

news2024/10/6 14:27:36

关于repo

repo只是谷歌做的,方便下载安卓源码的工具,本质上是对下载清单进行批量处理,然后使用git克隆。
在windows上下载源码只需要自己处理即可。

具体做法

首先使用git克隆安卓源码清单

git clone https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest

随后进入manifest目录,查看所有tag

git tag

在这里插入图片描述

tag名就是安卓源码的版本,选择你要的版本,记下来。例如android-13.0.0_r9
随后切换分支

git checkout android-13.0.0_r9

在这里插入图片描述
记住文件夹中的default.xml的路径
以上操作完成了清单的下载,接下来我们只需要执行按清单下载的操作即可。
我提供两个我编写的脚本,一个python环境,一个golang环境。
注意:该脚本不支持断点续传,如需使用,请保持网络环境良好或自行修改脚本。

Python环境

该Python下载脚本仅支持单线程下载,不过git仍可以跑满你的网速

import xml.dom.minidom
import os
from subprocess import call

version = "android-13.0.0_r9"

# 1. 源码要保存的路径
rootdir = "D:/AOSP/"+version

# 2. git 的路径
git = r"C:\Program Files\Git\cmd\git.exe"

# 3. default.xml 的路径
dom = xml.dom.minidom.parse(r"D:\AOSP\manifest\default.xml")
root = dom.documentElement

# 4. 只支持单一镜像源
prefix = git + " clone https://aosp.tuna.tsinghua.edu.cn/"
suffix = ".git"

if __name__ == '__main__':

    if not os.path.exists(rootdir):
        os.mkdir(rootdir)

    for node in root.getElementsByTagName("project"):
        os.chdir(rootdir)
        d = node.getAttribute("path")
        last = d.rfind("/")
        if last != -1:
            d = rootdir + "/" + d[:last]
            if not os.path.exists(d):
                os.makedirs(d)
            os.chdir(d)
        cmd = prefix + node.getAttribute("name") + suffix
        # 单线程下载
        call(cmd)

Golang环境

该golang脚本支持从多个镜像站并发下载,可限制每个镜像站同时下载的线程个数,以及总线程个数。
注意: * 总线程个数应小于等于各个镜像站线程个数相加*
resource.go

package main

import (
	"sync"
)

type Resource struct {
	Url  string
	Lock chan struct{}
}

type ResourcePool struct {
	resources []*Resource
	cond      *sync.Cond
}

func NewResourcePool(list []*Resource) *ResourcePool {
	pool := &ResourcePool{
		cond: sync.NewCond(&sync.Mutex{}),
	}
	pool.resources = list

	return pool
}

func (pool ResourcePool) GetResource() *Resource {
	pool.cond.L.Lock()
	defer pool.cond.L.Unlock()

	for {
		for _, resource := range pool.resources {
			select {
			case resource.Lock <- struct{}{}:
				return resource
			default:
				continue
			}
		}

		pool.cond.Wait()
	}
}

func (pool ResourcePool) ReleaseResource(resource *Resource) {
	<-resource.Lock

	pool.cond.Signal()
}

main.go

package main

import (
	"encoding/xml"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
)

type Project struct {
	XMLName xml.Name `xml:"project"`
	Name    string   `xml:"name,attr"`
	Path    string   `xml:"path,attr"`
}

type Manifest struct {
	XMLName xml.Name  `xml:"manifest"`
	Project []Project `xml:"project"`
}

var (
	concurrentNum int
	rootDir       string
	manifestPath  string

	wg sync.WaitGroup
)

var resourceA = &Resource{Url: "https://mirrors.bfsu.edu.cn/git/AOSP/%s.git", Lock: make(chan struct{}, 4)}
var resourceB = &Resource{Url: "https://aosp.tuna.tsinghua.edu.cn/%s.git", Lock: make(chan struct{}, 3)}

//var resourceC = &Resource{Url: "https://mirror.nju.edu.cn/%s.git", Lock: make(chan struct{}, 3)}

//var resourceC = &Resource{Url: "https://mirrors.shanghaitech.edu.cn/%s.git", Lock: make(chan struct{}, 3)}

func init() {
	flag.IntVar(&concurrentNum, "concurrentNum", 7, "Number of concurrent goroutines")
	flag.StringVar(&rootDir, "root", "D:/AOSP/android-13.0.0_r9", "Root dir of AOSP.")
	flag.StringVar(&manifestPath, "manifest", "D:/AOSP/manifest/default.xml", "Manifest of AOSP.")
}

func errorHandle(str string, err error) {
	if err != nil {
		log.Fatalf("Failed to %s: %v", str, err)
		os.Exit(-6)
	}
}

func main() {
	flag.Parse()
	manifestXML, err := os.ReadFile(manifestPath)
	errorHandle("Read manifest file", err)

	var manifest Manifest
	err = xml.Unmarshal(manifestXML, &manifest)
	errorHandle("Parse manifest XML", err)

	err = os.MkdirAll(rootDir, 0755)
	errorHandle("Create root directory", err)

	sem := make(chan struct{}, concurrentNum)

	pool := NewResourcePool([]*Resource{
		resourceA, resourceB,
	})

	for _, node := range manifest.Project {
		wg.Add(1)
		go func(project Project) {
			defer wg.Done()
			sem <- struct{}{}
			defer func() { <-sem }()

			cmdDir := rootDir

			d := project.Path
			last := strings.LastIndex(d, "/")
			if last != -1 {
				d = filepath.Join(rootDir, d[:last])
				if err := os.MkdirAll(d, 0755); err != nil {
					errorHandle("Create d directory", err)
				}

				cmdDir = d
			}
			resource := pool.GetResource()
			if resource == nil {
				fmt.Println("No resource available")
				os.Exit(2)
				return
			}

			cmd := exec.Command("git", "clone", fmt.Sprintf(resource.Url, project.Name))
			cmdDir = strings.ReplaceAll(cmdDir+"\\", "/", "\\")
			cmd.Dir = cmdDir
			if err := cmd.Run(); err != nil {
				fmt.Printf("Failed to clone node: %v %s \n", err, cmd)
				return
			}
			pool.ReleaseResource(resource)

			fmt.Printf("Cloned node: %s \n", project.Name)
		}(node)
	}

	wg.Wait()
}

截至到23年10月3日,完全可用的镜像站仅剩清华,其他AOSP的镜像或多或少均有问题
python的脚本足矣,经测试,均速16m/s,一晚上可以下载好android-13.0.0_r9的所有源码
go的脚本推荐大家不要乱用,过多的下载进程会对镜像站造成巨大的负载
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1057370.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.Tensor For Beginner - Motivation

为何要研究张量&#xff1f; --主要原因是几何。 Tensors Geometry 了解张量后&#xff0c;可深入了解几何的工作原理 几何的一个例子&#xff1a;爱因斯坦广义相对论中的时空几何 时空是如何弯曲的&#xff0c;宇宙是如何膨胀的。 要从数学上理解这两个问题&am…

归并排序及其非递归实现

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 归并排序递归实现 归并排序非递归实现 归并排序递归实现 图示&#xff1a; 代码&#xff1a; 先分再归并&#xff0c;像是后序一般。 //归并排序 void MergeSort(int* arr, int left, int right) {int* temp (int…

Pikachu靶场——越权访问漏洞(over permission)

文章目录 1. over permission1.1 水平越权1.1.1 源代码分析1.1.2 漏洞防御 1.2 垂直提权1.2.1 源代码分析1.2.2 漏洞防御 1.3 越权访问漏洞防御 1. over permission 漏洞描述 越权访问&#xff08;Broken Access Control&#xff0c;BAC&#xff09;&#xff0c;指应用在检查…

用python表格初级尝试

Excel&#xff0c;我的野心 当我输入3,2 就表示在第3行第2列。的单元格输入数据input输入表头 &#xff08;input内除了/&#xff0c;空格 回车 标点符号等 全部作为单元格分隔符&#xff09;由我设置input输入的是行or列 给选项 1. 行 2. 列默认回车或没输入值是列由我设置起…

SEO效果又慢又差,为什么还会有SEO从业者?

“SEO效果又慢又差&#xff0c;这么还会有SEO从业者&#xff1f;”这句话是我今天在某Q群里看到的&#xff0c;其实这个问题我之前也有写过一篇《你问我&#xff0c;为什么还有人做SEO&#xff1f;》。我文中提到过因为搜索无处不在&#xff0c;有搜索后&#xff0c;搜索引擎就…

JavaScript:从入门到进阶的旅程

JavaScript是一种广泛使用的编程语言&#xff0c;为网页和应用程序提供了交互性和动态性。从初学者到资深开发者&#xff0c;JavaScript都是一项值得掌握的技能。在本文中&#xff0c;我们将探讨JavaScript的基础知识&#xff0c;以及一些进阶的概念和技巧。 一、JavaScript简…

Linux系统编程系列之线程

一、什么是线程 线程&#xff08;Thread&#xff09;是计算机中的基本执行单元&#xff0c;是操作系统调度的最小单位。线程是进程内的一个独立执行流程&#xff0c;一个进程可以包含多个线程&#xff0c;这些线程共享进程的资源&#xff0c;但每个线程都有自己的独立栈空间以及…

基于SSM的学生事务处理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

matplotlib从起点出发(9)_Tutorial_9_cycler

0 需求 绘图时有时需要指定几种颜色&#xff0c;或者线型&#xff0c;我们统称为样式&#xff0c;让绘制出的内容在这些样式中循环配置。这时就需要使用到本文所提到的技巧&#xff0c;即cycler. 1 进入教程 本文是自定义属性循环(cycler)设置的演示&#xff0c;用于控制多线…

travel总结:

1、前期准备&#xff1a; 对于项目的大体构成做了一定的了解&#xff0c;然后主要是做后端的数据处理&#xff0c;前期的准备的话创建项目的大体结构&#xff0c;servlet、service、domain、dao、utils的项目结构。以及一些基础的代码的生成&#xff0c;我觉得最主要的是一些基…

leetCode 55.跳跃游戏 贪心算法

给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入…

MySQL的卸载与安装(Linux)

MySQL 前言1. 卸载MySQL1.1 查询与关闭对应MySQL服务1.2 卸载对应安装包 2. 安装MySQL2.1 配置MySQL官方yum源2.2 开始安装MySQL 前言 在这里演示的卸载与安装MySQL都是在Linux的Centos 7.6 环境下&#xff0c;不同环境会有所出入。 为了避免安装和卸载MySQL过程中受到权限的…

CF505B Mr. Kitayuta‘s Colorful Graph

Mr. Kitayuta’s Colorful Graph 题面翻译 给出一个 n n n 个点&#xff0c; m m m 条边的无向图&#xff0c;每条边上是有颜色的。有 q q q 组询问 对于第 i i i 组询问&#xff0c;给出点对 u i , v i u_i,v_i ui​,vi​。求有多少种颜色 c c c 满足&#xff1a;有至…

算法-动态规划/trie树-单词拆分

算法-动态规划/trie树-单词拆分 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/word-break/description/?envTypestudy-plan-v2&envIdtop-interview-150 1.2 题目描述 2 动态规划 2.1 解题思路 dp[i]表示[0, i)字符串可否构建那么dp[i]可构建的条件是&…

基于ssm的互联网废品回收/基于web的废品资源利用系统

摘 要 本毕业设计的内容是设计并且实现一个基于SSM框架的互联网废品回收。它是在Windows下&#xff0c;以MYSQL为数据库开发平台&#xff0c;Tomcat网络信息服务作为应用服务器。互联网废品回收的功能已基本实现&#xff0c;主要包括用户、回收员、物品分类、回收物品、用户下单…

W、X、Y

W z学长的apex 不等于180度的角的个数就是求转折点的个数 而每个y(x)都是一元函数&#xff0c;按照公式每个一元函数的转折点为 s(x)是若干y(x)的叠加&#xff0c;其中一个y(x)有转折点&#xff0c;在对应位置上s(x)也会有转折点 所以所有y(x)函数中不重复的转折点的个数就是…

Java练习题-键盘录入字符串实现大小写转换

✅作者简介&#xff1a;CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1&#x1f3c6; &#x1f4c3;个人主页&#xff1a;hacker707的csdn博客 &#x1f525;系列专栏&#xff1a;Java练习题 &#x1f4ac;个人格言&#xff1a;不断的翻越一座又…

【LeetCode热题100】--108.将有序数组转换为二叉搜索树

108.将有序数组转换为二叉搜索树 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 二叉搜索树的中序遍历是升序…

扩容LVM卷导致lvm元数据丢失的恢复过程

一、问题描述 因某次MySQL binlog占用过高扩容时&#xff0c;是直接对云盘操作&#xff0c;而扩容直接操作了lvm卷而未操作云盘分区&#xff0c;并随后执行了扩容的partprobe&#xff0c;resize2fs卷等操作&#xff1b;最后&#xff0c;显示并未扩容成功&#xff0c;重启系统后…

008:连续跌三天,买第四天上涨的盈利计算

尽管有连续三天跌&#xff0c;第四天上涨的概率>0.5&#xff0c;但是也不意味着一定会盈利。因为还要看涨跌大幅度。所以&#xff0c;我们应该来假设&#xff0c;于连续跌三天的最后时刻买入&#xff0c;而后第四天临近收盘卖出&#xff0c;看这样的最终盈利是多少。假设我们…