精华内容
下载资源
问答
  • Go交叉编译的那些

    2021-05-15 17:20:22
    最近两个月,一直在搞项目的国产化移植,把golang开发好的程序,运行在国产化平台上,操作系统基本都是基于Linux,但是...Golang交叉编译交叉编译在X64上的ubuntu 16.04系统上编译出其他平台的可执行程序, 查看Gol...

    最近两个月,一直在搞项目的国产化移植,把golang开发好的程序,运行在国产化平台上,操作系统基本都是基于Linux,但是CPU架构除了x86,还有ARM和MIPS,我们平时的Golang都是运行于x86 && x64 架构的CPU上,因此移植过程中遇到了好多坑,记录于此。

    Golang交叉编译

    交叉编译

    在X64上的ubuntu 16.04系统上编译出其他平台的可执行程序, 查看Golang支持的平台和版本:

    go tool dist list

    此命令会列出所有go语言支持的操作系统和cpu架构

    aix/ppc64

    android/386

    android/amd64

    android/arm

    android/arm64

    darwin/amd64

    darwin/arm64

    dragonfly/amd64

    freebsd/386

    freebsd/amd64

    freebsd/arm

    freebsd/arm64

    illumos/amd64

    js/wasm

    linux/386

    linux/amd64

    linux/arm

    linux/arm64

    linux/mips

    linux/mips64

    linux/mips64le

    linux/mipsle

    linux/ppc64

    linux/ppc64le

    linux/riscv64

    linux/s390x

    netbsd/386

    netbsd/amd64

    netbsd/arm

    netbsd/arm64

    openbsd/386

    openbsd/amd64

    openbsd/arm

    openbsd/arm64

    plan9/386

    plan9/amd64

    plan9/arm

    solaris/amd64

    windows/386

    windows/amd64

    windows/arm

    其实go的交叉编译非常简单,只需要在编译前指定系统和CPU架构,基本不会有任何问题,编译出来将文件拷贝到对应平台就能跑:

    GOOS=linux GOARCH=arm64 go build xxx.go

    # 有时候需要加上CGO_ENABLE=0

    CGO_ENABLE=0 GOOS=linux GOARCH=arm64 go build xxx.go

    go语言的交叉编译支持非常好,只要按照上述步骤基本不会出什么问题。坑,主要就坑在cgo, CGO_ENABLED=0 关闭cgo。

    采用cgo的交叉编译

    使用cgo,就必须指定CGO_ENABLE=1。并且必须指定CC参数为对应架构的gcc的交叉编译器。

    假设我们编译64位ARM平台的程序,就要提前下载aarch64版本的c++交叉编译工具CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=./aarch64-unknown-linux-gnueabi-5.4.0-2.23-4.4.6/bin/aarch64-unknown-linux-gnueabi-gcc go build xxx.go

    如果调用的CGO调用的C程序中依赖各种库,那么这个编译过程会报错各种依赖的库not found,各种基本的函数未定义。而且都是系统中最基本的库如libglibc、libgstream等。

    解决方案是必须在编译时,加上链接库的参数,而链接的库必须是交叉编译出的目标平台的系统库而不是当前系统的。

    这个在下载交叉编译工具链的时候,一般都会附带,我这里放到系统根目录下,然后通过C++编译时链接库的语法将库链接进去:

    主要是三个参数:-I , -isystem , -L, -l

    下面命令是个例子,假设项目中用到了phnono、curl、protobuf等组件:

    CGO_ENABLED=1 GOOS=linux GOARCH=arm64 CC=./aarch64-unknown-linux-gnueabi-5.4.0-2.23-4.4.6/bin/aarch64-unknown-linux-gnueabi-gcc -Wall -std=c++11 -Llib -isystem/aarch64/usr/include -L/aarch64/lib -ldl -lpthread -Wl,-rpath-link,/aarch64/lib -L/aarch64/lib/aarch64-linux-gnu -L/aarch64/usr/lib -I/aarch64/usr/include -L/aarch64/usr/lib/aarch64-linux-gnu -ldl -lpthread -Wl,-rpath-link,/aarch64/usr/lib/aarch64-linux-gnu -lphonon -lcurl -lprotobuf go build xxx.go

    到这一步,就基本解决了无法编译的坑。

    平台差异的问题

    在编译ARM版本的代码时,报错好几个系统调用找不到:

    undefined: syscall.Dup2

    undefined: syscall.SYS_FORK

    解决方案:对比golang源码实现:go/src/syscall/zsyscall_linux_amd64.go和go/src/syscall/zsyscall_linux_arm64.go,发现arm平台未实现Dup2但是提供了Dup3,参数略有差异,解决办法是修改调用的地方:

    // - syscall.Dup2(oldfd, newfd) 修改为:

    syscall.Dup3(oldfd,newfd,0)

    而SYS_FORK的调用,查找之下发现golang的ARM实现根本没有实现fork的系统调用,没有SYS_FORK这个宏或替代品。

    无奈只能修改项目代码,将fork的系统调用改为别的方式实现。

    MIPS的大小端问题

    报错:go.o: compiled for a big endian system and target is little endian

    主要体现在大小端字节序的问题,这是我在交叉编译Mips版本发现的一个问题,仔细查看了我的编译命令发现:CGO_ENABLED=1 GOOS=linux GOARCH=mips64 CC=./mips64el-unknown-linux-gnu-5.4.0-2.12-2.6.32/bin/mips64el-unknown-linux-gnu-gcc go build xxx.go

    这里的命令中:CC指定的是mips64el的编译器,el代表小端字节序,而GOARCH=mips64这是大端字节序,前后不一致导致编译的报错,

    解决方案:go和gcc保持统一、以目标平台为准(龙芯是小端字节序)将GOARCH指定为mips64le(注意是le不是el)

    最好加上LDFLAG=-ELCGO_ENABLED=1 GOOS=linux GOARCH=mips64le CC=./mips64el-unknown-linux-gnu-5.4.0-2.12-2.6.32/bin/mips64el-unknown-linux-gnu-gcc LDFLAGS=-EL go build xxx.go

    总结经验:

    1. golang程序开发少用原生的系统调用syscall

    2. 能用go解决的,尽可能不要用cgo

    3. 如果有模块必须通过C/C++调用,推荐C++和golang分离,C++和Golang程序间使用socket等方式进行进程间通信

    展开全文
  • ceres交叉编译

    2021-09-28 19:11:22
    交叉编译这个麻不麻烦主要还是看库作者资料给的全不全,ceres依赖库比较多,网上ceres交叉编译文章太少了,刚好前段时间自己试着用ceres在rk3308的板子上实现了回环的效果,在这里记录一下自己遇到的一些问题以及...

            交叉编译这个事麻不麻烦主要还是看库作者资料给的全不全,ceres依赖库比较多,网上ceres交叉编译文章太少了,刚好前段时间自己试着用ceres在rk3308的板子上实现了回环的效果,在这里记录一下自己遇到的一些问题以及解决方法。

            编译ceres一般有两种方法,一个是使用cmake-gui可视化界面网上有介绍不赘述,不过在我使用cmake-gui过程中一直配置不了lapack路径,不太好用,我这里使用的是直接修改cmake_list去编译

            首先说下不带suitesparse的ceres编译,这个比较简单不管是使用cmake-gui还是修改cmake_list,都能很容易成功,这里说下怎么修改cmake_list,由于这部分代码主要都是c、c++,所以只需要指定c 、c++编译器以及系统环境即可:

    SET(CMAKE_SYSTEM_NAME Linux)
    SET(TOOLCHAIN_DIR "/home/yc/rockchip_rk3308_addFortran_0804_sdk")
    SET(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/bin/aarch64-rockchip-linux-gnu-gcc)
    SET(CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/bin/aarch64-rockchip-linux-gnu-g++)

            如果要使用稀疏矩阵优化,那就比较麻烦了,主要是,ceres依赖suitesparse,而suitesparse又依赖lapack和blas,我们分开说。

            lapack/blas:看网上有文章说使用openbals,我试了一下没成功,应该是我自己问题,不过suitesparse官方文档也说了建议不要使用openblas。我使用的是lapack-release-lapack-3.8.0,因为自带了blas,编译方法同上面不过要注意添加Fortran的编译器路径,如果你的sdk没有Fortran,则需要自己编译一下。

    suitesparse:

    修改suitesparseconfig.mk:
    f77=aarch64-rockchip-linux-gnu-gfortran
    CUDA=no
    拷贝lapack blas库到lib文件夹下
    LDLIBS += -lgfortran
    编译
    AUTOCC=no CC=/home/yc/rockchip_rk3308_addFortran_0804_sdk/bin/aarch64-rockchip-linux-gnu-gcc CXX=/home/yc/rockchip_rk3308_addFortran_0804_sdk/bin/aarch64-rockchip-linux-gnu-g++ F77=/home/yc/rockchip_rk3308_addFortran_0804_sdk/bin/aarch64-rockchip-linux-gnu-gfortran make library
    如果缺少什么库,编译好后放在lib下,就能找到了
    提示fortran mpfr(mpfr版本最好大于4.0)一些看不懂的库,可以看看是不是sdk缺失,上面都是我自己的路径,换成你们自己的就好了。

    ceres编译: 
            分别修改每个xxxfind.cmake,set 路径一般都能找到了有些引用第三方库,在find_packge时候会默认去找cmake/module/findxxx.cmake,导致找不到安装路径可以删掉此处的findcmake,然后会去寻找xxxconfig.cmake ,set 一下路径应该就能找到了,然后像编译其他库一样编译就行了。
            suitesparse里面仿照component写一个blas的这样就能使能suitesparse了,中间提示test example错误,可以关掉option 里的tset example。中间提示test example错误,可以关掉option 里的tset example,因为你编译的exe只能运行在最终的目标环境下,跟你电脑上的linux系统是有区别的。

            交叉编译相当磨人,也在这个过程学习到很多,如果还有什么不清楚的可以下面评论,这个方法我是重复试验过可行的,编译的库也在机器上运行,实现了回环的效果。

    展开全文
  • 交叉编译总结

    2021-05-14 13:20:46
    思考:对交叉编译不熟悉,一些后感觉很简单的问题事前烦恼了很久。源代码的编译大致可以分为三个类,用cmake的,用make的, 用脚本的。用cmake的最好改,其次是用脚本的,一般文档写得全。用make的往往是很简陋的...

    思考:

    对交叉编译不熟悉,一些事后感觉很简单的问题事前烦恼了很久。源代码的编译大致可以分为三个类,用cmake的,

    用make的, 用脚本的。用cmake的最好改,其次是用脚本的,一般文档写得全。用make的往往是很简陋的,没文档,相关资料也少。

    总结:

    一.cartographer的Gmock GTest Glog模块的交叉编译

    首先下载Gmock GTest Glog的源码,Gmock和GTest在github上的一个仓库中

    修改cmakelist中修改

    cmakelist中的设置

    #告知当前使用的是交叉编译方式,必须配置

    SET(CMAKE_SYSTEM_NAME Linux)

    SET(TOOLCHAIN_DIR "/home/gzpeite/pettoolchain")

    #指定编译工具,一定要设置

    #或交叉编译器使用绝对地址

    SET(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabi-gcc)

    #指定C++交叉编译器

    SET(CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabi-g++)

    #不一定需要设置

    #指定交叉编译环境安装目录...

    SET(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR})

    #从来不在指定目录下查找工具程序

    SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

    #只在指定目录下查找库文件

    SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)

    #只在指定目录下查找头文件

    SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

    二cartographer中的boost的iostream,首先在boost官网下载boost版本

    我下的是boost_1.6的版本,不同的版本,流程不一样,

    [http://www.boost.org](http://www.boost.org)

    编译过程

    1.首先运行boost解压目录下的

    **./bootstrap.sh**

    2.修改生成的**project-config.jam**文件

    修改:

    using gcc : arm : arm-none-linux-gnueabi-gcc ;

    修改(这边不改也没事):

    option.set prefix :(交叉编译器所在位置);

    option.set exec-prefix :(交叉编译器所在位置)/bin ;

    option.set libdir :(交叉编译器所在位置)/lib ;

    option.set includedir :(交叉编译器所在位置)/include ;

    如果编译boost时出现以下问题,按照如下流程可解决

    看前面的 pkgconfig 。

    就是他的东西。

    pkgconfig 是一个命令程序,他通过一个通用的参数从 .pc 文件里面获取一些数据来帮助调用某个函数库的程序得到正确的编译参数。这是开发用的程序,如果你不需要开发编译程序。这部分都是 *-devel 包里面的数据。这些包卸载即可。

    其实 pkg-config 就是个二传手而已。不过他提供了一个通用的参数获取方式,很多软件还是比较喜欢给他准备一个配置数据文件的。

    网上给的建议

    这是因为boost的iostream库依赖于zlib和bzip2,所以您应该首先安装zlib和bzip2,然后运行,这两个包佩特科技给的库里有,但是要正确的指定路径

    tar --bzip2 -xf /path/to/boost_1_67_0.tar.bz2

    ./bootstrap.sh --prefix = path / to / installation / prefix

    ./b2

    ./b2安装

    请参见页面中的【5.4如果发生构建错误】:[https]([https://www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html](https://www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html)) : //[www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html](http://www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html)[]([https://www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html](https://www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html))

    请注意,当您运行./b2时,应该看到以下结果(没有这两个的boost的iostream,在cartographer中运行会报错):

    * zib:是(已缓存)

    * bzip2:是(已缓存)

    通过,这样boost就能找到zlib,zlib好像又需要bzip2,通过下面这两个就将他们弄进boost_iostreams了,有zlib的iostreams是需要bzip2的

    bzip2的的名字是bzlip2, 但是写路径要写bzip2,提示给我错误是bzlip2

    这个有点坑,但是注意一点,找lib包的路径的名字和lib包的名字一定是相关的

    ./b2 -j8 --with-iostreams -s BZIP2_LIBRARY_PATH="/home/gzpeite/pettoolchain/lib" -s BZIP2_INCLUDE="/home/gzpeite/pettoolchain/include" -s ZLIB_LIBRARY_PATH="/home/gzpeite/gittestarm/boost_1_71_0/zlib/save/usr/local/lib" -s ZLIB_INCLUDE="/home/gzpeite/gittestarm/boost_1_71_0/zlib/save/usr/local/include"

    3.测试编译效果

    三,cartographer中的ceres的交叉编译

    在github上下载ceres的2018年的版本,因为新的版本用些新的gcc的特性,导致gcc4.9编译的时候有些东西不识别,

    ceres依赖suitesparse和tbb

    tbb暂时没编译成功,但是不影响运行

    suitessparse依赖于lapack,lapack依赖于blas

    blas和lapack我们选择openblas, 它自带了blas和lapack,在github上找到openblas后git下来按照说明文档既可编译armv7下的程序,之后suitesparse和ceres中用到lapack和blas的时候,库的路径都选openblas.a就行

    suitesparse的配置选项主要在suitesparse_configure文件夹下的suitesparse.mk中配置,我下载的suitesparse源码是4.0的,更改其中的cc和cxx的路径,具体还是参考虚拟机中的该文件吧,

    如果找不到某个文件,可以试着在cxxflags中添加 -L./(path) -m -rt -rpath("path")

    如果怎么写都找不到,那就将缺少的那个库编好后放到交叉编译工具文件夹下的所有lib中,也就三四个吧,保管就找的到了。

    suitesparse就算编译成功了,其编出的库也可能是残缺的。我的经验是lapack blas libm.so librt.so 这4个库容易少,编译完最好往上拉一下。

    四,在cartographer中的protobuf的交叉编译

    在github上下载protobuf的3.6的版本,最新的3.10版本

    一 、 protobuf 安装

    下载链接

    1\. 确认安装依赖库:automake ,autoconf ,libtool

    2\. 下载 protobuf 安装文件,protobuf-cpp-3.6.0.tar.gz ,

    解压,

    第一次编译(获得protoc,根据proto文件生成.c和.h文件。编译在arm上执行的程序也是用这个x86上的protoc)

    ./autogen.sh

    ./configure

    make

    make check(报错,一般不用管)

    sudo make install

    然后进行第二次编译

    先make clean

    ./configure --host=arm-linux CC=PATH/arm-none-linux-gnueabi-gcc CXX=PATH/arm-none-linux-gnueabi-g++ --disable-protoc --prefix=/usr/local/protobuf-c-arm

    得到arm下的库

    在make intall中指定安装路径 make install = DESTDIR

    但是protoc要用第一次编译的,不要用第二次编译的。注意,不然在linux 编译protoc文件无法编译

    五,cartographer下编译lua(注意,makefile文件有很多个,要选有下面这些选项的makefile)

    在开发嵌入式项目时,由于嵌入式平台没有lua环境,只能自己移植。先到官网上下载最新的lua源码(点击打开链接)。

    接下来按照下面步骤:

    1、修改src/Makefile文件内容:

    源码包中的原始的Makefile的部分需要更改的内容如下:

    # Your platform. See PLATS for possible values.

    PLAT= none

    CC= gcc -std=gnu99

    CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS)

    LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)

    LIBS= -lm $(SYSLIBS) $(MYLIBS)

    AR= ar rcu

    RANLIB= ranlib

    RM= rm -f

    更改后的内容如下:

    # Your platform. See PLATS for possible values.

    PLAT= linux

    CC=arm-oe-linux-gnueabi-gcc -std=gnu99 -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=$(SDKTARGETSYSROOT)

    CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS)

    LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)

    LIBS= -lm $(SYSLIBS) $(MYLIBS)

    AR= arm-oe-linux-gnueabi-ar rcu

    RANLIB= arm-oe-linux-gnueabi-ranlib

    RM= rm -f

    SYSCFLAGS= -fexpensive-optimizations -frename-registers -fomit-frame-pointer -ftree-vectorize -Wno-error=maybe-uninitialized -finline-functions -finline-limit=64 -include quectel-features-config.h -fstack-protector-strong -pie -fpie -Wa,--noexecstack

    SYSLDFLAGS= -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-z,relro,-z,now,-z,noexecstack

    修改下面的内容;

    linux:

    $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"

    为:

    linux:

    $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl"

    同时将luaconf.h文件的64行屏蔽。

    2.修改顶层目录的Makefile文件

    原始的文件部分内容如下:

    # Your platform. See PLATS for possible values.

    PLAT= none

    # Where to install. The installation starts in the src and doc directories,

    # so take care if INSTALL_TOP is not an absolute path. See the local target.

    # You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with

    # LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h.

    INSTALL_TOP= /usr/local

    修改后的内容如下:

    # Your platform. See PLATS for possible values.

    PLAT= linux

    # Where to install. The installation starts in the src and doc directories,

    # so take care if INSTALL_TOP is not an absolute path. See the local target.

    # You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with

    # LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h.

    INSTALL_TOP= 自己想要安装的目录

    保存,make,make install

    上述只能产生lua的静态库。如果要产生动态库so,则按照下面步骤来:

    1、在顶层的Makefile中的

    TO_LIB= liblua.a

    修改为

    TO_LIB= liblua.a liblua.so

    2、在/src/Makefile中的如下两行之间:

    ALL_A= $(LUA_A)

    # Targets start here.

    添加如下选项

    LUA_SO=liblua.so

    ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO)

    $(LUA_SO): $(CORE_O) $(LIB_O)

    $(CC) -o $@ -shared -fPIC $? -ldl -lm

    六,最后编译cartographer时注意事项

    1,将根目录下的cmakelsit中test相关和main相关全部注释掉,这样就用不到gmock和gtest了,也少了一些错,编译起来速度也快些。

    2,在FindXXX.cmake中通过set写绝对路径,具体参考虚拟机中的

    3,如果少了什么库,但是你也编了,就通过target_linked_libraris来强制指定,写绝对路径,具体参考虚拟机中的。一般需要添加的都是suitesparse中的相关库,因为系统的FindCeres.cmake可能帮你去找了这些库

    但是你自己写的FindCeres.cmake可能就没写这些,但是没关系,通过target_linked_liraries将suitesparse编译后产生的库都链接上,运行时,ceres就能找到了

    七 一些有用的技巧

    1 objdump -s --section=.comment xxx

    可以看文件的编译器和含有什么库

    2makefile中

    修改cc和cxx的路径一般就是

    CC= ..../arm-gcc

    CXX= ..../arm-g++

    添加动态库一般 -l(例如math库就是-lm pthread库就是-pthread) 通过-L./ 和rpath=("")来强制动态库的路径

    写在CXXFLAGS CFLAGS

    有的库要用到特殊的编辑器比如fortron啥的,路径就改为交叉编译工具中的arm-fortron路径

    LIBS 用绝对路径来指定相应库

    用warning 来打印消息

    3在cmake中

    用message来打印消息

    通过cmakecache来查看你编译的这个库在编译时候产生了哪些变量,一般是路径相关的变量

    4 undefined reference的错误一般就是找不到实现,找不到实现有两种情况,一是找不到库,二是找到的库里没有实现相因的函数。

    库里没有相应函数的实现的原因有

    库是残缺的,譬如编译的suitesparse库就会出现这种情况,选的blas不对,boost库编译没有配置zlib等。

    库的版本不对应,譬如r16提供的gcc才4.9 比较落后,很多实现没有,所以用的ceres protobuf boost不能太新了,选2018及之前的。

    5 unrecognaiz file 一般就是编译项目用的编译器  和 其依赖的库被编译时用的编译器 不一致产生的

    展开全文
  • Java时段交叉计算

    2021-08-06 21:53:49
    背景 最近接到一个需求,做表结算(每月固定日期结算一次,类似抄表),需要对仪表数据...用户选择的时段可能和库中已有表数据存在交叉时段,也有可能不存在交叉。可是怎么求交叉呢?在网上找找查查自己修改一番然后适

    背景

    最近接到一个需求,做表结算(每月固定日期结算一次,类似抄表),需要对仪表数据进行补录(比如:钢厂电表坏了,做报表时需要把坏了这段时间消耗的电补录进去)。数据库有一张统计表,表中有字段开始时间,结束时间。现在补录数据也有个时段,现在需要把补录的数据结算到统计表中去。

    分析

    因为统计表中数据很多,不止存在一个表数据,还有各种水表气表等的结算数据。实现方案是按照用户所选择的表和时段进行补录。用户选择的时段可能和库中已有表数据存在交叉时段,也有可能不存在交叉。可是怎么求交叉呢?在网上找找查查自己修改一番然后适应了需求,下面直接上干货!!

    解决方案

    1. 在库中找到是否与补录进来的数据存在时段交叉
    2. 补录数据拆分到分钟级别。value = diffSecond*miniteValue

    1.在数据库查询有交叉时段的数据

    mapper.java

    SELECT xxxxx FROM energy_data_point_statistics WHERE data_code = #{dataCode}
            and ((time_begin <![CDATA[ <= ]]> #{beginDate} and time_end >= #{endDate}) or (time_begin <![CDATA[ <= ]]> #{endDate} and time_end >= #{endDate})
            or (time_begin >= #{beginDate} and time_end <![CDATA[ <= ]]> #{endDate}) or (time_begin <![CDATA[ <= ]]> #{beginDate} and time_end >=#{beginDate}))
    

    此处,A-B,C-D两个时段包含情况

    1. 两段不相交
    2. 包含关系
    3. 相交

    XxxserviceImpl.java–计算相交时间长度

     /***
         * @Author
         * @Description 判断两个日期重合部分时间(单位 : 毫秒)
         * @Date 2021/7/19 9:52
         */
        public long countDateIntersection(String start1, String end1, String start2, String end2) {
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            long s1 = 0;
            long s2 = 0;
            long e1 = 0;
            long e2 = 0;
            try {
                //标准化到1970-01-01
                s1 = sdf2.parse(start1).getTime();
                s2 = sdf2.parse(end1).getTime();
                e1 = sdf2.parse(start2).getTime();
                e2 = sdf2.parse(end2).getTime();
            } catch (ParseException e) {
                log.error("countDateIntersection--计算错误", e);
            }
            if (e1 >= s1 && e2 <= s2) {
                //s1,s2时段包含e1,e2
                return e2 - e1;
            } else if (s1 >= e1 && e2 >= s2) {
                //e1,e2时段包含s1,s2
                return s2 - s1;
            } else {
                //两者时段相交
                long ret = Math.min(s2, e2) - Math.max(s1, e1);
                return ret < 0 ? 0 : ret;
            }
        }
    
    

    思考和自测耗时久,回过头去思考也就那么也回事儿~
    打完收工!
    如有不对,希望大家多多斧正,留言交流!!

    展开全文
  • meson 交叉编译

    千次阅读 2021-05-13 16:48:33
    meson 使用 ndk 工具链交叉编译 arm64 的配置 [binaries] c = '/Android/Sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang' cpp = '/Android/Sdk/ndk/22.1.7171670/...
  • 你要说没有交叉吧,系数其实还是和 有关系的,你要说有交叉吧,又不是我们FM,PNN,ONN等等网络中讲得这么回。 这么看下来,DCN给我们的,大体上是一个空头支票。它的交叉也不一定是我们想要的交叉,如果想要真正...
  • 求解旅行商问题的顺序交叉多子代遗传算法【专利摘要】本发明公开了一种求解旅行商问题的顺序交叉多子代遗传算法。首先依据生物进化理论和数学生态学理论,提出了一种求解旅行商问题的顺序交叉多子代遗传算法,并给出...
  • 交叉编译tcpreplay

    2021-03-17 10:03:37
    交叉编译tcpreplay前言下载tcpreplay源码配置编译环境前言二级目录三级目录 前言 最近项目上出现个问题,其中一个报文发出去后,在互联网中被丢包。后续的重传也被丢包。因为该连接只有该数据包被丢弃,前面和后面的...
  • opus交叉编译

    2021-05-12 10:55:14
    从上个礼拜四接到带我的老师的任务,了解一下开源的音频编解码库opus,并且将这个开源库交叉编译到xx6138的板子上,看一下测试程序运行时cpu使用率。先去opus.org上将源代码下载下来,同时看了一点点的Documentation...
  • 原标题:学会Word交叉引用,再也不用一个一个改编号了在日常办公中编辑内容比较长的文档时,经常需要在文中引用文档内其他位置上的内容,通常在需要引用处写【参考本章第N节的内容】。如果是手动输入【参考本章第N节...
  • 在网上查了一堆后,不知是我比较蠢还是怎么了,总是没搞明白这个联合类型和交叉类型到底怎么回,今天终于搞明白这个了,给做个分享随便做下笔记 联合类型 实际上我们可以把联合类型理解为“或”,交叉类型理解为...
  • 所以来重新安装配置arm linux交叉编译环境。顺便记下.....1.虚拟机安装ubuntu9.10,这个很简单了不需累述了,安装前vmware会让你选择划分多大的硬盘,其实这个并不会是真的立即分离出那么大的空间出来,即使你目前只...
  • 数据中心中,在交换机之间或交换机与服务器之间,为了灵活性和方便管理,有源设备之间都是使用交叉连接和通过配线架互联。在一些场合,还有的要求在同一通道内使用多个交叉连接或互联。 大多数人都知道,永久链路是...
  • go语言交叉编译 - 附xgo踩坑之旅

    千次阅读 2021-03-01 16:21:18
    frp的交叉编译配置: env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_darwin_amd64 ./cmd/frpc GOOS: Target Operating System GOARCH:Target ...
  • 因为本来个体残差异质性都是可能存在的嘛,如果我们做模型的时候不考虑,简单的认为人都是一样的水平,其实和你在嵌套数据中用了回归是一回的,此时你的统计推断可能不准,注意是可能不准,如果你的人群确实都是一...
  • 其中有一部分是Linux系统自带的,还有一些我们自己来扩充的。 6、将工具链导出到环境变量 export PATH=/usr/local/arm/arm-2009q3/bin:$PATH 在一个终端中执行以上命令后,该终端中就可以直接使用arm-linux -gcc了...
  • 学习曲线2.1 选择最优K值2.2 不同K取值对模型的影响2.3 神器之一:学习曲线2.3.1 选取最优的K值2.4交叉验证2.4.1 泛化能力2.5 神器之二:K折交叉验证2.6 绘制带交叉验证的学习曲线2.7 是否需要验证集?2.8 交叉验证的...
  • 嵌入式设备由于不具备一定的处理器能力和存储空间,程序开发一般用PC来完成,然后将可执行文件下载到嵌入式系统中运行。这是目前嵌入式程序开发的不二选择——Host/target模式...自己建立交叉编译环境是一件很头疼的...
  • 3、当程序被停住时,可以检查这个时候程序中发生的 4、动态地改变程序的运行环境。 远程(交叉)GDB调试 调试桩(调试代理):在目标机上驻留有一小段代码。 调试桩作用: 1、在目标机上视线由主机上的调试器发送...
  • arm-linux-gcc安装安装arm-linux-gcc步骤:一:网上下载个压缩包,我下载的是arm-linux-gcc-4.4.3.tar.gz二:解压arm-linux-gcc-...linux-gcc: line 15: exec: /root/.: cannot execute: 成功 怎么回 答对加50 展开
  • 在执行第一个命令时,如果--host设置为arm linux,则不会执行该命令,这告诉我应该使用'--host'进行交叉编译。这就是为什么我什么都没做。 当运行第二条线路时,我得到configure: WARNING: Cache variable ac_cv_...
  • 立创EDA专业版之交叉选择并阵列放置元器件????交叉选择????阵列放置 ????交叉选择 在原理图界面,先框选需要交叉选择的元器件对象,右键,选择交叉选择(如果熟练之后,直接选择元器件,快捷键Shift+X)。 完成...
  • 忆阻器交叉开关阵列中的长短期记忆(LSTM)神经网络 原文:Long short-term memory networks in memristor crossbar arrays 作者:CanLi. et al. 期刊:Nature machine intelligence 导师布置的寒假任务之一,翻译指定...
  • 第一次写博客,记录一下研究windows到linux交叉编译的过程,发布在网上比写到自己电脑的word上更有意义 写在前面,这是在windows下完成交叉编译的全过程记录,所以有一些针对windows的独特经验,希望能有所帮助吧 ...
  • CSS语言:CSSSCSS确定body {background-color: #82b4b4;}.piano {position: absolute;top: 50%;left: 50%;width: 0;height: 0;}.piano--key {position: absolute;top: 50%;left: 50%;width: 512px;...
  • 信控交叉口组成

    2021-07-13 13:56:37
    这里写自定义目录标题信控交叉口组成1.人井与手井2.信号灯3.非机动车与行人灯4.电源线种类:5.通信信号机电子警察交叉口整体组成 信控交叉口组成 信控交叉口中交通工程问题设计知识面众多,下文进行总结,完善知识...
  • 小编典典您 可以 做您想做的,但是我不确定 为什么要这么做。获得动态列别名后,如何计划引用它们?也就是说,如果您从数据库中提取列别名,那么您将如何使用它们呢?我可能错过了您提出问题的原因。无论如何,我...
  • 来源:学习时报作者:李侠2020年10月30日,据国家自然科学基金委员会官网发布消息,基金委成立第九大学部——交叉科学部,这也是国家自然科学基金委时隔11年再次成立新的科学部。紧接着,2...
  • 导读:走出舒适区,我了解了 Go 的交叉编译功能。本文字数:5017,阅读时长大约: 6分钟https://linux.cn/article-13385-1.html作者:Gaurav Kamathe译者:MjSeven在 Linux 上测试软件时,我使用各种架构的服务器,...
  • 有很多方法可以将cross-compile转换为Raspberry Pi,也发布了用于交叉编译Qt或opencv的解决方案.但是,我找不到任何解决方案来与也使用opencv的Qt交叉编译程序.我在64位PC上使用debian尝试了以下操作:>我使用this ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,384
精华内容 20,153
关键字:

交叉事