scons_交叉编译arm64_sysroot基于根文件rootfs编译方法

news2024/11/16 15:38:58

文章目录

    • 1.问题现象
    • 2.环境变量
    • 3.实例1:交编译arm64 hello.c
      • 解决方法1: 指定rootfs下的include头文件
      • 解决方法2: 下载开源arm64-linux-gnu-gcc
      • 小结
    • 4.交叉编译依赖第3方库
      • 1.前言
      • 2.小知识: gcc默认搜索与支持的库
      • 3.实例: 交叉编译依赖ROS的程序
        • gcc/g++ 编译流程
        • gcc/g++ 链接流程
    • 5.遇到的问题
      • 1.链接选项--rpath --rpath-link区别
      • 2.scons如何添加--rpath-link
      • 3.scons如何修改链接选项顺序
    • 6.总结
    • 7.未解决疑问, 问题

1.问题现象

  1. 目前使用docker + qemu +arm64 容器编译做编译.
  2. 之前做嵌入式开发, 使用的是传统的arm-linux-gcc 交叉编译, 使用SDK环境, 添加程序和库, 按模版添加Makefile, cmake, config, 具体原理不清.
  3. 最近使用scons替换Makefile, cmake; 发现gcc的 --sysroot 选项, 可以指定rootfs路径,替换默认搜索头文件, 库路径
    • cc编译选项: -I /usr/include -I /usr/include/aarch64-linux-gnu
    • ld链接选项: -L /usr/lib -L /usrlib
  4. 尝试使用传统的交叉编译方法, 编译一下项目.
  5. 解决遗留疑问: 如果交叉编译依赖opencv, openssl, ros等第3方库, 如何配置的问题.

2.环境变量

  • 交叉编译工具路径: /home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/
  • 交叉编译前缀: aarch64-none-linux-gnu-
  • rootfs根文件系统路径: /home/liuj/3_work/6_rk3588_sdk/debian/binary
  • ubuntu软件中心, arm64 交叉编译工具: g++-aarch64-linux-gnu gcc-aarch64-linux-gnu

3.实例1:交编译arm64 hello.c

代码:
1_hello.c

#include <stdio.h>
 
int main()
{
    printf("hello world\n");
    return 0;
}

SConstruct

# 交叉编译工具路径
cross_Tools_Path="/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/"
# 交叉编译工具前缀
cross_Tool_Prefix="aarch64-none-linux-gnu-"
# rootfs路径
rootdir="/home/liuj/3_work/6_rk3588_sdk/debian/binary"

# scons官方交叉编译示例
env_options = {
   "CC"    : cross_Tool_Prefix+"gcc",
   "CXX"   : cross_Tool_Prefix+"g++",
   "LD"    : cross_Tool_Prefix+"ld",
   "AR"    : cross_Tool_Prefix+"ar",
   "STRIP" : cross_Tool_Prefix+"strip",
}
env = Environment(**env_options)
env.AppendENVPath('PATH', cross_Tools_Path)

# 编译选项
env['CCFLAGS'] = "--sysroot=%s "%(rootdir)
# env['CCFLAGS'] += "-I %s/usr/include \
#     -I %s/usr/include/aarch64-linux-gnu \
#     -I %s/usr/include/freetype2 \
#     -I %s//usr/local/include" \
#     %(rootdir,rootdir,rootdir,rootdir)

env.Program('1_hello.c')

运行结果: scons

aarch64-none-linux-gnu-gcc -o 1_hello.o -c --sysroot=/home/liuj/3_work/6_rk3588_sdk/debian/binary 1_hello.c
In file included from 1_hello.c:1:
/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory
27 | #include <bits/libc-header-start.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

编译错误原因:

  • rk3588默认自带编译工具链aarch64-none-linux-gnu-gcc 不支持–sysroot选项

解决方法1: 指定rootfs下的include头文件

SConstruct 取消如下注释

env['CCFLAGS'] += "-I %s/usr/include \
    -I %s/usr/include/aarch64-linux-gnu \
    -I %s/usr/include/freetype2 \
    -I %s//usr/local/include" \
    %(rootdir,rootdir,rootdir,rootdir)

