bazel的详细使用教程

由于CSDN;复制近来的mk笔记格式太乱 建议看这个pdf文档
https://download.csdn.net/download/qq_41537499/89512254

为什么要学习bazel?

  1. 从Android 14开始,Google仍然强烈建议开发者使用Bazel和Kleaf构建Android内核及其工件。这表明Bazel在特定领域(如内核模块构建)的应用得到了推广和加强。
  2. 编译流程:截止到Android 13,大部分配置文件还是Android.bp,通过Soong解析成Ninja文件。而来到Android 14,Bazel的解析流程会被加入进来,使得Bazel在编译过程中的应用更为深入。
  3. 官方支持:对于独立应用开发,大多数开发者更习惯于使用build.gradle。不过,随着Google逐渐扩大Bazel在Android框架代码中的应用范围,未来可能会有更多的官方支持和文档来指导开发者使用Bazel进行Android开发

0.简介

Bazel是一个开源的构建工具,用于自动化软件构建过程。它主要用于构建大型、复杂的项目,如Google的内部项目和开源项目。Bazel使用一种名为Starlark的高级编程语言来描述构建规则,这使得构建过程更加灵活和可扩展。

Bazel的主要特点包括:

  1. 高度可扩展:Bazel允许用户自定义构建规则,以满足各种项目的特定需求。
  2. 跨平台支持:Bazel可以在多种操作系统上运行,包括Linux、macOS和Windows。
  3. 高性能:Bazel通过并行构建和缓存机制,提高了构建速度。
  4. 依赖管理:Bazel可以自动处理项目的依赖关系,确保正确的构建顺序。
  5. 持续集成:Bazel与持续集成系统(如Jenkins、Travis CI等)无缝集成,方便进行自动化构建和测试。

要开始使用Bazel,首先需要安装Bazel二进制文件,然后创建一个名为WORKSPACE的文件,其中包含项目的元数据和依赖项。接下来,编写一个或多个名为BUILD的文件,其中包含构建规则。最后,使用bazel build命令构建项目。
bazel官网
https://bazel.google.cn/?hl=zh-cn
需要环境:
linux(Ubuntu)
zip、unzip
C++ 构建工具链
JDK.版本 21
Python。支持版本 2 和 3,安装其中一个就足够了。
例如,在 Ubuntu Linux 上,您可以使用以下命令安装这些要求:
sudo apt-get install build-essential openjdk-21-jdk python zip unzip

安装:

所有操作环境是在ubuntu下面
安装教程地址:https://bazel.google.cn/install/ubuntu?hl=zh-cn
推荐使用二进制安装程序
下载地址:
https://github.com/bazelbuild/bazel/releases

sudo apt install g++ unzip zip
#安装jdk
sudo apt-get install default-jdk
#下载bazel
wget https://github.com/bazelbuild/bazel/releases/download/7.2.0/bazel-7.2.0-installer-linux-x86_64.sh
#加执行权限
chmod +x bazel-version-installer-linux-x86_64.sh
#配置环境变量
vim ~/.bashrc
export PATH=“ P A T H : PATH: PATH:HOME/bin”
#执行安装
./bazel-version-installer-linux-x86_64.sh --user
–user 标志将 Bazel 安装到系统上的 $HOME/bin 目录中,并将 .bazelrc 路径设置为 $HOME/.bazelrc。使用 --help 命令可查看其他安装选项。
#查看版本
root@zyp:/opt/test_Cmake/lib/build# bazel --version
bazel 7.2.0

下载Demo示例

