2022年1月

个人网站上搭建了有Blog、Git等服务,均是通过nginx反代,以子目录形式提供服务。因此这些服务是可以共用一个https证书的。

而cloudreve就麻烦了,目前没有找到以子目录形式提供服务的办法,只能先以子域名的方式搭建。

证书的申请也得添加一个子域名证书,好在acme.sh申请Let's Encrypt时,支持多域名证书。

申请了Let's Encrypt后,关键是后续要定时更新,而cloudreve服务也不能停,因此只能在nginx的配置上想办法了。

如下是cloudreve在nginx的反代配置,应该支持同时运行cloudreve服务、证书在后台自动续期。

server {
    listen 80;
    listen [::]:80;
    server_name cloudreve.XXX.cn;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl      http2;
    listen [::]:443 ssl http2;
    server_name cloudreve.XXX.cn;

    include /YYY/etc/nginx/sites-conf/https.conf;
    include /YYY/etc/nginx/sites-conf/common.conf;
	
	# 支持Let's Encrypt申请证书 
    location ^~ /.well-known {
	    # 使用与主网站一样的路径
		root  /YYY/web;
        location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }
        return 404;
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:5212;

        # 如果您要使用本地存储策略,请将下一行注释符删除,并更改大小为理论最大文件尺寸
        # client_max_body_size 20000m;
    }
}

 

Git的交叉编译

gitea的服务启动是不依赖于Git的。但在初始化时会检测Git程序是否存在,同时也是创建、克隆仓库所必需。

默认安装系统提供的Git库也是可行,但依赖很多,感觉很不实在。

因此直接从官方下载源代码过来,交叉编译一个定制版本出来。

1.环境

Host环境:Ubuntu 18.04.5 (PC)

编译工具链:arm-himix200-linux(解包自arm-himix200-linux.tgz,据说来自Hi3516dv300SDK),海思提供的arm编译工具链

环境变量:执行命令:export PATH=/opt/hisi-linux/x86-arm/arm-himix200-linux/bin:$PATH

编译器arm-himix200-linux默认输出的ELF格式为private flags = 5000200: [Version5 EABI] [soft-float ABI],与ubuntu-armhf的格式private flags = 5000400: [Version5 EABI] [hard-float ABI]不兼容(soft-float ABI与hard-float ABI的传参规则不一样,因此会不兼容)。

通过gcc的print-multi-lib查询

xxx@xxx-HP-ProDesk-480-G5-MT:~/BigEye$ arm-himix200-linux-gcc --print-multi-lib
.;
armv5te_arm9;@mcpu=arm926ej-s
a9;@mcpu=cortex-a9
a7;@mcpu=cortex-a7
a17;@mcpu=cortex-a17
a17_a7;@mcpu=cortex-a17.cortex-a7
a53;@mcpu=cortex-a53
a73;@mcpu=cortex-a73
a73_a53;@mcpu=cortex-a73.cortex-a53
armv5te_arm9_soft;@mcpu=arm926ej-s@mfloat-abi=soft
armv5te_arm9_vfp;@mcpu=arm926ej-s@mfloat-abi=softfp@mfpu=vfp
a9_soft;@mcpu=cortex-a9@mfloat-abi=soft
a9_softfp_vfp;@mcpu=cortex-a9@mfloat-abi=softfp@mfpu=vfp
a9_softfp_vfpv3-d16;@mcpu=cortex-a9@mfloat-abi=softfp@mfpu=vfpv3-d16
a9_vfpv3;@mcpu=cortex-a9@mfloat-abi=softfp@mfpu=vfpv3
a9_vfpv3_neon;@mcpu=cortex-a9@mfloat-abi=softfp@mfpu=neon
a9_hard_neon;@mcpu=cortex-a9@mfloat-abi=hard@mfpu=neon
a7_soft;@mcpu=cortex-a7@mfloat-abi=soft
a7_softfp_vfpv4;@mcpu=cortex-a7@mfloat-abi=softfp@mfpu=vfpv4
a7_softfp_neon-vfpv4;@mcpu=cortex-a7@mfloat-abi=softfp@mfpu=neon-vfpv4
a7_hard_neon-vfpv4;@mcpu=cortex-a7@mfloat-abi=hard@mfpu=neon-vfpv4
a17_soft;@mcpu=cortex-a17@mfloat-abi=soft
a17_softfp_vfpv4;@mcpu=cortex-a17@mfloat-abi=softfp@mfpu=vfpv4
a17_softfp_neon-vfpv4;@mcpu=cortex-a17@mfloat-abi=softfp@mfpu=neon-vfpv4
a17_hard_neon-vfpv4;@mcpu=cortex-a17@mfloat-abi=hard@mfpu=neon-vfpv4
a17_a7_soft;@mcpu=cortex-a17.cortex-a7@mfloat-abi=soft
a17_a7_softfp_vfpv4;@mcpu=cortex-a17.cortex-a7@mfloat-abi=softfp@mfpu=vfpv4
a17_a7_softfp_neon-vfpv4;@mcpu=cortex-a17.cortex-a7@mfloat-abi=softfp@mfpu=neon-vfpv4
a17_a7_hard_neon-vfpv4;@mcpu=cortex-a17.cortex-a7@mfloat-abi=hard@mfpu=neon-vfpv4
a53_soft;@mcpu=cortex-a53@mfloat-abi=soft
a53_softfp_vfpv4;@mcpu=cortex-a53@mfloat-abi=softfp@mfpu=vfpv4
a53_softfp_neon-vfpv4;@mcpu=cortex-a53@mfloat-abi=softfp@mfpu=neon-vfpv4
a53_hard_neon-vfpv4;@mcpu=cortex-a53@mfloat-abi=hard@mfpu=neon-vfpv4
a73_soft;@mcpu=cortex-a73@mfloat-abi=soft
a73_softfp_vfpv4;@mcpu=cortex-a73@mfloat-abi=softfp@mfpu=vfpv4
a73_softfp_neon-vfpv4;@mcpu=cortex-a73@mfloat-abi=softfp@mfpu=neon-vfpv4
a73_hard_neon-vfpv4;@mcpu=cortex-a73@mfloat-abi=hard@mfpu=neon-vfpv4
a73_a53_soft;@mcpu=cortex-a73.cortex-a53@mfloat-abi=soft
a73_a53_softfp_vfpv4;@mcpu=cortex-a73.cortex-a53@mfloat-abi=softfp@mfpu=vfpv4
a73_a53_softfp_neon-vfpv4;@mcpu=cortex-a73.cortex-a53@mfloat-abi=softfp@mfpu=neon-vfpv4
a73_a53_hard_neon-vfpv4;@mcpu=cortex-a73.cortex-a53@mfloat-abi=hard@mfpu=neon-vfpv4