scons编译成功

aarch64-none-linux-gnu-gcc -o 1_hello.o -c --sysroot=/home/liuj/3_work/6_rk3588_sdk/debian/binary -I /home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/include -I /home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/include/aarch64-linux-gnu -I /home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/include/freetype2 -I /home/liuj/3_work/6_rk3588_sdk/debian/binary//usr/local/include 1_hello.c
aarch64-none-linux-gnu-gcc -o 1_hello 1_hello.o

解决方法2: 下载开源arm64-linux-gnu-gcc

ubuntu软件仓库安装arm64交叉编译工具

sudo apt install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu

SConstruct 修改之后如下

import os

cross_Tool_Prefix="aarch64-linux-gnu-"
rootdir="/home/liuj/3_work/6_rk3588_sdk/debian/binary"
env_options = {
   "CC"    : cross_Tool_Prefix+"gcc",
   "CXX"   : cross_Tool_Prefix+"g++",
   "LD"    : cross_Tool_Prefix+"ld",
   "AR"    : cross_Tool_Prefix+"ar",
   "STRIP" : cross_Tool_Prefix+"strip",
}

env = Environment(**env_options)
env['CCFLAGS'] = "--sysroot=%s "%(rootdir)

env.Program('1_hello.c')

编译 scons

aarch64-linux-gnu-gcc -o 1_hello.o -c --sysroot=/home/liuj/3_work/6_rk3588_sdk/debian/binary 1_hello.c
aarch64-linux-gnu-gcc -o 1_hello 1_hello.o

小结

  1. 解决方法1 有一个问题, 编译C++文件错误, 提示找不到头文件, 暂未找到解决方法.
  2. 后续使用 ** 解决方法2** , 目的是验证gcc --sysroot选项做交叉编译功能

4.交叉编译依赖第3方库

1.前言

之前的文章: 搭建交叉编译环境–RK3588示范
遗留一个问题: 如果交叉编译依赖opencv, openssl, ros等第3方库, 改如何配置.

2.小知识: gcc默认搜索与支持的库

  • 交叉编译工具路径: /home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/

查看gcc默认搜索lib库
./aarch64-none-linux-gnu-gcc --print-search-dirs

install:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/lib/gcc/aarch64-none-linux-gnu/10.3.1/
programs:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/libexec/gcc/aarch64-none-linux-gnu/10.3.1/:/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/libexec/gcc/:/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/lib/gcc/aarch64-none-linux-gnu/10.3.1/…/…/…/…/aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu/10.3.1/:/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/lib/gcc/aarch64-none-linux-gnu/10.3.1/…/…/…/…/aarch64-none-linux-gnu/bin/
libraries:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/lib/gcc/aarch64-none-linux-gnu/10.3.1/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/lib/gcc/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/lib/gcc/aarch64-none-linux-gnu/10.3.1/…/…/…/…/aarch64-none-linux-gnu/lib/aarch64-none-linux-gnu/10.3.1/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/lib/gcc/aarch64-none-linux-gnu/10.3.1/…/…/…/…/aarch64-none-linux-gnu/lib/…/lib64/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/aarch64-none-linux-gnu/libc/lib/aarch64-none-linux-gnu/10.3.1/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/aarch64-none-linux-gnu/libc/lib/…/lib64/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/aarch64-none-linux-gnu/libc/usr/lib/aarch64-none-linux-gnu/10.3.1/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/aarch64-none-linux-gnu/libc/usr/lib/…/lib64/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/lib/gcc/aarch64-none-linux-gnu/10.3.1/…/…/…/…/aarch64-none-linux-gnu/lib/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/aarch64-none-linux-gnu/libc/lib/:
/home/liuj/3_work/6_rk3588_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/…/aarch64-none-linux-gnu/libc/usr/lib/

大家可以查看每一个lib库路径;
通过查看, 发现主要是支持libc, libgnuc, stdc++库.
gcc工具自带的lib库

