当前位置: 首页 > news >正文

基于Docker搭建属于你的CC++集成编译环境

常常,我会幻想着拥有一个随时可以携带、随时可以使用的开发环境,那该是多么美好的事情。

在工作中,编译环境的复杂性常常让我头疼不已。稍有不慎,删除了一些关键文件,整个编译链就会瞬间崩溃。更糟糕的是,当我花费大量时间和精力搭建好的环境,不得不在不同的机器上重复这份工作时,心中的焦虑更是无以言表。尤其是当代码需要交给同事处理,如果能将整个环境如同复制粘贴一般简单传递,那将是多么美妙的事。

当然,虚拟机的确可以实现这种“复制粘贴”的效果,但从版本管理、镜像托管和维护的角度来看,其成本却颇高。这样的方案,并不是我心目中理想的选择。于是,我将目光转向了Docker。

一、需求整理

我理想的C/C++编译环境,至少需要具备以下环境或工具:

  1. Conan​: 一个我常用且比较流行的的C/C++包管理工具
  2. CMake​: 最流行的C/C++构建系统
  3. 基础编译环境:gcc​,make​,gdb​等
  4. ARM编译工具链:gcc-arm-none-eabi​, gcc-arm-linux-gnueabihf​, gcc-aarch64-linux-gnu​等
  5. 基础开发库:比如libssl-dev​, libgl-dev​等,这些主要是方便其他上层库的编译

二、Docker简介

image

Docker 是一个容器引擎。对于没有接触过 Docker 的开发者来说可能比较陌生。可以将 Docker 大致理解为一个轻量级虚拟机框架,但实际上它比虚拟机更高效。Docker 具备以下几点特性:

  1. 足够快:Docker 容器启动速度非常快,通常只需要几秒钟。这是因为容器共享主机操作系统的内核,而不像虚拟机需要启动一个完整的操作系统。这种高效性使得开发和测试过程更加顺畅。
  2. 管理方便:Docker 提供了丰富的命令行工具和 API,使得容器的创建、启动、停止和销毁变得非常简单。同时,Docker Compose 允许开发者使用一个简单的 YAML 文件来定义和管理多容器应用,使得部署和管理复杂应用变得更加方便。
  3. 生态好:Docker 拥有庞大且活跃的社区,提供了丰富的镜像资源。通过 Docker Hub,开发者可以方便地下载和分享容器镜像。Docker 还支持与各种 CI/CD 工具、云平台和编排工具(如 Kubernetes)的集成,形成了一个完善的生态系统。
  4. 一致性:Docker 确保应用程序在开发、测试和生产环境中运行的一致性。这意味着开发者可以在本地开发和测试应用程序,然后将相同的容器部署到生产环境中,而不必担心环境差异带来的问题。
  5. 资源高效:与传统的虚拟机相比,Docker 容器更加轻量级,消耗的资源更少。容器共享主机操作系统的内核,避免了虚拟机需要为每个实例分配完整操作系统资源的情况。
  6. 安全隔离:Docker 使用内核命名空间(namespace)和控制组(cgroup)技术提供进程和资源的隔离。这种隔离确保了每个容器之间的安全性,避免了相互干扰。
  7. 可移植性:Docker 容器可以在任何支持 Docker 的系统上运行,无论是本地开发环境、云服务还是数据中心。这种可移植性使得应用程序能够在不同环境之间轻松迁移。

这些特性使得 Docker 成为现代软件开发和部署过程中不可或缺的工具,极大地提高了应用的可移植性和开发效率。在Docker中包含三个基本概念,分别是:

  • 镜像(Image) :Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 容器(Container) :镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository) :仓库可看成一个代码控制中心,用来保存镜像。

Docker 的安装方法不在这里赘述。目前 Docker 发布了 Docker Desktop 软件,这款桌面软件允许用户通过 GUI 来管理 Docker 镜像和容器。对新手来说会比较友好,至于是使用命令行还是 GUI 方式,可根据个人喜好进行选择。

三、DockerFile

FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
COPY ./sources.list /etc/apt/sources.list# Install packages
RUN set -eux \&& apt-get update \&& apt-get -yq upgrade \&& apt-get -yq install \aptitude apt-rdepends bash build-essential ccache clang clang-tidy cppcheck curl doxygen diffstat gawk gdb git gnupg gperf iputils-ping \linux-tools-generic nano nasm ninja-build openssh-server openssl pkg-config python3 python-is-python3 spawn-fcgi net-tools iproute2 \sudo tini unzip valgrind wget zip texinfo gcc-multilib chrpath socat cpio xz-utils debianutils \patch perl tar rsync bc xterm whois software-properties-common apt-transport-https ca-certificates\dh-autoreconf apt-transport-https g++ graphviz xdot mesa-utils \&& exit 0# Install cmake
RUN set -eux \&& wget https://github.com/Kitware/CMake/releases/download/v3.28.5/cmake-3.28.5-linux-x86_64.sh -q -O /tmp/cmake-install.sh \&& chmod u+x /tmp/cmake-install.sh \&& mkdir /opt/cmake-3.28.5 \&& /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-3.28.5 \&& rm /tmp/cmake-install.sh \&& ln -s /opt/cmake-3.28.5/bin/* /usr/local/bin \&& cmake --version \&& exit 0# Install arm compiler
RUN set -eux \&& apt-get update \&& apt-get -yq install \gcc-arm-none-eabi \g++-arm-linux-gnueabi gcc-arm-linux-gnueabi \g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf \g++-aarch64-linux-gnu gcc-aarch64-linux-gnu \&& exit 0# Install python pip
RUN set -eux \&& python3 --version \&& curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \&& python3 get-pip.py \&& rm get-pip.py \&& python3 -m pip install -U pip \&& pip3 --version \&& pip3 install --upgrade pip setuptools wheel \&& pip3 --version \&& exit 0# Install python packages
RUN set -eux \&& pip3 --version \&& pip3 install --upgrade pip setuptools wheel \&& pip3 --version \&& pip3 install --upgrade autoenv autopep8 cmake-format clang-format conan meson \&& pip3 install --upgrade cppclean flawfinder lizard pygments pybind11 GitPython pexpect subunit Jinja2 pylint CLinters \&& exit 0# Install libraries
RUN set -eux \&& apt-get install -yq \libgl-dev libgl1-mesa-dev \libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxext-dev \libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev \libxss-dev libxt-dev libxtst-dev libxv-dev libxxf86vm-dev libxcb-glx0-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev \libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev \libxcb-xinerama0-dev libxcb-dri3-dev uuid-dev libxcb-cursor-dev libxcb-dri2-0-dev libxcb-dri3-dev libxcb-present-dev \libxcb-composite0-dev libxcb-ewmh-dev libxcb-res0-dev libxcb-util-dev libxcb-util0-dev\&& apt-get -yq autoremove \&& apt-get -yq autoclean  \&& apt-get -yq clean  \&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \&& exit 0# Setup ssh
RUN set -eux \&& mkdir -p /var/run/sshd \&& mkdir -p /root/.ssh \&& sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config \&& sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config \&& echo 'root:root' | chpasswd \&& exit 0ENTRYPOINT ["/usr/bin/tini","--"]
CMD ["/usr/sbin/sshd","-D","-e"]

如您所见,我已经写完了一份DockerFile。其中包含了一些基础工具,如网络工具、CMake、Python、ARM交叉编译工具链等。甚至还有一些开发用的基础库,同时也配置好了SSH。点击下方图片查看最新完整代码👇👇👇(欢迎START!!!🤩)

3.1 基础镜像和环境变量设置

FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
COPY ./sources.list /etc/apt/sources.list
  • FROM ubuntu:22.04:指定基础镜像为Ubuntu 22.04。
  • ENV DEBIAN_FRONTEND=noninteractive:设置环境变量,使apt-get在非交互模式下运行,避免提示用户输入。
  • COPY ./sources.list /etc/apt/sources.list:将本地的sources.list文件复制到容器中的/etc/apt/sources.list,这里使用了清华源,如果不要请将此条代码注释掉。

3.2 安装基础软件包

RUN set -eux \&& apt-get update \&& apt-get -yq upgrade \&& apt-get -yq install \aptitude apt-rdepends bash build-essential ccache clang clang-tidy cppcheck curl doxygen diffstat gawk gdb git gnupg gperf iputils-ping \linux-tools-generic nano nasm ninja-build openssh-server openssl pkg-config python3 python-is-python3 spawn-fcgi net-tools iproute2 \sudo tini unzip valgrind wget zip texinfo gcc-multilib chrpath socat cpio xz-utils debianutils \patch perl tar rsync bc xterm whois software-properties-common apt-transport-https ca-certificates\dh-autoreconf apt-transport-https g++ graphviz xdot mesa-utils \&& exit 0
  • set -eux:启用严格模式,打印所有命令,并在出现错误时停止脚本执行。
  • apt-get update:更新包列表。
  • apt-get -yq upgrade:升级所有已安装的包。
  • apt-get -yq install … :安装列出的各种软件包,涵盖编译工具、开发工具、网络工具等。

3.3 安装CMake