所以,所有库的编译都需要修改默认CFLAGS,添加上:

CFLAGS="-mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4"

2.依赖

git 2.34.1编译时,会依赖于如下一些包:openssl、zlib、pcre2、curl、expat等等(git想要支持https的推送与拉取,需要curl及expat的支持)。

env CURL_CONFIG=/data/app/bin/curl-config CFLAGS="-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " CPPFLAGS="-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 -I/data/app/include" LDFLAGS="-L/data/app/lib -Wl,--rpath=/data/app/lib"  ./configure --prefix=/data/app --host=arm-himix200-linux --target=arm-himix200-linux --without-iconv --with-expat=/data/app --without-tcltk --with-curl=/data/app ac_cv_lib_curl_curl_global_init=yes ac_cv_prog_CURL_CONFIG=/data/app/bin/curl-config NO_ICONV=true ac_cv_fread_reads_directories=true ac_cv_snprintf_returns_bogus=false
make V=1
make DESTDIR=/XXX install

执行命令后,将安装git相应的共享库、头文件等至/XXX目录下。

Gitea如需要支持此版本,则需要修改配置文件,

2.1 openssl

下载链接:https://www.openssl.org/source/old/1.1.1/openssl-1.1.1k.tar.gz

编译命令如下(生成的Makefile不太正确,需要用sed命令修正):

./Configure --prefix=/data/app --openssldir=/data/app/etc/ssl --libdir=lib  --with-zlib-include=/data/app/include --with-zlib-lib=/data/app/lib/ no-asm no-async shared zlib-dynamic no-ssl3-method linux-armv4 --cross-compile-prefix=arm-himix200-linux-
sed -i 's|arm-himix200-linux-gcc|gcc|g' Makefile
sed -i 's|-O3|-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4|g' Makefile
sed -i 's|./demoCA|/data/app/etc/ssl|g' apps/CA.pl.in
sed -i 's|./demoCA|/data/app/etc/ssl|g' apps/openssl.cnf
make
make DESTDIR=/XXX install

执行命令后,将安装openssl相应的共享库、头文件等至/XXX目录下。

2.2 zlib

下载链接:http://www.zlib.net/zlib-1.2.11.tar.gz

编译命令如下(默认会是O3,建议用O2):

//export CC=arm-himix200-linux-gcc
env CC=arm-himix200-linux-gcc CFLAGS="-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " ./configure --prefix=/data/app
make
make DESTDIR=/XXX install

执行命令后,将安装zlib相应的共享库、头文件等至/XXX目录下。

2.3 libpcre2

下载链接:https://github.com/PhilipHazel/pcre2/releases/download/pcre2-10.39/pcre2-10.39.tar.bz2