git clone https://github.com/bazelbuild/examples
这个Demo里面有C++、Java、Android等示例
Demo目录内容
root@zyp:/opt/test_bazel/examples# ll
总计 13580
drwxr-xr-x 17 root root 4096 7月 1 17:37 ./
drwxr-xr-x 3 root root 4096 7月 1 15:54 …/
drwxr-xr-x 7 root root 4096 7月 1 15:54 android/
-rw-r–r-- 1 root root 333 7月 1 15:54 AUTHORS
-rwxr-xr-x 1 root root 13788864 7月 1 17:37 bazel-7.2.0-installer-linux-x86_64.sh*
drwxr-xr-x 2 root root 4096 7月 1 15:54 .bazelci/
drwxr-xr-x 9 root root 4096 7月 1 15:54 bzlmod/
-rw-r–r-- 1 root root 381 7月 1 15:54 CODEOWNERS
drwxr-xr-x 12 root root 4096 7月 1 15:54 configurations/
-rw-r–r-- 1 root root 1685 7月 1 15:54 CONTRIBUTING.md
-rw-r–r-- 1 root root 779 7月 1 15:54 CONTRIBUTORS
drwxr-xr-x 6 root root 4096 7月 1 15:54 cpp-tutorial/
drwxr-xr-x 2 root root 4096 7月 1 15:54 flags-parsing-tutorial/
drwxr-xr-x 7 root root 4096 7月 1 15:54 frontend/
drwxr-xr-x 8 root root 4096 7月 1 15:54 .git/
drwxr-xr-x 2 root root 4096 7月 1 15:54 .github/
-rw-r–r-- 1 root root 107 7月 1 15:54 .gitignore
drwxr-xr-x 3 root root 4096 7月 1 15:54 java-maven/
drwxr-xr-x 3 root root 4096 7月 1 15:54 java-tutorial/
-rw-r–r-- 1 root root 11358 7月 1 15:54 LICENSE.txt
drwxr-xr-x 3 root root 4096 7月 1 15:54 make-variables/
-rw-r–r-- 1 root root 478 7月 1 15:54 .pre-commit-config.yaml
drwxr-xr-x 3 root root 4096 7月 1 15:54 query-quickstart/
-rw-r–r-- 1 root root 2688 7月 1 15:54 README.md
-rw-r–r-- 1 root root 320 7月 1 15:54 renovate.json
drwxr-xr-x 20 root root 4096 7月 1 15:54 rules/
drwxr-xr-x 3 root root 4096 7月 1 15:54 third-party-dependencies/

3.运行C++

https://bazel.google.cn/start/java?hl=zh-cn
编译stage1
git clone https://github.com/bazelbuild/examples

结构
examples
└── cpp-tutorial
├──stage1
│ ├── main
│ │ ├── BUILD
│ │ └── hello-world.cc
│ └── WORKSPACE
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── WORKSPACE
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── WORKSPACE
#编译stage1
cd cpp-tutorial/stage1
bazel build //main:hello-world
#会生成以下内容
Starting local Bazel server and connecting to it…
INFO: Analyzed target //main:hello-world (85 packages loaded, 6529 targets configured).
INFO: Found 1 target…
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 24.589s, Critical Path: 0.34s
INFO: 6 processes: 4 internal, 2 linux-sandbox.
INFO: Build completed successfully, 6 total actions

bazel-bin/main/hello-world
输出:
Hello world
Tue Jul 2 14:01:27 2024

stage1的hello-world.cc

#include
#include
#include

std::string get_greet(const std::string& who) {
return "Hello " + who;
}

void print_localtime() {
std::time_t result = std::time(nullptr);
std::cout << std::asctime(std::localtime(&result));
}

int main(int argc, char** argv) {
std::string who = “world”;
if (argc > 1) {
who = argv[1];
}
std::cout << get_greet(who) << std::endl;
print_localtime();
return 0;
}

#cpp-tutorial/stage1/main 目录中的 BUILD 文件
cc_binary(
name = “hello-world”,
srcs = [“hello-world.cc”],
)
hello-world 目标实例化 Bazel 的内置 cc_binary rule。
该规则会指示 Bazel 从没有依赖项的 hello-world.cc 源文件构建独立的可执行二进制文件

编译stage2
cpp-tutorial/stage2/main 目录中的 BUILD 文件

cc_library(
name = “hello-greet”,
srcs = [“hello-greet.cc”],
hdrs = [“hello-greet.h”],
)