RUN set -eux \&& wget https://github.com/Kitware/CMake/releases/download/v3.28.5/cmake-3.28.5-linux-x86_64.sh -q -O /tmp/cmake-install.sh \&& chmod u+x /tmp/cmake-install.sh \&& mkdir /opt/cmake-3.28.5 \&& /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-3.28.5 \&& rm /tmp/cmake-install.sh \&& ln -s /opt/cmake-3.28.5/bin/* /usr/local/bin \&& cmake --version \&& exit 0
  • wget … -O /tmp/cmake-install.sh:下载CMake安装脚本到/tmp目录。
  • chmod u+x /tmp/cmake-install.sh:给予安装脚本执行权限。
  • mkdir /opt/cmake-3.28.5:创建安装目录。
  • /tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-3.28.5:执行安装脚本,跳过许可证,并安装到指定目录。
  • rm /tmp/cmake-install.sh:删除安装脚本。
  • ln -s /opt/cmake-3.28.5/bin/ /usr/local/bin*:创建符号链接,使CMake命令可用。
  • cmake --version:验证CMake安装。

3.4 安装ARM编译器

RUN set -eux \&& apt-get update \&& apt-get -yq install \gcc-arm-none-eabi \g++-arm-linux-gnueabi gcc-arm-linux-gnueabi \g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf \g++-aarch64-linux-gnu gcc-aarch64-linux-gnu \&& exit 0
  • apt-get update:更新包列表。
  • apt-get -yq install … :安装ARM编译器,包括不同架构的编译器,如ARM none-eabi​、ARM Linux-gnueabi​、ARM Linux-gnueabihf​、AArch64 Linux-gnu​。

3.5 安装Python的pip工具

RUN set -eux \&& python3 --version \&& curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \&& python3 get-pip.py \&& rm get-pip.py \&& python3 -m pip install -U pip \&& pip3 --version \&& pip3 install --upgrade pip setuptools wheel \&& pip3 --version \&& exit 0
  • python3 --version:检查Python3版本。
  • curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py:下载pip安装脚本。
  • python3 get-pip.py:安装pip。
  • rm get-pip.py:删除安装脚本。
  • python3 -m pip install -U pip:升级pip。
  • pip3 --version:检查pip版本。
  • pip3 install --upgrade pip setuptools wheel:安装和升级常用的Python包。

3.6 安装Python包

RUN set -eux \&& pip3 --version \&& pip3 install --upgrade pip setuptools wheel \&& pip3 --version \&& pip3 install --upgrade autoenv autopep8 cmake-format clang-format conan meson \&& pip3 install --upgrade cppclean flawfinder lizard pygments pybind11 GitPython pexpect subunit Jinja2 pylint CLinters \&& exit 0
  • pip3 --version:检查pip版本。
  • pip3 install --upgrade pip setuptools wheel:确保pip及其依赖包是最新的。
  • pip3 install --upgrade autoenv autopep8 cmake-format clang-format conan meson:安装开发工具包。
  • pip3 install --upgrade cppclean flawfinder lizard pygments pybind11 GitPython pexpect subunit Jinja2 pylint CLinters:安装其他开发工具包。

3.7 安装其他开发库文件

RUN set -eux \&& apt-get install -yq \libgl-dev libgl1-mesa-dev \libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxext-dev \libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev \libxss-dev libxt-dev libxtst-dev libxv-dev libxxf86vm-dev libxcb-glx0-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev \libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev \libxcb-xinerama0-dev libxcb-dri3-dev uuid-dev libxcb-cursor-dev libxcb-dri2-0-dev libxcb-dri3-dev libxcb-present-dev \libxcb-composite0-dev libxcb-ewmh-dev libxcb-res0-dev libxcb-util-dev libxcb-util0-dev\&& apt-get -yq autoremove \&& apt-get -yq autoclean  \&& apt-get -yq clean  \&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \&& exit 0
  • 这些主要是QT的依赖库,后续也可以自行增加。

3.8 设置SSH

RUN \set -eux && \mkdir -p /var/run/sshd && \mkdir -p /root/.ssh && \sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config && \sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config && \echo 'root:root' | chpasswd && \exit 0
  • mkdir -p /var/run/sshd:创建sshd运行目录。
  • mkdir -p /root/.ssh:创建root用户的SSH目录。
  • sed -ri ‘s/^#?PermitRootLogin\s+.*/PermitRootLogin yes/’ /etc/ssh/sshd_config:允许root用户通过SSH登录。
  • sed -ri ‘s/UsePAM yes/#UsePAM yes/g’ /etc/ssh/sshd_config:禁用PAM。
  • echo ‘root’ | chpasswd:设置root用户密码为’root’。

3.9 入口点和默认命令

ENTRYPOINT ["/usr/bin/tini" "--"]
CMD ["/usr/sbin/sshd" "-D" "-e"]
  • ENTRYPOINT ["/usr/bin/tini" "–"] :使用tini作为init进程,处理信号和子进程。
  • CMD ["/usr/sbin/sshd" "-D" "-e"] :启动sshd服务并保持前台运行。

四、构建镜像

首先,请将第三部分的代码复制将其保存为Dockerfile​文件。如果您需要切换其他APT源(如阿里源、清华源等),请手动到官方镜像站获取相关源地址,并将其保存为sources.list​。这里附上Ubuntu22.04清华镜像源:

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse# 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
# deb-src http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse# 预发布软件源,不建议启用
# deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# # deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse

注意:请使用http而不要用https.

完成后您的文件夹应该为如下布局:

image
接下来请打开您的命令行程序并进入该文件夹,如果您使用的是Windows操作系统,推荐使用Powershell. 键入以下命令,开始构建:

docker buildx build . -t jelin-dev/ubuntu22.04

您可以在控制台中看到构建过程:

[+] Building 218.2s (14/14) FINISHED                                                                     docker:default=> [internal] load build definition from Dockerfile                                                               0.0s=> => transferring dockerfile: 3.77kB                                                                             0.0s=> [internal] load metadata for docker.io/library/ubuntu:22.04                                                    3.5s=> [internal] load .dockerignore                                                                                  0.0s=> => transferring context: 2B                                                                                    0.0s=> [internal] load build context                                                                                  0.0s=> => transferring context: 1.28kB                                                                                0.0s=> [1/9] FROM docker.io/library/ubuntu:22.04@sha256:a6d2b38300ce017add71440577d5b0a90460d0e57fd7aec21dd0d1b0761b  6.9s=> => resolve docker.io/library/ubuntu:22.04@sha256:a6d2b38300ce017add71440577d5b0a90460d0e57fd7aec21dd0d1b0761b  0.0s=> => sha256:2af372c1e2645779643284c7dc38775e3dbbc417b2d784a27c5a9eb784014fb8 424B / 424B                         0.0s=> => sha256:52882761a72a60649edff9a2478835325d084fb640ea32a975e29e12a012025f 2.30kB / 2.30kB                     0.0s=> => sha256:a8b1c5f80c2d2a757adc963e3fe2dad0b4d229f83df3349fbb70e4d12dd48822 29.53MB / 29.53MB                   5.7s=> => sha256:a6d2b38300ce017add71440577d5b0a90460d0e57fd7aec21dd0d1b0761bbfb2 1.13kB / 1.13kB                     0.0s=> => extracting sha256:a8b1c5f80c2d2a757adc963e3fe2dad0b4d229f83df3349fbb70e4d12dd48822                          1.0s=> [2/9] COPY ./sources.list /etc/apt/sources.list                                                                0.1s=> [3/9] RUN     set -eux &&     apt-get update &&     apt-get -yq upgrade &&     apt-get -yq install     aptit  81.2s=> [4/9] RUN set -eux     && wget https://github.com/Kitware/CMake/releases/download/v3.28.5/cmake-3.28.5-linux  13.4s=> [5/9] RUN     set -eux &&     apt-get update &&     apt-get -yq install         gcc-arm-none-eabi         g+  61.0s=> [6/9] RUN     set -eux &&     python3 --version &&     curl https://bootstrap.pypa.io/get-pip.py -o get-pip.p  9.8s=> [7/9] RUN     set -eux &&     pip3 --version &&     pip3 install --upgrade pip setuptools wheel &&     pip3   29.4s=> [8/9] RUN set -eux     && apt-get install -yq         libgl-dev libgl1-mesa-dev         libx11-xcb-dev libfon  5.8s=> [9/9] RUN     set -eux &&     mkdir -p /var/run/sshd &&     mkdir -p /root/.ssh &&     sed -ri 's/^#?PermitRo  0.4s=> exporting to image                                                                                             6.7s=> => exporting layers                                                                                            6.7s=> => writing image sha256:27e12e5d293fc972028bba5e9e488d4ed655ae5d479bd92b4fe1cb0295e6311d                       0.0s=> => naming to docker.io/jelin-dev/ubuntu22.04

构建完成后,您可以通过docker images​查看已有镜像:

REPOSITORY              TAG       IMAGE ID       CREATED              SIZE
jelin-dev/ubuntu22.04   latest    27e12e5d293f   About a minute ago   5.25GB

您可以通过以下命令创建并启动容器:

docker run -itd -p 2201:22 --name test jelin-dev/ubuntu22.04:latest

这样容器就在后台运行了,您可以通过SSH连接到容器,账号密码均为root

五、使用建议

众所周知,C/C++足够底层,以至于其跨平台特性也仅限于代码层面,只能通过使用不同的编译器编译才能实现多平台运行。所以它不像C#、Java、Python等编程语言有官方指定的包管理器,甚至连构建系统也五花八门。jelin-dev​这个镜像挑选了业界主流的C/C++包管理器和构建系统,以及配备了我所涉及到需要交叉编译的工具链,如果您有特殊的需要,您可以自行添加相关环境,再进行构建和使用。

Tap1. Conan包管理数据持久化

jelin-dev​ 镜像中,我使用了 Conan 作为包管理器。建议您在创建容器时将 /root/.conan2​ 文件夹挂载到本地目录中。这些数据很重要,因为 Conan 会将已经下载和编译的库存放在这个文件夹内。如果没有做持久化,那么每次使用都将需要重新构建这些库。