编译命令如下:

env  CFLAGS="-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " PKG_CONFIG_LIBDIR=/data/app/lib/pkgconfig/ ./configure --prefix=/data/app --enable-pcre2-16 --enable-pcre2-32 --enable-jit  --host=arm-himix200-linux --target=arm-himix200-linux 
make V=1
make DESTDIR=/XXX install

执行命令后,将安装libpcre2相应的共享库、头文件等至/XXX目录下。

2.4 curl

下载链接:https://curl.haxx.se/download/curl-7.80.0.tar.gz

编译命令如下:

env PKG_CONFIG_LIBDIR=/data/app/lib/pkgconfig/ LDFLAGS="-L/data/app/lib -Wl,--rpath-link=/data/app/lib"  CFLAGS="-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " ./configure --prefix=/data/app --host=arm-himix200-linux --target=arm-himix200-linux --disable-ldap --disable-ldaps --disable-manual --enable-ipv6 --enable-versioned-symbols --enable-threaded-resolver --with-openssl --with-libssh2 --with-random='/dev/urandom' 
//sed -i -e 's/ -shared / -Wl,-O1,--as-needed\0/g' libtool
make V=1
make DESTDIR=/XXX install

执行命令后,将安装curl相应的共享库、头文件等至/XXX目录下。
编译安装完成后的curl,某些使用curl-config脚本来链接libcurl的,可能会有链接问题,则可以直接修改/data/app/bin/curl-config脚本,将166行修改为

echo ${CURLLIBDIR}-lcurl -lnghttp2 -lssh2 -L/data/app/lib -lssh2 -lssl -lcrypto -lssl -lcrypto -lzstd -lbrotlidec -lbrotlicommon -lz -pthread

2.4.1 libnghttp2

下载链接:https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.gz

编译命令如下:

autoreconf -i
env PKG_CONFIG_LIBDIR=/data/app/lib/pkgconfig/  CFLAGS="-g -O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " CXXFLAGS="-g -O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " LDFLAGS="-mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4" ./configure --prefix=/data/app --disable-examples --disable-python-bindings --enable-lib-only --host=arm-himix200-linux --target=arm-himix200-linux
make V=1
make DESTDIR=/XXX install

执行命令后,将安装libnghttp2相应的共享库、头文件等至/XXX目录下。

2.4.2 brotli

下载链接:https://github.com/google/brotli/archive/refs/tags/v1.0.9.tar.gz

拷贝libzip的cross.cmake文件过来

编译命令如下:

mkdir build && cd build
env PKG_CONFIG_LIBDIR=/data/app/lib/pkgconfig/  CFLAGS="-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " cmake -DCMAKE_TOOLCHAIN_FILE=../cross.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/data/app -DCMAKE_INSTALL_LIBDIR=lib -DBUILD_SHARED_LIBS=True ..
make VERBOSE=1
make DESTDIR=/XXX install

执行命令后,将安装brotli相应的共享库、头文件等至/XXX目录下。

2.4.3 libssh2

下载链接:https://www.libssh2.org/download/libssh2-1.10.0.tar.gz

编译命令如下:

env PKG_CONFIG_LIBDIR=/data/app/lib/pkgconfig/  CFLAGS="-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " LDFLAGS="-L/data/app/lib -Wl,--rpath-link=/data/app/lib" ./configure --prefix=/data/app --host=arm-himix200-linux --target=arm-himix200-linux --disable-static --disable-examples-build
make V=1
make DESTDIR=/XXX install

执行命令后,将安装libssh2相应的共享库、头文件等至/XXX目录下。

2.5 expat

下载链接:https://github.com/libexpat/libexpat/releases/download/R_2_4_2/expat-2.4.2.tar.gz

拷贝libzip的cross.cmake文件过来

编译命令如下(由于Host环境的cmake版本很老,expat的CMakeLists.txt脚本需要较新的cmake,因此编译时去掉了生成pkg-config文件):

mkdir build && cd build
env PKG_CONFIG_LIBDIR=/data/app/lib/pkgconfig/ LDFLAGS="-L/data/app/lib -Wl,--rpath-link=/data/app/lib"  CFLAGS="-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " cmake -DCMAKE_INSTALL_PREFIX=/data/app -DCMAKE_TOOLCHAIN_FILE=../cross.cmake -DCMAKE_BUILD_TYPE=None -DEXPAT_BUILD_TOOLS=OFF -DEXPAT_BUILD_EXAMPLES=OFF -DEXPAT_BUILD_TESTS=OFF -DEXPAT_BUILD_DOCS=OFF -DEXPAT_BUILD_PKGCONFIG=OFF ../
make VERBOSE=1
make DESTDIR=/XXX install