cc_binary(
name = “hello-world”,
srcs = [“hello-world.cc”],
deps = [
“:hello-greet”,
],
)
使用此 BUILD 文件后,Bazel 会先构建 hello-greet 库(使用 Bazel 的内置 cc_library rule),
然后再构建 hello-world 二进制文件。hello-world 目标中的 deps 属性告知 Bazel,
必须使用 hello-greet 库才能构建 hello-world 二进制文件
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage2# ll
总计 56
drwxr-xr-x 3 root root 4096 7月 2 10:12 ./
drwxr-xr-x 6 root root 4096 7月 1 15:54 …/
lrwxrwxrwx 1 root root 105 7月 2 10:12 bazel-bin -> /root/.cache/bazel/_bazel_root/9e74109a65c3535de4ae1a422daa22e6/execroot/_main/bazel-out/k8-fastbuild/bin/
lrwxrwxrwx 1 root root 88 7月 2 10:12 bazel-out -> /root/.cache/bazel/_bazel_root/9e74109a65c3535de4ae1a422daa22e6/execroot/_main/bazel-out/
-rw-r–r-- 1 root root 327 7月 1 15:54 .bazelrc
lrwxrwxrwx 1 root root 78 7月 2 10:12 bazel-stage2 -> /root/.cache/bazel/_bazel_root/9e74109a65c3535de4ae1a422daa22e6/execroot/_main/
lrwxrwxrwx 1 root root 110 7月 2 10:12 bazel-testlogs -> /root/.cache/bazel/_bazel_root/9e74109a65c3535de4ae1a422daa22e6/execroot/_main/bazel-out/k8-fastbuild/testlogs/
drwxr-xr-x 2 root root 4096 7月 1 15:54 main/
-rw-r–r-- 1 root root 399 7月 2 10:05 MODULE.bazel
-rw-r–r-- 1 root root 9514 7月 2 10:12 MODULE.bazel.lock
-rw-r–r-- 1 root root 645 7月 1 15:54 README.md
-rw-r–r-- 1 root root 651 7月 1 15:54 WORKSPACE
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage2# bazel-bin/main/hello-world
Hello world

4.运行java

cd examples/java-tutorial
#目录结构
java-tutorial
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── cmdline
│ │ ├── BUILD
│ │ └── Runner.java
│ ├── Greeting.java
│ └── ProjectRunner.java
└── MODULE.bazel