故默认aarch64-linux-gnu-gcc 只能编译: 标准c/c++, kernel, linux系统编程等API 代码

3.实例: 交叉编译依赖ROS的程序

代码
test_uint8_array.cc

#include <stdint.h>
#include <vector>

#include <ros/console.h>
#include <ros/ros.h>
#include <std_msgs/UInt8MultiArray.h>
using namespace std;

int main(int argc, char* argv[])
{
	ros::init(argc, argv, "test_topic");
    ros::NodeHandle n;


    ros::Publisher pub_uint8_array = n.advertise<std_msgs::UInt8MultiArray>("/test/UInt8MultiArray", 5);
    std_msgs::UInt8MultiArray msg_uint8_array;
    // uint8_t data[4] = { 0x1, 0x2, 0x4, 0x8 };
    vector<uint8_t> data = { 0x1, 0x2, 0x4, 0x8 };
    while (ros::ok())
    {
        msg_uint8_array.data = data;
        pub_uint8_array.publish(msg_uint8_array);
        sleep(1);
        ros::spinOnce();
    }

    return 0;
}

SConstruct

import os

cross_Tool_Prefix="aarch64-linux-gnu-"
rootdir="/home/liuj/3_work/6_rk3588_sdk/debian/binary"
env_options = {
   "CC"    : cross_Tool_Prefix+"gcc",
   "CXX"   : cross_Tool_Prefix+"g++",
   "LD"    : cross_Tool_Prefix+"ld",
   "AR"    : cross_Tool_Prefix+"ar",
   "STRIP" : cross_Tool_Prefix+"strip",
   "LINKCOM" : "$LINK -o $TARGET $SOURCES $LD_PREFLAGS $_LIBDIRFLAGS $__RPATH $LINKFLAGS $_LIBFLAGS",
}
env = Environment(**env_options)

# 编译选项
env['CCFLAGS'] = "--sysroot=%s "%(rootdir)
env['CCFLAGS'] += "-I %s/opt/ros/noetic/include "%(rootdir)
env['CPPPATH'] = ["%s/usr/include"%(rootdir),
    "%s/usr/include/aarch64-linux-gnu"%(rootdir),
    "%s/usr/include/freetype2"%(rootdir),
    "%s/usr/local/include"%(rootdir)
    ]

# 链接选项
env['LD_PREFLAGS'] = "--sysroot=%s " %(rootdir)
sys_lib = [rootdir+"/lib",
    rootdir+"/usr/lib",
    rootdir+"/usr/lib/aarch64-linux-gnu",
    rootdir+"/usr/local/lib",
    rootdir+"/lib/aarch64-linux-gnu",
]
ros_lib = [rootdir+'/opt/ros/noetic/lib']

env['LIBPATH'] = sys_lib+ros_lib

dep_lib = ['roscpp','rosconsole']
env['LIBS'] = dep_lib

# env['RPATH'] = ros_lib
env['LINKFLAGS'] = "-Wl,--rpath-link={} ".format(" ".join(ros_lib))
env['LINKFLAGS'] += "-Wl,--copy-dt-needed-entries "

env.Program('test_uint8_array.cc')

scons编译成功

arch64-linux-gnu-g++ -o test_uint8_array.o -c --sysroot=/home/liuj/3_work/6_rk3588_sdk/debian/binary -I /home/liuj/3_work/6_rk3588_sdk/debian/binary/opt/ros/noetic/include -I/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/include -I/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/include/aarch64-linux-gnu -I/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/include/freetype2 -I/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/local/include test_uint8_array.cc
aarch64-linux-gnu-g++ -o test_uint8_array test_uint8_array.o --sysroot=/home/liuj/3_work/6_rk3588_sdk/debian/binary -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/lib -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/lib -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/lib/aarch64-linux-gnu -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/local/lib -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/lib/aarch64-linux-gnu -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/opt/ros/noetic/lib -Wl,--rpath-link=/home/liuj/3_work/6_rk3588_sdk/debian/binary/opt/ros/noetic/lib -Wl,--copy-dt-needed-entries -lroscpp -lrosconsole
scons: done building targets.

