1
uiosun 2023-01-17 09:51:12 +08:00 3
路过,向前兼容?那个不是 JAVA 的 Slogan 之一吗——JAVA8 永远的神……
|
2
lichao 2023-01-17 09:52:59 +08:00
这方面无敌的还是 M$
|
3
Crawping 2023-01-17 09:54:12 +08:00 4
c++ 一大特点
生产环境与编译环境绑定.. |
4
tool2d OP |
5
ysc3839 2023-01-17 09:59:07 +08:00 via Android
glibc 按理来说不依赖内核吧?不过只能新版本 glibc 兼容旧版本编译的程序,不能反过来。
MSVC 这边,之前是只能同版本兼容,但是能多版本共存。VS2015 开始可以跨版本兼容,但是如果程序使用了新版本加入的函数那就不兼容旧版本。不过 MSVC 一直可以静态链接。 |
6
besto 2023-01-17 10:01:27 +08:00
1, C++11 之前的 C++ 真的忍不了;
2, clang 这种有很多默认检查,但基本可以关,这甚至直接导致 github 上一大堆开源代码拉下来编不过; 3, 一般 gcc 都是谈版本不谈年份。。。交叉编译,难道是嵌入式? linaro 最新的才 7.5...arm 官网有 9.x 的,不过 2012 年的 gcc 不能用是什么鬼 |
7
wingkwanli888 2023-01-17 10:03:55 +08:00 via iPhone
2023 年了为什么 c++ 还没有 npm, maven 之类的包管理器
|
9
tool2d OP @ysc3839 依赖的,你 google 搜一下"glibc kernel compatibility",遇到这种问题,完全无解。
好像可以通过修改 GLIBC 里的 MIN_KERNEL_SUPPORTED 来屏蔽一些功能,支持老内核的 linux ,可这货一般没人去自己编译。 而且 GLIBC 和 VC Runtime 不一样,加了太多东西,静态编译会有各种奇怪问题,真是心力交瘁。 |
10
lhbc 2023-01-17 10:08:32 +08:00 via Android
想要不依赖系统提供的库,不想用内核的 API ,就自己整齐一套
又想调用系统库,又要调用系统 API ,还想不依赖版本,这种好事哪有这么容易 自己把东西整齐活了,就不依赖了 |
11
ysc3839 2023-01-17 10:09:41 +08:00 via Android
|
12
Noicdi 2023-01-17 10:11:06 +08:00 via iPhone 2
最近在搞公司项目一个老模块依赖的 openssl 升级,体会到了这种兼容问题,整得我狗脑子要炸了
|
13
iold 2023-01-17 10:18:19 +08:00 via iPhone
@wingkwanli888 #7 vcpkg ,巨硬的,我一直在用
|
14
bitdepth 2023-01-17 10:23:14 +08:00
試過靜態編譯?
其實是你 toolchains 有問題 |
15
luvroot 2023-01-17 10:24:18 +08:00
用 Go 把,静态依赖编译,让你不用考虑环境的问题
|
16
DsuineGP 2023-01-17 10:25:24 +08:00 1
|
17
tool2d OP @bitdepth 静态编译后运行,运行也报内核太低,这点就很迷了。
toolchains 应该没问题,因为能正常生成 ELF ,我想在放到普通桌面 linux 上,大概率也能顺利运行。只是服务器比较特殊,不敢随便动内核。 想想还是 MS 好啊,静态编译 CRT ,基本上就没什么负担了。 |
19
bitdepth 2023-01-17 10:34:06 +08:00
你只是 ABI 相容,不代表 sysycall 相容
你大過是 timestamp 之類轉換為 64bits 這種 ioctl 出問題了 |
20
junmoxiao 2023-01-17 11:09:25 +08:00
有一说一上面提到的问题都可以解决,看看 vc-ltl 那个项目,xp 到最新的 win11 ,就算 api 有变化,一样能兼容。从原理上来说 linux 下也能做到,只是没人做
|
21
zunceng 2023-01-17 11:19:32 +08:00
正常的 c++ 只有代码能跨平台
|
22
geelaw 2023-01-17 11:21:39 +08:00 via iPhone
跨 DLL 请自觉 extern C 或者 COM
|
23
yolee599 2023-01-17 11:33:14 +08:00 via Android
编译器的锅关我 C++ 什么事?:doge:
|
24
yolee599 2023-01-17 11:43:19 +08:00 via Android
我用 gcc 编译过很多代码,从来没遇到过内核版本的问题,无论是 x86 项目,还是 arm 项目,都很顺利啊。OP 文中说的“交叉编译环境”,一般指在 x86 下编译 arm 的环境,这个你得用“交叉编译器”,还要配置好环境变量,指定到你这个交叉编译器
|
25
yolee599 2023-01-17 11:49:50 +08:00 via Android
交叉编译器一般使用 gcc ,除了 NDK ,我还没见过有什么项目使用 clang 作为交叉编译器
|
26
tool2d OP @yolee599 CLANG 比想的要更强,我就是编译 NDK 时发现,改改 taget 就能跨平台编译,就让人感觉很舒适。
最近 CLang 又加了对 VS IDE 编译和调试支持,生成的 OBJ 可以无缝嵌入 VC2015-VC2022 编译器。于是,我就想 ALl in one 一把,让 CLANG 也支持生成 Linux ELF 。 结果还是太傻太天真了。 |
28
maxxfire 2023-01-17 13:45:23 +08:00
没有什么是不能通过增加一层中间层来解决的问题,这个中间层可以理解为转换层、适配层。
具体技术可以是 函数指针,虚函数表,dlopen 等等,可以参考 COM 组件对象模型。 |
29
nmgwddj 2023-01-17 13:49:40 +08:00
目前跨平台项目编译问题我还是推荐使用 conan ,对于三方库的管理和编译工具链没有重度依赖。
我们现在工程 C++ 标准锁定在 14 ,Windows > MSVC15 (如果没有用一些较新的 API ,使用 7.0 SDK XP 都可以支持)、macOS 、iOS apple-clang > 12.4 ( macOS ARM64 支持) 以上、Android NDK21 clang9 以上、Linux GCC5 以上。GCC5 已经支持大部分 C++14 标准,如果是为了兼容一些 GCC5 没有支持的特性或者旧内核系统,可以考虑 GCC7+ glibc2.23 的 docker 镜像,这样 Ubuntu 16.04 都可以跑。 主流的 libevent 、openssl 、sqlite3 、libcurl 、zlib 、qt 等都验证编译通过。 |
30
icyalala 2023-01-17 14:15:15 +08:00
@wingkwanli888 包管理 vcpkg 、conan ,国内的 xmake 也可以试试。只是还是一言难尽。。
|
31
duke807 2023-01-17 14:25:19 +08:00 via Android
要查清楚是谁报内核太低这个错,就是谁的锅
|
32
weidaizi 2023-01-17 14:37:02 +08:00
@wingkwanli888 历史问题,如果依赖库的工程用的全是 cmake 的话,FetchContent 也是可以一把梭的
|
33
mingl0280 2023-01-17 16:27:28 +08:00 via Android
哈哈哈哈,跟我遇到的坑一模一样。
当然,新版 gcc 还有更坑的……我之前用 elf 编辑绕过了一下(就是去掉签名里面的 @版本),结果新版 gcc 加了几个 @@版本开头的隐藏函数( elf 编辑器里面根本找不着)直接干死了我试图绕过这个问题的方法…… |
34
zhyl 2023-01-17 16:46:00 +08:00
glibc 不能够静态链接的,换 musl 就行了
|
35
newmlp 2023-01-17 16:50:55 +08:00
这方面还是微软兼容性好,ntdll 从 xp 到 11 ,基本没什么问题
|
37
ipwx 2023-01-17 17:22:41 +08:00
你遇到的大概是安全检查。如果没这个拦着你,等 syscall 行为不符合预期的时候,出 bug 你都不知道哪里死的。
怪就怪 Linux 内核 syscall 一直在升级 ( doge |
38
icylogic 2023-01-17 17:28:57 +08:00 6
glibc 的兼容性,和 C++ 动态库的兼容性是两件事,而且这两点几乎都和 clang 没什么关系。你提到的这些问题,大部分锅是 glibc 的。
glibc 几乎很少有人需要最新版的特性,所以只要你去链最老的 glibc 就可以了,一般会推荐让你到所有目标平台中最老的那个去编译。glibc 就是唯一特殊的那个崽,不能静态链接。 c++ 你想用新的编译器、新的库(包括 std )是完全可以的,既可以静态链接(如果你能搞到静态库),也可以自己打包动态库(比如 /usr/lib/myapp/libxxx.so )然后设置 rpath 到 $ORIGIN 之类的,后者其实就是 Windows 那种一个 exe 带一堆 dll ( vcruntime140.dll, etc) 的风格。 这两点综合起来就是,比如你需要给 Ubuntu 18.04, 20.04, ... 这些平台提供支持,那你首先准备一台 Ubuntu18.04 的环境,然后通过 toolchain ppa 之类的东西安装或者编译一套新版的 g++/clang ,多新的都可以,只要你能在 18.04 上跑。最后用这套工具链去编译你的 app ,然后把所有依赖 (除了 glibc) 通过静态或者动态的东西打包带走。 这个你找台环境试一下就知道怎么回事了,比如尝试一下给一台默认 gcc 5.x 的环境编一个使用了 C++17 Filesystem 的应用。 你要是觉得麻烦就直接 docker 得了。 |
40
jworg 2023-01-17 18:10:45 +08:00
@icylogic 我那公司跑还是原生跑,不过特意准备了好几套不同的 linux 环境的容器然后在 docker 里面编译,配合 jenkins 分发到对应的服务器,都是当初运维偷懒没有升级,最后谁也不敢动,结果各种版本都有。
|
41
ipwx 2023-01-17 18:17:46 +08:00 1
@icylogic glibc 有点像 windows 的 kernelXX.dll ,封装了很多 syscall 相关的东西。
然后有一种 docker 镜像叫做 manylinux 镜像,目的就是为可移植的 二进制编译 提供帮助。 https://github.com/pypa/manylinux 虽然主要用于 python 社区的二进制分发,但 python 你懂的,一堆 C/C++ 扩展,所以 C++ 的工具链是齐的。 |
43
Zepp 2023-01-18 10:54:22 +08:00 via Android
https://stackoverflow.com/a/11207190
看看这个? gcc 有选项可以指定兼容的内核版本的 |
44
Zepp 2023-01-18 10:56:23 +08:00 via Android
@Zepp #43 sorry 我好像搞错了,这里说的是编译 glibc 时的 configure 选项,需要你自己重编译 glibc 才行
|
45
tool2d OP @Zepp 嗯,我也看到了。查过的几个别人编译好的 gcc/clang 参数,基本都是默认值,没人去主动修改。
也许自己编译 GLIBC 是可行的,只是我没有尝试。 还有一点我帖子里没提到,实验下来编译 i386 ELF 是不限制内核版本的,只有 x64 位的 ELF 才限制。 |
46
jones2000 2023-01-18 17:36:14 +08:00
项目所有代码在目标机器上源码编译,不就可以了。 除非有些库你没有重新编译
|
47
luoqeng 2023-01-18 19:07:25 +08:00
还能 golang 有远见,绕过 glibc ,直接 syscall
|
48
nmap 2023-01-18 19:29:22 +08:00
这种场景就是 golang 最大的优势之一
|
49
codehz 2023-01-18 21:19:05 +08:00 via iPhone
zig 内建的 clang 可以随意指定 glibc 的版本,就当作 abi 三元组的一部分
-target x86_64-linux-gnu.2.34 就能链接到 glibc 2.34 的版本(其他版本以此类推,最低到 2.16 ,十年前的版本),而且不在乎编译平台的 glibc 版本,甚至 windows 上也可以生成 linux 的 binary 参考 https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html |
50
learningman 2023-01-26 19:08:20 +08:00 via Android
@luoqeng 然后 cgo 又回去了
|
51
jinsongzhao 2023-02-15 14:56:35 +08:00
@nmap golang 一样,你试试最新版本去低版本操作系统跑一下试试,还是得换最老版本的 go 编译
|
52
jinsongzhao 2023-02-15 14:58:09 +08:00
@luvroot golang 的静态编译一样
|
53
jinsongzhao 2023-02-15 15:04:21 +08:00
golang 自带了很多库,所以好很多而已,但是本质一样,依赖操作系统本身的向下兼容
|