Tap2. 使用CLion

CLion 是一个非常好用的 IDE,功能多样且灵活。它默认使用 CMake 进行构建,并且对 CMake 的支持比其他 IDE 都要强大,配置项目和管理变得非常轻松。除此之外,CLion 还提供了 Conan 插件,可以通过 GUI 方式配置依赖,使用体验非常棒。另外,CLion 对 Docker 的支持也是一大亮点。启动速度极快,几乎感觉不到延迟,使用起来非常顺畅。这些特性让 CLion 成为开发 C++ 项目的理想选择。


相关文章:

基于Docker搭建属于你的CC++集成编译环境

常常,我会幻想着拥有一个随时可以携带、随时可以使用的开发环境,那该是多么美好的事情。 在工作中,编译环境的复杂性常常让我头疼不已。稍有不慎,删除了一些关键文件,整个编译链就会瞬间崩溃。更糟糕的是,…...

如何限制上网行为?上网行为管控软件有什么功能?

上网行为的管理与限制对于保障企业安全、提高员工工作效率以及保护孩子健康成长都显得尤为重要。 上网行为管控软件作为一种专业的工具,在这方面发挥着不可替代的作用。 本文将探讨如何限制上网行为,并介绍上网行为管控软件的主要功能。 一、如何限制上…...

重庆耶非凡科技有限公司的选品师项目靠谱吗?

在跨境电商和零售市场日益繁荣的今天,选品师的角色愈发凸显出其重要性。重庆耶非凡科技有限公司作为一家致力于多元化服务的科技公司,其选品师项目备受关注。那么,重庆耶非凡科技有限公司的选品师项目靠谱吗?接下来,我们将从多个…...

基于Cloudflare/CloudDNS/GitHub使用免费域名部署NewBing的AI服务

部署前准备: Cloudflare 账号 https://dash.cloudflare.com/login CloudDNS 账号 https://www.cloudns.net/ GitHub 账号 https://github.com/Harry-zklcdc/go-proxy-bingai Cloudflare 部署 Worker CloudDNS 获取免费二级域名 GitHub New Bing Ai 项目 https://git…...

redux状态管理用法详解

在React中使用redux,官方要求安装俩个其他插件 - Redux Toolkit 和 react-redux 1.ReduxToolkit (RTK) 官方推荐编写 Redux 逻辑的方式,是一套工具的集合集,简化书写方式 简化 store 的配置方式; 内置 immer 支持…...

细说ARM MCU中的MX_GPIO_Init()函数的实现过程

目录 1、建立.ioc工程 2、 MX_GPIO_Init()函数 (1)MX_GPIO_Init()函数的类型 (2)MX_GPIO_Init()函数中用到的结构体变量 (3)MX_GPIO_Init()函数使能时钟 (4)MX_GPIO_Init()函数…...

【wordpress】网站提示Error establishing a database connection错误代码

Error establishing a database connection错误代码处理方法: 检查数据库连接情况检查数据库账号密码是否正确检查数据库是否开启 总之较大可能是数据库出现了问题...

图书管理系统——Java实现

文章目录 Java实现图书管理系统问题分析框架搭建业务实现项目测试代码演示BookioperationUserMain(默认包) Java实现图书管理系统 学习了前六篇的SE语法,我们现在要用它们实现一个简单的图书管理系统项目,深入了解各个知识点的应…...

Capto 标准版【简体中文+Mac 】

Capto 是一套易于使用的屏幕捕捉、视频录制和视频编辑 Capto-capto安装包-安装包https://souurl.cn/DPhBmP 屏幕录制和教程视频制作 记录整个屏幕或选择的任何特定区域。在创建内容丰富的教程视频时选择显示或隐藏光标。无论您做什么,都可以确保获得高质量的视频。…...

连锁收银系统的五大功能 会员营销是核心

连锁企业的收银系统是其经营管理的关键工具之一,具备多种功能可以帮助企业提高效率、优化服务并实现会员营销。以下是连锁收银系统的五大功能,其中会员营销作为核心功能将在最后详细讨论。 首先,收银系统应具备高效的销售管理功能。这包括商品…...

射频功率限幅器简略

在功率输入保护方面,限幅器是最好用的器件之一,可以保护后级电路不受超限功率的损害,限幅器其实像TVS功能一样,让超过阈值的功率释放到接地上,来达到限制幅度的目的,目前限幅器的限幅幅度大多都大于15dBm,很…...

[备忘] Reboot Linux in python

1.可行的Reboot方法 1.1 修改/etc/sudoers 假定当前用户是mimi,增补这一行: mimi ALL(ALL) NOPASSWD: ALL 这是为了免输指令。 sudoers文件尽量在覆盖前把它的权限改回去: 原始权限 mimidebian-vm:~/test_app$ ls -l /tmp/sudoers -r--r-…...