bazel build //:ProjectRunner
bazel-bin/ProjectRunner
输出 Hi
#java-tutorial/BUILD
java_binary(
name = “ProjectRunner”,
srcs = glob([“src/main/java/com/example/*.java”]),
)
ProjectRunner 目标实例化了 Bazel 的内置 java_binary 规则。该规则会告知 Bazel 构建 .jar 文件和封装容器 Shell 脚本(均以目标命名)。

目标中的属性明确声明了其依赖项和选项。虽然 name 属性是必需的,但许多属性是可选的。例如,在 ProjectRunner 规则目标中,name 是目标的名称,
srcs 指定 Bazel 用于构建目标的源文件,main_class 指定包含主方法的类。(您可能已经注意到,我们的示例使用 glob 将一组源文件传递给 Bazel,而不是逐个列出它们。
输出
root@zyp:/opt/test_bazel/examples/java-tutorial# bazel build //:ProjectRunner
Starting local Bazel server and connecting to it…
WARNING: --enable_bzlmod is set, but no MODULE.bazel file was found at the workspace root. Bazel will create an empty MODULE.bazel file. Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel. For more details, please refer to https://github.com/bazelbuild/bazel/issues/18958.
INFO: Analyzed target //:ProjectRunner (92 packages loaded, 1493 targets configured).
INFO: From Building ProjectRunner.jar (2 source files):
warning: [options] source value 8 is obsolete and will be removed in a future release
warning: [options] target value 8 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
INFO: Found 1 target…
Target //:ProjectRunner up-to-date:
bazel-bin/ProjectRunner
bazel-bin/ProjectRunner.jar
INFO: Elapsed time: 260.100s, Critical Path: 1.54s
INFO: 8 processes: 5 internal, 2 linux-sandbox, 1 worker.
INFO: Build completed successfully, 8 total actions
root@zyp:/opt/test_bazel/examples/java-tutorial# bazel-bin/ProjectRunner
Hi!

总结
root@zyp:/opt/test_bazel/examples/java-tutorial/src/main/java/com/example# ll
总计 20
drwxr-xr-x 3 root root 4096 7月 1 15:54 ./
drwxr-xr-x 3 root root 4096 7月 1 15:54 …/
drwxr-xr-x 2 root root 4096 7月 1 15:54 cmdline/
-rw-r–r-- 1 root root 122 7月 1 15:54 Greeting.java
-rw-r–r-- 1 root root 130 7月 1 15:54 ProjectRunner.java
root@zyp:/opt/test_bazel/examples/java-tutorial/src/main/java/com/example# cat Greeting.java
package com.example;

public class Greeting {
public static void sayHi() {
System.out.println(“Hi!”);
}
}
root@zyp:/opt/test_bazel/examples/java-tutorial/src/main/java/com/example# cat ProjectRunner.java
package com.example;

public class ProjectRunner {
public static void main(String args[]) {
Greeting.sayHi();
}
}

在java目录下src/main/com/example下有两个java文件,代码如上 、
ProjectRunner是程序入口 通过调用Greeting 中的sayHi()方法 输出Hi

5.运行Android

cd examples/android/tutorial
目录结构
.
├── README.md
└── src
└── main
├── AndroidManifest.xml
└── java
└── com
└── example
└── bazel
├── AndroidManifest.xml
├── Greeter.java
├── MainActivity.java
└── res
├── layout
│ └── activity_main.xml
└── values
├── colors.xml
└── strings.xml

bazel info workspace

运行报错 解决方法

ERROR: The ‘info’ command is only supported from within a workspace (below a directory having a WORKSPACE file).

root@zyp:/opt/test_bazel/examples/android/tutorial/# touch WORKSPACE
root@zyp:/opt/test_bazel/examples/android/tutorial/# vim WORKSPACE
android_sdk_repository(name = “androidsdk”)
#配置sdk路径
echo “export ANDROID_HOME=$HOME/home/zyp/Android/Sdk” >> ~/.bashrc

root@zyp:/opt/test_bazel/examples/android# bazel info workspace
/opt/test_bazel/examples/android/tutorial/
能输出路径即ok

android_library
在 src/main/java/com/example/bazel 目录中创建一个新的 BUILD 文件,在BUILD中定义如何编译
java源代码,如何处理资源文件生成APK,例如声明一个新的 android_library 规则来编译java源代码:
src/main/java/com/example/bazel/BUILD:
package(
default_visibility = [“//src:subpackages”],
)

android_library(
name = “greeter_activity”,
srcs = [
“Greeter.java”,
“MainActivity.java”,
],
manifest = “AndroidManifest.xml”,
resource_files = glob([“res/**”]),
)

定义一个android_binary 规则来编译整个应用:
android_binary规则为应用构建 Android 应用软件包(.apk)。生成的apk位于bazel-bin下
在 src/main/ 目录中创建一个新的 BUILD 文件,并声明一个新的 android_binary 目标:
android_binary(
name = “app”,
manifest = “AndroidManifest.xml”,
deps = [“//src/main/java/com/example/bazel:greeter_activity”],
)

构建
bazel build //src/main:app
//https://maven.google.com/com/android/tools/r8/8.3.37/r8-8.3.37.jar
bazel mobile-install //src/main:app

Bazel还支持自动化测试和部署。
bazel test命令运行单元测试,并通过bazel run命令运行应用。
此外,还可以使用bazel mobile-install命令将应用安装到连接的Android设备上
名称 位置
Android 清单文件 src/main/AndroidManifest.xml和src/main/java/com/example/bazel/AndroidManifest.xml
Android 源文件 src/main/java/com/example/bazel/MainActivity.java和Greeter.java
资源文件目录 src/main/java/com/example/bazel/res/
…/android/tutorial下的目录结构
root@zyp:/opt/test_bazel/examples/android/tutorial/bazel-tutorial# ll
总计 12
drwxr-xr-x 3 root root 4096 7月 2 14:31 ./
drwxr-xr-x 3 root root 4096 7月 2 13:42 …/
drwxr-xr-x 4 root root 4096 7月 2 14:31 bazel-out/
lrwxrwxrwx 1 root root 54 7月 2 14:31 MODULE.bazel -> /opt/test_bazel/examples/android/tutorial/MODULE.bazel
lrwxrwxrwx 1 root root 59 7月 2 14:31 MODULE.bazel.lock -> /opt/test_bazel/examples/android/tutorial/MODULE.bazel.lock
lrwxrwxrwx 1 root root 51 7月 2 14:31 README.md -> /opt/test_bazel/examples/android/tutorial/README.md
lrwxrwxrwx 1 root root 45 7月 2 14:31 src -> /opt/test_bazel/examples/android/tutorial/src/
lrwxrwxrwx 1 root root 51 7月 2 14:31 WORKSPACE -> /opt/test_bazel/examples/android/tutorial/WORKSPACE

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Gradle学习-5 发布二进制插件

注&#xff1a;以下示例基于Gradle8.0 1、发布插件 复制一分 buildSrc&#xff0c;执行命令行&#xff0c;生成一个新目录 leon-gradle-plugin cp -rf buildSrc leon-gradle-plugin在 leon-gradle-plugin 目录下的 build.gradle 中引入maven plugins{// 引用 Groovy 插件&…

【热部署】✈️Springboot 项目的热部署实现方式

目录 &#x1f378;前言 &#x1f37b;一、热部署和手动重启 &#x1f37a;二、热部署的实现 2.1 手动启动热部署 2.2 自动检测热部署 2.3 关闭热部署 &#x1f49e;️三、章末 &#x1f378;前言 小伙伴们大家好&#xff0c;书接上文&#xff0c;通过Springboot 中的 actu…

解析Kotlin中扩展函数与扩展属性【笔记摘要】

1.扩展函数 1.1 作用域&#xff1a;扩展函数写的位置不同&#xff0c;作用域就也不同 扩展函数可以写成顶层函数&#xff08;Top-level Function&#xff09;&#xff0c;此时它只属于它所在的 package。这样你就能在任何类里使用它&#xff1a; package com.rengwuxianfun …

zabbix“专家坐诊”第244期问答

问题一 Q&#xff1a;请教一下&#xff0c;我的zabbix6.0配置的基于snmptrap上报的日志提取关键字推送告警&#xff0c;正则表达式能否帮忙看看怎么弄&#xff1f;我这配置的提示一直不正确&#xff1f; A&#xff1a;具体看一下这里的信息。 Q&#xff1a;这个我是直接复制的…

如何计算弧线弹道的落地位置

1&#xff09;如何计算弧线弹道的落地位置 2&#xff09;Unity 2021 IL2CPP下使用Protobuf-net序列化报异常 3&#xff09;编译问题&#xff0c;用Mono可以&#xff0c;但用IL2CPP就报错 4&#xff09;Wwise的Bank在安卓上LoadBank之后&#xff0c;播放没有声音 这是第393篇UWA…

ssm旅游信息分享网站-计算机毕业设计源码92194

目录 1 绪论 1.1 研究背景 1.2研究意义 1.3论文结构与章节安排 2 旅游信息分享网站分析 2.1 可行性分析 2.2 系统功能分析 2.3 系统用例分析 2.4 系统流程分析 2.5本章小结 3 旅游信息分享网站总体设计 3.1 系统功能模块设计 3.2 数据库设计 3.4本章小结 4 旅游信…

从全连接到卷积

一、全连接到卷积 1、卷积具有两个原则&#xff1a; 平移不变性&#xff1a;无论作用在哪个部分&#xff0c;它都要有相同的作用&#xff0c;而不会随着位置的改变而改变 局部性&#xff1a;卷积核作用处&#xff0c;作用域应该是核作用点的周围一小部分而不作用于更大的部分 …

一篇文章搞懂弹性云服务器和轻量云服务器的区别

前言 在众多的云服务器类型中&#xff0c;弹性云服务器和轻量云服务器因其各自的特点和优势&#xff0c;受到了广大用户的青睐。那么&#xff0c;这两者之间到底有哪些区别呢&#xff1f;本文将为您详细解析。 弹性云服务器&#xff1a;灵活多变的计算资源池 弹性云服务器&…

【计算机体系结构】缓存的false sharing

在介绍缓存的false sharing之前&#xff0c;本文先介绍一下多核系统中缓存一致性是如何维护的。 目前主流的多核系统中的缓存一致性协议是MESI协议及其衍生协议。 MESI协议 MESI协议的4种状态 MESI协议有4种状态。MESI是4种状态的首字母缩写&#xff0c;缓存行的4种状态分别…

CoAtNet(NeurIPS 2023, Google)论文解读

paper&#xff1a;CoAtNet: Marrying Convolution and Attention for All Data Sizes third-party implementation&#xff1a;https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/maxxvit.py 背景 自AlexNet以来&#xff0c;ConvNets一直是计算机…

【接口自动化测试】第四节.实现项目核心业务的单接口自动化测试

文章目录 前言一、登录单接口自动化测试 1.1 登录单接口文档信息 1.2 登录成功 1.3 登录失败&#xff08;用户名为空&#xff09;二、数据驱动的实现 2.1 json文件实现数据驱动三、课程添加单接口自动化测试 3.1 课程添加单接口文档信息 3.2 课程…

N5 使用Gensim库训练Word2Vec模型

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊# 前言 前言 这周学习训练一个Word2Vec模型&#xff0c;并进行一些基本的词向量操作。 Word2Vec 模型 Word2Vec 是一种基于神经网络的词向量表示方法&#x…

Qt Q_ASSERT详解

Q_ASSERT详解 引言一、基本用法二、深入了解三、参考链接 引言 Q_ASSERT是 Qt 框架中的一个宏&#xff0c;用于在调试时检查某个条件是否为真。它是程序调试中的一个重要工具&#xff0c;有助于开发者在开发过程中及时发现并修复潜在的错误。 一、基本用法 只在使用 Qt 的 D…

API 授权最佳实践

API&#xff08;应用程序编程接口&#xff09;就像秘密之门&#xff0c;允许不同的软件程序进行通信。但并不是每个人都应该拥有每扇门的钥匙&#xff0c;就像不是每个软件都应该不受限制地访问每个 API 一样。 这些 API 将从银行的移动应用程序到您最喜欢的社交媒体平台的所有…

嵌入式C语言中指针与链表的关系详解

假定给你一块非常小的内存,这块内存只有8字节,这里也没有高级语言,没有操作系统,你操作的数据单位是单个字节,你该怎样读写这块内存呢? 注意这里的限定,再读一遍,没有高级语言,没有操作系统,在这样的限制之下,你必须直面内存读写的本质。 这个本质是什么呢? 本质…

Vuex的基本使用

1.安装vuex npm i vuex3 2.引入 import Vuex from vuex 3.使用 Vue.use(Vuex) 4.在src下的目录创建store&#xff0c;新建index.js import store from ./store 5.编写index.js import Vue from vue import Vuex from vuex Vue.use(Vuex)//用于操作组件中的动作 const actions{a…

Linux安装Node-RED并实现后台运行及开机启动

首先确保系统中已近成功安装Node.js&#xff0c;并保证需要的合适版本&#xff1a; 关于node.js的安装可以参考我的另一篇博文:《AliyunOS安装Node.js》。 然后就可以使用npm工具安装Node-RED了&#xff0c;很简单使用如下命令&#xff1a; sudo npm install -g --unsafe-per…

antd Select前端加模糊搜索

背景&#xff1a;前端的小伙伴经常在开发antd Select的时候后端不提供搜索模糊搜索接口&#xff0c;而是全量返回数据&#xff0c;这个时候就需要我们前端自己来写一个模糊搜索了。 效果 代码截图 代码 <SelectshowSearchmode"multiple"options{studioList}filte…

视频分析、目标检测的过去和未来:目标检测从入门到精通 ------ YOLOv8 到 多模态大模型处理视觉基础任务

文章大纲 计算机视觉项目的关键步骤目标检测入门视频分析项目最佳实践数据集构建数据准备:数据集标注规范与数据规模参考标注工具标注工具:目标检测yolo 极简标注工具综合标注工具:label-studio半自动标注工具:X-AnyLabeling目标检测与多模态哪些多模态模型可以做目标检测?…

构建安全稳定的应用:Spring Security 实用指南

前言 在现代 Web 应用程序中&#xff0c;安全性是至关重要的一个方面。Spring Security 作为一个功能强大且广泛使用的安全框架&#xff0c;为 Java 应用程序提供了全面的安全解决方案。本文将深入介绍 Spring Security 的基本概念、核心功能以及如何在应用程序中使用它来实现…