或者

env PKG_CONFIG_LIBDIR=/data/app/lib/pkgconfig/ LDFLAGS="-L/data/app/lib -Wl,--rpath-link=/data/app/lib"  CFLAGS="-O2 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 " ./configure --host=arm-himix200-linux --target=arm-himix200-linux --prefix=/data/app --without-xmlwf --without-examples --without-tests --disable-static --without-docbook
make V=1
make DESTDIR=/XXX install

执行命令后,将安装expat相应的共享库、头文件等至/XXX目录下。

如果使用cmake编译,由于未生成.pc文件,所以需要手工添加相应文件data/app/lib/pkgconfig/expat.pc

prefix=/data/app
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: expat
Version: 2.4.2
Description: expat XML parser
URL: https://libexpat.github.io/
Libs: -L${libdir} -lexpat -lm
Cflags: -I${includedir}

使用OpenGL显示简单的视频,对于一些纹理需要旋转并水平翻转,找到一个示例代码,做少量修改

// RotateByVector.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>
#include <math.h>

using namespace std;
#define CV_PI 3.1415926

//定义返回结构体
struct Point3f
{
    Point3f()
    {
        x = 0.0f;
        y = 0.0f;
        z = 0.0f;
    }

    Point3f(double _x, double _y, double _z)
    {
        x = _x;
        y = _y;
        z = _z;
    }
    double x;
    double y;
    double z;
};

//点绕任意向量旋转,右手系
//输入参数old_x,old_y,old_z为旋转前空间点的坐标
//vx,vy,vz为旋转轴向量
//theta为旋转角度角度制,范围在-180到180
//返回值为旋转后坐标点
Point3f RotateByVector(double old_x, double old_y, double old_z, double vx, double vy, double vz, double theta)
{
    double r = theta * CV_PI / 180;
    double c = cos(r);
    double s = sin(r);
    double new_x = (vx*vx*(1 - c) + c) * old_x + (vx*vy*(1 - c) - vz * s) * old_y + (vx*vz*(1 - c) + vy * s) * old_z;
    double new_y = (vy*vx*(1 - c) + vz * s) * old_x + (vy*vy*(1 - c) + c) * old_y + (vy*vz*(1 - c) - vx * s) * old_z;
    double new_z = (vx*vz*(1 - c) - vy * s) * old_x + (vy*vz*(1 - c) + vx * s) * old_y + (vz*vz*(1 - c) + c) * old_z;
    return Point3f(new_x, new_y, new_z);
}

// 可类比glRotate
Point3f RotateByVector(Point3f in_, double vx, double vy, double vz, double theta)
{
    double r = theta * CV_PI / 180;
    double c = cos(r);
    double s = sin(r);
    double new_x = (vx*vx*(1 - c) + c) * in_.x + (vx*vy*(1 - c) - vz * s) * in_.y + (vx*vz*(1 - c) + vy * s) * in_.z;
    double new_y = (vy*vx*(1 - c) + vz * s) * in_.x + (vy*vy*(1 - c) + c) * in_.y + (vy*vz*(1 - c) - vx * s) * in_.z;
    double new_z = (vx*vz*(1 - c) - vy * s) * in_.x + (vy*vz*(1 - c) + vx * s) * in_.y + (vz*vz*(1 - c) + c) * in_.z;
    return Point3f(new_x, new_y, new_z);
}

int main()
{
    // 原始
    Point3f A[] = {
        Point3f(1.0f,  1.0f, 0.0f),
        Point3f(1.0f,  -1.0f, 0.0f),
        Point3f(-1.0f, -1.0f, 0.0f),
        Point3f(-1.0f,  1.0f, 0.0f)
    };
    Point3f B[sizeof(A)/sizeof(Point3f)];
    Point3f C[sizeof(A)/sizeof(Point3f)];

    memset(&B, 0, sizeof(B));
    memset(&C, 0, sizeof(B));

    for(unsigned int idx = 0; idx < sizeof(A)/sizeof(Point3f); idx ++){
        // 围绕Z轴,旋转90度
        B[idx] = RotateByVector(A[idx], 0, 0, -1, 90);
        printf("idx: %d, x: %.05f, y: %.05f, z: %.05f\n", idx, B[idx].x, B[idx].y, B[idx].z);
    }
    printf("\n\n");
    for(unsigned int idx = 0; idx < sizeof(A)/sizeof(Point3f); idx ++){
        // 再水平翻转
        C[idx] = RotateByVector(B[idx], 0, 1, 0, 180);
        printf("idx: %d, x: %.05f, y: %.05f, z: %.05f\n", idx, C[idx].x, C[idx].y, C[idx].z);
    }

    system("pause");
    return 0;
}