美化的流程显示

gcc/g++ 编译流程

gcc-编译指定路径

gcc/g++ 链接流程

gcc-sysroot-指定链接路径

运行测试:
拷贝文件到arm64 开发板, 运行正常.

5.遇到的问题

1.链接选项–rpath --rpath-link区别

一开始使用 env[‘RPATH’], 对应的gcc链接选项为 -Wl,--rpath=xxx_lib_dir
在ld链接时提示错误:

/usr/bin/ld: warning: libxxx.so.6, needed by /a/b/c/libyyy.so, not found (try using -rpath or -rpath-link)

网上搜索到的区别: GCC 中 -L、-rpath和-rpath-link的区别

  • –rpath 1.链接时指定依赖库路径 2.运行时指定链接路径
  • –rpath-link 1.链接时指定依赖库路径

尝试修改为–rpath-link, 如下

-- -Wl,--rpath=/home/liuj/3_work/6_rk3588_sdk/debian/binary/opt/ros/noetic/lib 
++ -Wl,--rpath-link=/home/liuj/3_work/6_rk3588_sdk/debian/binary/opt/ros/noetic/lib \

手动运行g++链接指令, 命令如下

aarch64-linux-gnu-g++ -o test_uint8_array.out test_uint8_array.o \
 --sysroot=/home/liuj/3_work/6_rk3588_sdk/debian/binary   \
 -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/lib   \
 -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/lib   \
 -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/lib/aarch64-linux-gnu   \
 -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/local/lib   \
 -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/lib/aarch64-linux-gnu   \
 -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/opt/ros/noetic/lib \
 -Wl,--rpath-link=/home/liuj/3_work/6_rk3588_sdk/debian/binary/opt/ros/noetic/lib \
 -Wl,--copy-dt-needed-entries \
 -lroscpp -lrosconsole

结果:
手动链接成功

2.scons如何添加–rpath-link

查看官方文档, github下载源代码查看, 没有找到scons设置–rpath-link的选项
解决方法:
使用 LINKFKAGS 设置 --rpath-link

ros_lib = [rootdir+'/opt/ros/noetic/lib']
env['LINKFLAGS'] = "-Wl,--rpath-link={} ".format(" ".join(ros_lib))

编译结果: -->链接错误

aarch64-linux-gnu-g++ -o test_uint8_array -Wl,--rpath-link=/home/liuj/3_work/6_rk3588_sdk/debian/binary/opt/ros/noetic/lib -Wl,--copy-dt-needed-entries test_uint8_array.o -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/lib -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/lib -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/lib/aarch64-linux-gnu -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/usr/local/lib -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/lib/aarch64-linux-gnu -L/home/liuj/3_work/6_rk3588_sdk/debian/binary/opt/ros/noetic/lib -lroscpp -lrosconsole
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find /lib/aarch64-linux-gnu/libc.so.6
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find /usr/lib/aarch64-linux-gnu/libc_nonshared.a
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: cannot find /lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
collect2: error: ld returned 1 exit status
scons: *** [test_uint8_array] Error 1

解决方法:
-Wl选项放在-L选项之后, -->链接通过.

新问题:
如何设置scons ld链接选项顺序

3.scons如何修改链接选项顺序

官方文档 修改编译/链接选项顺序

# cc/gcc 编译选项顺序
CCCOM       = '%CC %CFLAGS %_IFLAGS -c %< -o %>',
# c++/g++ 编译选项顺序
CXXCOM      = '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
# 链接选项顺序
LINKCOM     = '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',

修改LINKCOM 即可修改scons ld链接选项顺序

我的修改如下
SConstruct

# 1.修改 ld选项顺序: 使LINKFLAGS 在 _LIBDIRFLAGS 之后
# 2.自定义 ld前缀选项 LD_PREFLAGS
env_options = {
   "LINKCOM" : "$LINK -o $TARGET $SOURCES $LD_PREFLAGS $_LIBDIRFLAGS $__RPATH $LINKFLAGS $_LIBFLAGS",
}

# 3.定义LD_PREFLAGS
env['LD_PREFLAGS'] = "--sysroot=%s " %(rootdir)