windows打开工程文件是顺序读写吗

在 Windows 操作系统中,打开和读写工程文件的过程可以是顺序读写,也可以是随机读写,具体取决于使用的软件和文件的性质。以下是一些详细解释: 顺序读写 顺序读写(sequential access)是指按文件中数据的顺…...

【Python】解决Python报错:AttributeError: ‘generator‘ object has no attribute ‘xxx‘

🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…...

【1800】【5.22-5.24】

E1. String Coloring (easy version) E2. String Coloring (hard version) 【细节参考了题解】 题意:序列拆分为最少的若干条不降序列。 思路:简单版可以 n 2 n^2 n2 dp。定义 b o o l d p ( i , j ) bool ~dp(i, j) bool dp(i,j) 表示是否存在方案…...

统计各个商品今年销售额与去年销售额的增长率及排名变化

文章目录 测试数据需求说明需求实现分步解析 测试数据 -- 创建商品表 DROP TABLE IF EXISTS products; CREATE TABLE products (product_id INT,product_name STRING );INSERT INTO products VALUES (1, Product A), (2, Product B), (3, Product C), (4, Product D), (5, Pro…...

华为校招机试 - 矿车运输成本(20240522)

题目描述 露天矿采矿作业的特点是规模大,矿石和废料的移动量达到百万吨,运输成本开销较大,需要寻求一种最优的运输路径节省成本。 已知矿场可以划分成 N * M 的网格图,每个网格存在地形的差异,因此通过不同网格时,成本开销存在差异。 网格有以下 5 种类型: 标志为 S …...

【C++奇技淫巧】CRTP(奇特重现模板模式)

CRTP(Curiously Recurring Template Pattern,奇特重现模版模式),是一种在C中使用模板来实现的设计模式,主要用于实现编译时多态性(静态多态)。这种模式通过类模板和模板继承机制来实现,使得派生…...

web学习笔记(六十一)

目录 如何使用公共组件来编写页面 如何使用公共组件来编写页面 1.导入公共组件nav.vue import Catenav from "/components/nav.vue"; 2.在页面插入子组件 如果使用了setup语法糖此时就可以直接在页面插入 <Catenav ></Catenav>标签&#xff0c; …...

Nginx在Docker中的应用:容器化部署与扩展

在当今的云计算和微服务时代&#xff0c;Docker容器技术因其轻量级、可移植性和可扩展性而受到广泛关注。Nginx&#xff0c;作为一个高性能的HTTP和反向代理服务器&#xff0c;也在Docker中找到了其广泛的应用场景。本文将探讨Nginx在Docker中的容器化部署和扩展策略&#xff0…...

vscode编译和调试wsl环境的c语言程序

直接f5会报错&#xff0c;提示你改一下json文件 launch.json { “version”: “0.2.0”, “configurations”: [ { “name”: “(gdb) Launch”, “type”: “cppdbg”, “request”: “launch”, “program”: “ w o r k s p a c e F o l d e r / a . o u t " , " …...

(CPU/GPU)粒子继承贴图颜色发射

GetRandomInfo节点(复制贴进scratch pad Scripts) Begin Object Class/Script/NiagaraEditor.NiagaraClipboardContent Name"NiagaraClipboardContent_22" ExportPath/Script/NiagaraEditor.NiagaraClipboardContent"/Engine/Transient.NiagaraClipboardConten…...

【C#】 一个窗体能够显示、最小化、最大化、关闭时分别触发方法

在C#的WPF应用程序中&#xff0c;窗体&#xff08;即继承自System.Windows.Window的类&#xff09;能够通过处理以下事件来响应显示、最小化、最大化和关闭操作&#xff1a; 1.显示&#xff1a; 窗体显示时没有直接对应的事件&#xff0c;但你可以通过覆盖OnLoaded方法或订阅…...

pgsql基本操作

查看已经存在的数据库 postgres# \lList of databasesName | Owner | Encoding | Collate | Ctype | Access privileges ----------------------------------------------------------------------postgres | postgres | UTF8 | C | C | runoobdb …...

3d渲染的常用概念和技术,渲染100邀请码1a12

之前我们介绍了3D渲染的基本原理和流程&#xff0c;这次说下几个常用概念和技术。 3D渲染中涉及到很多专业的概念和技术&#xff0c;它们决定了渲染质量和效果&#xff0c;常用的有以下几个。1、光线追踪 光线追踪是一些专业渲染器&#xff08;如V-Ray和Corona等&#xff09;…...

热敏电阻的设计

热敏电阻(NTC)的作用&#xff1a;抑制开机时的浪涌电流。防止开机瞬间产生的浪涌电流损坏后面的元件。 取值依据:根据对开机的脉冲电流&#xff08;浪涌电流&#xff09;小于多少A&#xff1f; 由,这个U是指最大输入电压&#xff0c;I为要求的浪涌电流。 NTC是负温度系数的热…...

macOS上编译android的ffmpeg及ffmpeg.c

1 前言 前段时间介绍过使用xcode和qt creator编译调试ffmepg.c&#xff0c;运行平台是在macOS上&#xff0c;本文拟介绍下android平台如何用NDK编译链编译ffmepg库并使用。 macOS上使用qt creator编译调试ffmpeg.c macOS上将ffmpeg.c编译成Framework 大体思路&#xff1a; 其…...

RxSwift - 实现一个MVVM架构的TableView

文章目录 RxSwift - 实现一个MVVM架构的TableView前沿MVVM架构的Tableview目录结构1、模型&#xff08;Model&#xff09;2、视图模型&#xff08;ViewModel&#xff09;3、视图&#xff08;View&#xff09; 界面效果 RxSwift - 实现一个MVVM架构的TableView 前沿 MVVM架构在…...

在 CentOS 7 上安装并配置 Redis 允许远程连接的详细教程

第一部分&#xff1a;安装 Redis Redis 是一款高性能的键值存储系统&#xff0c;广泛应用于缓存、消息队列及数据库场景。下面是如何在 CentOS 7 系统上安装 Redis 的步骤。 步骤1&#xff1a;安装 EPEL 仓库 EPEL (Extra Packages for Enterprise Linux) 提供了许多 CentOS 默…...

越来越多企业选择开源批发订货系统

在当今竞争激烈的市场环境中&#xff0c;越来越多的企业选择开源批发订货系统来提高运营效率、降低成本并实现业务的数字化转型。以下是开源批发订货系统的四大优势及其重要功能&#xff1a; 首先&#xff0c;开源批发订货系统具有高度的灵活性和定制性。由于其源代码开放&…...

KT6368A双模蓝牙芯片上电到正常发送AT指令或指令复位需要多久

一、简介 KT6368A芯片上电到正常发送AT指令&#xff0c;或者开启蓝牙广播被搜索到&#xff0c;或者指令复位需要多久等等系列问题总结 详细描述 其实这些问题归结到一起&#xff0c;就还是一个问题&#xff0c;芯片上电需要多久的时间 在另外一份文档里面&#xff0c;是有描…...

代码随想录算法训练营第38天 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

代码随想录算法训练营第38天 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯 理论基础自己看到题目的第一想法看完代码随想录之后的想法 链接: 509. 斐波那契数 链接: 70. 爬楼梯 链接: 746. 使用最小花费爬楼梯 理论基础 五部曲&#xff1a; 1.确定dp数组&#xf…...

变现实谈,我要的不是灵光一现,而是真实的实现!——感悟篇

变现要的是行动不是想法 正文时代奇点奇迹 点题以己及人 正文 每当我看到了一个有趣的事情 我会在脑中构思一些想法 会贴合我当下的想要做的事情 比如 在我写下这篇文章之前 我看到了 二战期间的诞生的一个奇迹 可口可乐 我就思考 咦 原来可口可乐居然是在这么个时间点成长…...

Matlab操作Excel筛选指定数据的对应数据

Matlab中在表格中寻找指定汉字&#xff0c;并返回其所在行数&#xff0c; 将该行数的另一列提取出来。 目录 一、前言 二、直接在命令行输出 三、保存筛选数据excel 一、前言 源数据excel&#xff1a; 指定汉子&#xff1a;买&#xff0c;得到下面数据&#xff1a; 二、直接…...

对于C++STL及其时间复杂度的总结

由于本次在山东CCPC邀请赛中&#xff0c;对于堆的时间复杂度记忆不清晰&#xff0c;导致第4题没有做出来&#xff0c;与铜牌失之交臂&#xff0c;故觉应整理STL的时间复杂度。 本文仅整理有用&#xff08;竞赛&#xff09;的stl及其用法&#xff0c;并且不阐述过于基础的内容。…...

Docker搭建FRP内网穿透服务器

使用Docker搭建一个frp内网穿透 在现代网络环境中&#xff0c;由于防火墙和NAT等原因&#xff0c;内网设备无法直接被外网访问。FRP (Fast Reverse Proxy) 是一款非常流行的内网穿透工具&#xff0c;它能够帮助我们将内网服务暴露给外网。本文将介绍如何在Linux服务器上使用Do…...

【NumPy】掌握NumPy的divide函数:执行高效的数组除法操作

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…...

您的虚拟机未能继续运行,原因是遇到一个可纠正的错误。请保留挂起状态并纠正错误,或放弃挂起状态。

镜像&#xff1a;应急响应靶机 错误信息 此虚拟机的处理器所支持的功能不同于保存虑拟机状态的虚拟机的处理器所支持的功能。 从文件"E:\XXX.vmss"还原 CPU 状态时出错。 您的虚拟机未能继续运行&#xff0c;原因是遇到一个可纠正的错误。请保留挂起状态并纠正错误…...

FPGA DMA IP核使用指南

摘要 本文旨在介绍FPGA中DMA(Direct Memory Access)IP核的使用,包括其基本框架、测试代码编写以及仿真波形的分析。DMA是一种允许外围设备直接与内存进行数据交换的技术,无需CPU的介入,从而提高了数据传输的效率。 1. 引言 在现代FPGA设计中,DMA IP核因其…...

【博客20】缤果Matlab串口调试助手V1.0(中级篇)

超级好用的Matlab串口调试助手 开发工具: MATLAB 2024a中文版 (编程语言matlab) -> Matlab APP Designer 目录 前言 一、软件概要&#xff1a; 二、软件界面&#xff1a; 1.App演示 ​ ​---- ◇♣♡♠ ---- 2.其他扩展App展示 ​编辑 三、获取 >> 源码以及G…...

南京威雅学校:2024年度大戏《Tinkerbell(小叮当)》震撼落幕

三天连演三场 两小时十六幕高潮迭起的舞台故事 一百五十余名师生台前幕后全统筹 逾千名观众现场观演 四个城市五大平台同步直播 南京威雅2024年度大戏 《Tinkerbell&#xff08;小叮当&#xff09;》震撼落幕 它以商演级别的舞台设计 宏大而精密的舞台调度 直击心灵的…...

Kotlin 函数

文章目录 函数的定义函数的返回值参数默认值 & 调用时参数指定函数作用域Lambda 表达式匿名函数内联函数扩展函数中缀函数递归函数 & 尾递归函数 函数的定义 函数可以理解成一个小小的加工厂&#xff0c;给入特定的原材料&#xff0c;它就会给出特定的产品。 fun [接…...

动态路由协议实验——RIP

动态路由协议实验——RIP 什么是RIP ​ RIP(Routing Information Protocol,路由信息协议&#xff09;是一种内部网关协议&#xff08;IGP&#xff09;&#xff0c;是一种动态路由选择协议&#xff0c;用于自治系统&#xff08;AS&#xff09;内的路由信息的传递。RIP协议基于…...

数据结构 | 二叉树(基本概念、性质、遍历、C代码实现)

1.树的基本概念 树是一种 非线性 的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。 把它叫做树是因 为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&#xff0c;称为根…...

很多Oracle中的SQL语句在EF中写不出来

很多复杂的Oracle SQL语句在Entity Framework&#xff08;EF&#xff09;中很难直接表达出来。虽然EF提供了一种方便的方式来使用C#代码查询和操作数据库&#xff0c;但它在处理某些复杂的SQL特性和优化时可能会有局限性。 以下是一些在EF中可能难以直接实现的Oracle SQL功能和…...

浏览器打开PHP文件弹出下载而不是运行代码

说明 使用phpstudy&#xff0c;极少会出现这种情况。 这里主要是帮助大家理解&#xff0c;为什么上传的木马不运行。 问题原因 首先需要理解&#xff0c;访问PHP文件弹出下载&#xff0c;说明服务端的容器&#xff08;比如Apache或者Nginx&#xff09;把文件当成了一个普通二…...

安卓自定义UI组件开发流程

安卓自定义ui组件开发流程 开发安卓自定义UI组件的流程大致可以分为以下几个步骤&#xff1a; 确定需求和设计&#xff1a; 确定需要自定义的UI组件的功能和外观。设计组件的交互逻辑和视觉效果。 创建自定义组件类&#xff1a; 创建一个新的Java类&#xff0c;继承自View、V…...

【LINUX】LINUX基础(目录结构、基本权限、基本命令)

文章目录 LINUX的目录结构LINUX的基本权限LINUX基本命令 LINUX的目录结构 /&#xff1a;表示根目录bin&#xff1a;存放二进制可执行文件(命令ls、cat、mkdir等)boot&#xff1a;存放系统引导文件dev&#xff1a;存放设备文件etc&#xff1a;存放系统配置文件home&#xff1a;…...

Aigtek功率放大器的主要性能要求有哪些

功率放大器是电子系统中的重要组件&#xff0c;用于将低功率信号放大到高功率水平。功率放大器的性能直接影响到信号的放大质量和系统的整体性能。下面西安安泰将介绍功率放大器的主要性能要求。 增益&#xff1a;功率放大器应当具有足够的增益&#xff0c;即将输入信号的幅度放…...

2024.5.29晚训参考代码

因为本套题没有BFS例题&#xff0c;所以我先把BFS模板放着 #include<bits/stdc.h> using namespace std; int n,m;//n*m的棋盘 int dis[402][402]; bool vis[402][402]; int X[]{-2,-2,-1,-1,1,1,2,2};//偏移量的表 int Y[]{-1,1,-2,2,-2,2,-1,1};//定义一个数组&…...