OnMac:操作系统是否为MacOS,如果是,则设置为1,否则设置为0(默认0) :# 0 - 在Windows 或Linux 平台上
# 1 - 在Macintosh 平台上
OnMac=1USE_CUDA:运行环境中是否安装了CUDA,如果是则设置为1,否则设置为0(默认0)。需要注意的是,如果已经安装了CUDA,并且在编译过程中想要使用它,则需要检查系统中安装的CUDA的根目录是否与CUDA_ROOT变量中指定的路径一致。如果不一致,需要手动修改CUDA_ROOT变量,使其与系统保持一致: # 0 - 使用CPU
#1 - 使用GPU
使用_CUDA=1
# 如果需要修改此路径
CUDA_ROOT=/usr/local/cuda-9.0
CUDA_LIB_DIR=$(CUDA_ROOT)/lib64
CUDA_INCLUDE=$(CUDA_ROOT)/includeUSE_MKL:运行环境中是否安装了MKL数学运算库,如果有则设置为1,否则设置为0(默认0)。需要注意的是,如果MKL已经安装,并且在编译过程中要使用它,则需要检查系统中安装的MKL的根目录是否与MKL_ROOT变量中指定的路径一致。如果不一致,需要手动修改MKL_ROOT变量,使其与系统保持一致。 INTEL_ROOT是MKL路径的父目录,需要一起检查:#use MKL
使用_MKL=1
INTEL_ROOT=/opt/英特尔
MKL_ROOT=/opt/intel/mkl
MKL_LIB_DIR=$(MKL_ROOT)/lib/intel64/
MKL_INCLUDE=$(MKL_ROOT)/includeUSE_OPENBLAS:运行环境中是否安装了OpenBLAS数学运算库,如果有则设置为1,否则设置为0(默认0)。需要注意的是,如果已经安装了OpenBLAS,并且在编译过程中想要使用它,则需要检查系统中安装的OpenBLAS的根目录是否与OPENBLAS_ROOT变量中指定的路径一致。如果不一致,需要手动修改OPENBLAS_ROOT变量,使其与系统保持一致:#use OpenBLAS
使用_OPENBLAS=1
OPENBLAS_ROOT=/opt/OpenBLAS
OPENBLAS_LIB_DIR=$(OPENBLAS_ROOT)/lib
OPENBLAS_INCLUDE=$(OPENBLAS_ROOT)/include 完成后,正常执行Make命令。系统画面如下:
开始建造.
开始建库
完成图书馆建设
完成构建可执行文件
开始构建可执行文件
完成建设.
跳过构建动态链接库
构建可执行文件:/bin/NiuTensor.CPU完成后,会在工程目录下的bin目录下生成NiuTensor.CPU可执行程序。
要使用
可执行程序的使用
可执行程序,只需执行./bin/NiuTensor.CPU -test即可。该命令将执行单元测试。如果没有问题,最后会有提示。
好的!一切都很好!
NiuTensor系统动态链接库的生成与使用
库文件的生成
这部分也很简单。除了OnMac、USE_CUDA、USE_MKL和USE_OPENBLAS开关的设置(参考上一章)外,只需更改Makefile中的dll变量即可。只需将开关设置为1:
# 是否生成dll
dll=1完成后,正常执行Make命令即可。系统画面如下:
开始建造.
开始建库
完成图书馆建设
完成构建可执行文件
开始构建可执行文件
完成建设.
构建动态链接库:/lib/libNiuTensor.CPU.so
构建可执行文件:/bin/NiuTensor.CPU完成后,会在工程目录下的lib目录下生成libNiuTensor.CPU.so库文件。
从Makefile中的描述可以看出,库文件的编译实际上集成了NiuTensor中的核心操作以及每个操作的单元测试,不包括Main.cpp文件($(MAIN_FILE))。
ifeq ($(dll), 1)
@echo "构建动态链接库: $(NIUTRANS_DLL)"
@$(CXX) -shared -Wall $(CXXFLAGS) $(MACRO) $(LDFLAGS) $(OBJS) $(DEPLIBS) -o $@
别的
@echo "跳过构建动态链接库"
endif
库文件的使用
如上所述,编译后的库文件包含NiuTensor中的所有张量操作以及相应的单元测试。所以对于库文件的测试,我们直接使用Main.cpp文件和库文件联合编译。命令为g++ -o ./bin/NiuTensor.CPU ./source/Main.cpp ./lib/libNiuTensor.CPU.so -std=c++11 在bin目录下生成可执行程序。
执行./bin/NiuTensor.CPU -test 进行单元测试。如果没有问题,最后会有提示。
好的!一切都很好!注意:上述过程生成的可执行程序只能在编译路径下执行,否则会提示找不到库文件。对于这个问题还没有找到合适的解决方案。如果有合适的解决方案,我们稍后会更新。
类Unix系统兼容性测试
类Unix系统这里主要测试的是Linux系统和macOS下可执行程序和动态链接库的兼容性。
可执行程序兼容性
实验方法是在Linux和macOS上生成对应平台的可执行程序,然后直接放到另一个操作系统中尝试执行。
执行结果如下:
在Linux平台执行macOS程序:-bash:/dllTest:无法执行二进制文件,无法正常执行。在macOS平台执行Linux程序: zsh: exec format error:/NiuTensor.CPU 均无法正常执行。
但由于macOS默认使用LLVM进行编译,而Linux平台使用GCC,是否会因为编译器差异而无法运行呢?为了验证这个猜想,我们进行了一个简单的实验。
我们使用GCC在macOS平台上编译NiuTensor可执行程序,然后在Linux平台上进行测试。结果和上面一样,但是还是会报二进制文件无法执行的错误。
动态链接库兼容性
与可执行程序兼容性的测试方法类似,我们交换Linux和macOS上生成的动态链接库libNiuTensor.CPU.so文件,然后尝试用动态链接库编译Main.cpp文件。
执行结果如下:
在Linux平台上使用macOS下生成的动态链接库进行编译:/lib-mac/libNiuTensor.CPU.so: file not recognize: Unrecognized file format
collect2: 错误:ld 返回1,无法正确编译。在macOS 平台上执行Linux 程序:找不到架构x86_64 的ld: 符号
clang: error: 链接器命令失败,退出代码为1(使用-v 查看调用)无法正常编译。
不兼容的解释
可执行程序的不兼容
由于不同操作系统下可执行程序的文件格式和API的差异,不同操作系统下的二进制文件往往不兼容。
可执行程序的文件格式
编译出来的可执行程序其实可以理解为一个执行包,它不仅包括编译出来的二进制机器指令(代码段),还包括数据段和BBS段(存放程序中未初始化的全局变量)等.并且可执行程序各部分的设置和组织在每个操作系统中都是不同的。其中Linux平台广泛使用EFL格式进行打包,macOS使用Mach-O,WIndows平台使用PE。虽然每个操作系统都有自己的打包方式策略,但由于其中记录的核心内容几乎是相同的,所以有很多第三方软件可以将某些操作系统上的软件迁移到其他操作系统上,比如大名鼎鼎的Wine、 Windows平台上的软件可以迁移到类Unix平台上运行。
关于可执行程序的文件格式,维基百科提供了每种文件格式支持的功能的详细比较。
操作系统API
操作系统API是指操作系统提供给应用程序调用使用的接口,使开发人员无需关注操作系统底层操作细节,即可方便、快捷地使用。同时,API仅限制应用程序的函数调用方式,不涉及内部实现。因此,可以通过操作系统层面的更新来不断优化应用程序的执行效率和运行方式,并在保证界面不变的情况下对应用程序进行比较。与旧程序的良好兼容性。对于Windows操作系统来说,主要使用的API是Windows API,它包括基础服务、图形设备接口和其他操作接口。对于Unix操作系统来说,采用的是POSIX,类Unix操作系统往往都兼容这个接口,比如常见的Linux和macOS。由于类Unix平台在程序开发人员中的高度普及,许多优秀的软件都倾向于基于POSIX接口来开发。因此,为了增强Windows平台的竞争力,微软也在逐步完善对POSIX接口的支持。
要了解不同操作系统上的界面差异,最直观的方法就是从我们编写C++程序时对不同操作系统的适配开始。以下代码来自NiuTensor系统中XMem.h中的一个片段。为了保证在Linux、macOS和Windows平台上顺利执行,它通过宏定义来适配不同平台使用的头文件。
#ifdef __苹果__
#include#include#elif WIN32
#包括#其他
#include#endif 从以上两点可以看出,不同平台编译生成的可执行程序受到文件格式和操作系统API差异的限制,很难直接跨平台执行。对于有跨平台需求的项目开发,我们在编码过程中需要考虑到跨平台的问题。例如,我们的NiuTensor开源项目已经适配了常见的操作系统API。这使得由于可执行程序文件的格式,我们很难直接使用在其他平台上编译的二进制程序,但是我们仍然可以通过编译和安装使软件在不同的操作系统上运行。
动态链接库的不兼容
在谈论动态链接库时,我们首先需要明确什么是库文件。我们在编程过程中经常会听到动态链接库和静态链接库。其实两者存在的主要目的都是为了减少开发者反复“造轮子”的过程。开发人员将比较底层的功能封装成库文件供其他人员直接调用,降低了整个系统的开发难度。它还具有解耦系统中各个模块的作用,这对于大型项目的开发很有帮助。我们都知道程序的编译过程包括预编译、编译、汇编代码生成和链接,而使用库文件的过程实际上就是在链接过程中插入编译好的库。整个流程如下:
Image 对于静态库,我们可以直观的理解为,它是我们编译(未链接)的中间文件,当它与其他文件链接时,库中的所有内容都会整合到可执行文件中。因此,从理论上讲,先将部分代码编译成静态链接库,然后与其他代码链接成最终的可执行文件,与直接编译链接全部代码是完全一样的。这意味着如果我们要更新项目中的静态库,需要重新编译最终的可执行文件,使用起来比较不方便。动态链接库解决了这个问题。它在链接过程中并不直接将代码添加到可执行程序中,而是在运行时动态加载(因此称为动态链接库)。由于这个特性,动态链接库获得的可执行程序本身的大小会比静态库获得的要小(因为有些代码没有加载到动态库中)。同时,对库文件的更新不需要重构可执行程序。编译。但同时,动态库的一个弱点是,可执行程序在发布时需要与库文件一起交付给用户,否则会出现找不到库的问题。
一般来说,动态库和静态库都有各自的优点。静态库的好处是编译得到的可执行程序不再与编译时使用的库文件相关,移植起来非常方便。动态库的优点是底层库文件的升级更加灵活,不需要用户重新编译。
与可执行程序类似,无论是动态库还是静态库,在不同的操作系统上仍然存在可执行文件格式和操作系统API的问题。因此,只需将其他平台的库文件应用到第三方操作即可。系统也无法正常链接,会出现前面实验中提到的无法识别文件格式等问题。
后记
本文主要对可执行程序和库文件的跨平台兼容性进行实验和讨论,查阅了相关资料,对可执行文件有了更深入的了解。分享一下,供大家参考。如果有任何疑问,请在留言区留言。
一些感想
别是爱迪生,他是发明家。我们需要做的是科学家,用科学的方法和手段来认识世界。
——肖先生
图片这篇文章主要是我目前对NiuTensor项目跨平台兼容性的测试过程的总结。前半部分是一些小实验,后半部分是对实验结果的分析。整体来说,我其实觉得流程的逻辑还是存在一些问题的。我们总是习惯通过实验来验证,但在验证之前,我们其实并没有对问题进行深入的认识和思考。最后,我们可能会看到结果并将其留在那里。导致以后出现类似的问题。事实上,张二和尚还是一头雾水,帮不上什么忙。至于二进制文件和库文件的兼容性,其实如果我们提前查一下相关资料就会发现,单纯通过迁移是不可能成功链接或运行的。得出这个结论之后再进行实验可能更符合科学研究的流程。这也是肖老师一直说的不要成为爱迪生的道理,鼓励自己吧!
附上过程中使用到的一些工具
ldd/otool工具
ldd 和otool 工具是分别为Linux 平台和macOS 平台提供的工具,用于分析可执行程序所依赖的库。两者都可以列出可执行程序或共享库所依赖的函数库。
ldd的全称是List Dynamic Dependency。中文意思是列出动态库依赖关系。使用方法为ldd NiuTensor.CPU,其中NiuTensor.CPU是可执行文件。执行结果如下:
$ldd NiuTensor.CPU
linux-vdso.so.1=(0x00007fff4dcce000)
libdl.so.2=/lib64/libdl.so.2 (0x00007f0c60509000)
libpthread.so.0=/lib64/libpthread.so.0 (0x00007f0c602ed000)
libstdc++.so.6=/lib64/libstdc++.so.6 (0x00007f0c5ffe6000)
libm.so.6=/lib64/libm.so.6 (0x00007f0c5fce4000)
libgcc_s.so.1=/lib64/libgcc_s.so.1 (0x00007f0c5face000)
libc.so.6=/lib64/libc.so.6 (0x00007f0c5f70d000)
/lib64/ld-linux-x86-64.so.2(0x00007f0c6070d000)包括三列,分别代表程序所依赖的库名称、系统根据需求提供的库位置以及起始地址库加载。
otool 是为macOS 平台提供的工具。它的全称是对象文件显示工具。主要用于分析编译后的目标文件。该工具集成在XCode 中。 otool工具可以通过在命令中指定-L参数来分析可执行程序中调用的依赖库。 otool -L NiuTensor.CPU。运行后结果如下:
NiuTensor.CPU:
/usr/lib/libSystem.B.dylib(兼容版本1.0.0,当前版本1281.0.0)
/usr/lib/libc++.1.dylib (兼容版本1.0.0,当前版本800.7.0) 包含的内容与ldd命令显示的内容类似,包括系统提供的库信息,以及系统的兼容性补充了相应的库版本。供开发者参考。
注意
本文使用的代码版本为_gitlab内测版本_(版本SHA为ca1f18435adfe154c7fbe1a7193d3db64c8fee0a),但本文进行的测试理论上与代码版本没有直接关系。使用github上的版本理论上也有同样的现象,但笔者没有直接测试过。如果有任何疑问,请及时在评论区讨论。谢谢你!
好了,文章到这里就结束啦,如果本次分享的全面探索NiuTensor系统在类Unix系统下的兼容性测试和问题对您有所帮助,还望关注下本站哦!
【全面探索NiuTensor系统在类Unix系统下的兼容性测试】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
这很有用!希望他们能尽快解决所有问题,让我可以用它来取代我现在的工具。
有5位网友表示赞同!
对于许多开发者来说,类Unix系统的兼容性非常重要。期待看到NiuTensor在不同环境下的表现。
有13位网友表示赞同!
测试一个开源项目的重要步骤,确保更广泛的用户都能使用并受益于NiuTensor。
有11位网友表示赞同!
这说明开发者们把兼容性问题放在心上,希望能让所有开发者都能轻松使用这个系统。
有7位网友表示赞同!
类Unix系统的用户群体庞大,这个测试对大家都是一件好事!
有14位网友表示赞同!
期待看到最终结果,看看NiuTensor在不同平台上的表现怎么样。
有12位网友表示赞同!
对于我来说,只要NiuTensor能在我的系统中运行,我就很高兴了。
有19位网友表示赞同!
这是一个很大的挑战,但开源项目需要这样的测试才能不断进步。
有10位网友表示赞同!
牛气!希望这个测试能确保NiuTensor在各个平台上都能够使用流畅。
有10位网友表示赞同!
作为一名开发人员,我理解兼容性测试的重要性,期待看到最终的结果。
有11位网友表示赞同!
我相信开发者们一定尽力让NiuTensor在所有类Unix系统中都能完美运行!
有17位网友表示赞同!
这样的测试非常有助于开源项目的质量提升,用户体验也会更好。
有6位网友表示赞同!
希望这个测试能帮助开发者们更深入了解不同类Unix系统之间的差异。
有14位网友表示赞同!
NiuTensor的兼容性测试将会对未来发展起到重要的作用。
有5位网友表示赞同!
感谢开发者们为开源项目贡献出的努力,期待看到最终成果!
有10位网友表示赞同!
这个测试对于想要使用NiuTensor的用户来说非常重要,可以让他们更了解系统是否满足自己的需求。
有18位网友表示赞同!
希望未来NiuTensor能够在更多平台上顺利运行,让更多人受益!
有14位网友表示赞同!
我很期待看到最终的测试结果,相信NiuTensor一定是一个功能强大且兼容性强劲的系统!
有14位网友表示赞同!
开源项目的兼容性测试是一项非常好的实践,有助于项目的发展和用户的体验提升。
有6位网友表示赞同!