运行scons, 编译链接通过,如文章 3.实例: 交叉编译依赖ROS的程序

6.总结

  • make, cmake, scons本质上是调用gcc/g++ 命令进行编译, 链接. 各种参数选项, 是为了配置gcc/g++选项.
    如本次使用scons, 与手动执行 gcc/g++ 交叉编译链接成功.
    那cmake各种参数设置, 也是为了调整编译/链接选项, 实现手动执行gcc命令的效果.
  • 又一次熟悉了gcc/g++ 编译,链接流程, 交叉编译环境配置.
  • 猜测–rpath-link , 是gcc检查到host x86_64, target arch64, 不能使用–rpath包含路径.

7.未解决疑问, 问题

Q1: 如何打印显示gcc默认include路径?
Q2: 为什么gcc/g++ ld链接选项顺序, 对链接结果有影响?

  • 默认ld链接选项顺序 -Wl,--rpath-link -Llib_dir -llib 失败
  • -Llib_dir -Wl,--rpath-link -llib 成功.
    知道的小伙伴留言一下.

签名
一个喜欢机器人行业的 嵌入式-内核驱动-系统-中间件-网络-开发工程师
微信: liuj1637664504


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

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

相关文章

阿里云双11活动:如何通过客户端连接linux服务器?配置入门详解

前言 最近双11活动&#xff0c;发现阿里云有服务器活动&#xff0c;就买了一个&#xff0c;今天主要给大家介绍下&#xff0c;如何通过通过客户端进行连接linux服务器后&#xff0c;进行简单的操作。 配置服务器信息 打开浏览器登录到阿里云服务器页面上&#xff0c;找到个人…

uni-app/vue封装etc车牌照输入,获取键盘按键键值

先看下效果如下&#xff1a; 动态图如下 uniapp的keyup获取不到keyCode和compositionstart&#xff0c;compositionend&#xff0c;所以需要监听input节点的keyup事件&#xff0c; 思路以及代码如下&#xff1a; 1.将每一个字符用文本框输入&#xff0c;代码如下 <view …

ClickHouse基础知识(二):ClickHouse 安装教程

1. 准备工作 1.1 确定防火墙处于关闭状态 1.2 CentOS 取消打开文件数限制 &#xff08;1&#xff09;在 hadoop101 的 /etc/security/limits.conf 文件的末尾加入以下内容 sudo vim /etc/security/limits.conf&#xff08;2&#xff09;在 hadoop101 的/etc/security/limits.…

64.乐理基础-打拍子-前八后十六、前十六后八拍子

前置内容&#xff1a;63.乐理基础-打拍子-四十六-CSDN博客 前八后十六指的是前半拍是一个八分音符&#xff0c;后半怕是两个十六分音符的节奏型&#xff0c;如图1。 前十六后八刚好就与前八后十六反着&#xff0c;如图3。 图1&#xff1a;在以四分音符为一拍的时候这三个音符加…

Android下载gradle失败解决方法

1、在gradle-wrapper.properties文件中查看自己需要下载gradle什么版本的包和zip路径&#xff08;wrapper/dists&#xff09;。 2、在setting中查看Gradle的保存路径&#xff0c;如下图&#xff1a;C:/Users/Administrator/.gradle&#xff0c;加上第一步的zip路径得到下载grad…

chcp 65001

chcp 65001 DOS,BAT,CMD乱码 转UTF-8&#xff0c;就不会汉字乱码了 936 GBK 65001 UTF-8

C语言中关于if else的理解

if else我们可以理解为 if(条件1) //如果条件1成立 语句1&#xff1b; //执行语句1 else //如果条件1不成立 语句2; //执行语句2 这是一个经典的if els…

Vue Echarts 多折线图只有一条X轴(合并X轴数据并去重排序) - 附完整示例

echarts&#xff1a;一个基于 JavaScript 的开源可视化图表库。 目录 效果 一、介绍 1、官方文档&#xff1a;Apache ECharts 2、官方示例 二、准备工作 1、安装依赖包 2、示例版本 三、使用步骤 1、在单页面引入 echarts 2、指定容器并设置容器宽高 3、数据处理&am…

Word中插入mathtype的行内公式显示不全,设置行距,最小值

Word中插入mathtype的行内公式显示不全 如下图&#xff1a;公式上下被遮住 解决方式&#xff1a; 设置所在段落的行距&#xff1a;最小值--xx磅。同时取消勾选 “如果定义了文档网格&#xff0c;则对齐到网格” 处理后效果&#xff1a;

电子科大软件架构设计——期末复习题集

文章目录 系统分析与设计概述面向对象建模语言系统规划系统需求分析系统架构设计软件建模详细设计与设计模式用户界面设计 系统分析与设计概述 1&#xff0e;下面哪个不是信息系统利益相关者?&#xff08;D) A&#xff0e;客户B&#xff0e;用户 C.开发人员D&#xff0e;监理…

免费SSL证书申请入口

免费SSL证书的优势 a. 低成本 免费SSL证书相对于其他类型的SSL证书来说&#xff0c;无需支付昂贵的费用。对于个人网站、小型企业或预算有限的组织而言&#xff0c;免费SSL证书是一种经济实惠的选择。 b. 提高搜索引擎排名 搜索引擎算法中&#xff0c;对于使用HTTPS协议的网…

Solana 生态铭文跨链桥 Sobit 是何神圣?其场外白名单已达到1200U

在短暂的沉寂&#xff0c;在与 Solana 手机 Saga 联合生态 Meme 币 Bonk 掀起一波 meme 浪潮&#xff0c;以及GPU 计算网路Render network 宣布将从公链Polygon迁往Solana 后&#xff0c;Solana 生态再次迎来爆发。随着 SOL 代币在 12 月暴涨&#xff0c;SOL 也在市值上超越了 …

性能测试-jemeter:安装 / 基础使用

一、理解jemeter 官网-Apache JMeter-Apache JMeter™ JMeter是一款开源的性能测试工具&#xff0c;主要用于模拟大量用户并发访问目标服务器&#xff0c;以评估服务器的性能和稳定性。 JMeter可以执行以下任务序号用途描述1性能测试通过模拟多个用户在同一时间对服务器进行…

python风格规范之missing whitespace after

python风格规范之missing whitespace after 规范错误/警告描述规范错误描述(示例)规范错误认知正确示例 规范错误/警告描述 PEP 8: E231 missing whitespace after [mark]规范错误描述(示例) 规范错误认知 上述规范错误表示"[mark]"后面没有添加空格 。错误示例如下…

第一届能源电子产业创新大赛太阳能光伏赛道在京顺利完成初赛评审

近日&#xff0c;第一届能源电子产业创新大赛太阳能光伏赛道初赛在北京顺利举行。本次太阳能光伏赛道赛事由工业和信息化部产业发展促进中心、宜宾市人民政府主办&#xff0c;宜宾市经济和信息化局、宜宾高新技术产业园区承办&#xff0c;中国国检测试控股集团股份有限公司协办…

C语言之字符串处理

目录 字符串长度 显示字符串 数字字符的出现次数 大小写字符转换 字符串数组的参数传递 非字符串的字符数组 目前我们所学习到的是围绕字符串的处理&#xff0c;仅仅是生成字符串、读取并显示字符串&#xff0c;下面我学习更加灵活处理字符串的方式。 字符串长度 我们来看…

MR实战:统计总分与平均分

文章目录 一、实战概述二、提出任务三、完成任务&#xff08;一&#xff09;准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录 &#xff08;二&#xff09;实现步骤1、创建Maven项目2、添加相关依赖3、创建日志属性文件4、创建成绩映射器类5、创建成绩驱动器类6、启…

单词搜索 II[困难]

一、题目 给定一个m x n二维字符网格board和一个单词&#xff08;字符串&#xff09;列表words&#xff0c; 返回所有二维网格上的单词。单词必须按照字母顺序&#xff0c;通过 相邻的单元格 内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同…

面试官:并发和并行的区别

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…