首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
V2EX  ›  Linux

为什么如今的库还会被编译成 shared library 来用?内存和磁盘空间都已经足够了呀

  •  
  •   fhc023 · 34 天前 · 4091 次点击
    这是一个创建于 34 天前的主题,其中的信息可能已经有所发展或是发生改变。

    主要是历史原因吗?是不是还有其他的理由?

    58 回复  |  直到 2019-01-14 19:01:31 +08:00
        1
    ysc3839   34 天前 via Android   ♥ 1
    足够不代表可以随意浪费,当节约的成本几乎为 0 的时候为什么还要浪费?
        2
    doun   34 天前 via iPhone
    版本管理等,编译时间等? golang 不就是全静态编译链接了吗
        3
    Osk   34 天前   ♥ 2
    想起了被 node_modules 支配的恐惧,,,
        4
    across   34 天前
    为什么不用 shared lib,反而要采用浪费内存和磁盘的方法?
        5
    thedrwu   34 天前 via Android
    底层库的 hotfix/upgrade 不会牵一发而动全身

    Windows hook

    LGPL

    obj/linker 的兼容性

    等等
        6
    fhc023   34 天前
    哦 我是觉得相对它的收益 成本有点高。作为库的使用者,得保证开发和生产环境的这些依赖版本都一致。还是很痛苦的。
        7
    wbing   34 天前
    改一个库的功能,把库替换了就好了,就不用把使用这个库的程序再重新编译一次
        9
    fhc023   34 天前
    @doun 我很喜欢 go 呀 但是有很多有现有 c 库的情况就很尴尬。没太试过用 go 调用 c 不知道好不好
        10
    shyangs   34 天前
    想起了被 node_modules 支配的恐惧
    ::doge::
        11
    fhc023   34 天前
    @wbing 如果编译成 static library 的话也是不用重新编译的 只是打包一下
        12
    fhc023   34 天前
    @Osk 哈哈 package-lock.json
        13
    thedrwu   34 天前 via Android
    @fhc023 如果操作系统的 runtime 打个补丁,需要重新安装所有的程序。还是说每个程序都静态链接一份操作系统?
        14
    tewilove   34 天前 via Android
    库克:mmp。
    安卓:内存可能只够开个 QQ。
        15
    WordTian   34 天前 via Android
    并不够,比如 office 软件要都搞成静态链接,开了这个你就不用干别的了
        16
    catalina   34 天前
    别开玩笑,你想折腾死那些官方源和镜像源吗(笑哭)
        17
    fhc023   34 天前
    @thedrwu 有道理
        18
    fhc023   34 天前
    我二了
        19
    misaka19000   34 天前   ♥ 1
    我觉得对于客户端程序动态链接是有必要的,而对于服务端的程序则比较适合使用静态链接的程序
        20
    danc   34 天前
    开玩笑吧。比如 windows 操作系统,你看有多少 dll 文件,你要静态链接了,编译一次得多久,而且你的内存能放得下不
        21
    byteli   34 天前 via Android
    很多是为了热更的
        22
    expy   34 天前
    作为用户还是喜欢普通应用层软件静态链接,下一个可执行文件到处都能跑。
        23
    smdbh   34 天前
    1. 并不够
    2. 修改维护
        24
    yanqiyu   34 天前   ♥ 1
    glibc:我现在要修一个 BUG,请问你准备更新几个软件呢
        25
    fhc023   34 天前
    仔细想了下。像底层库更新这种情况的话,用动态库确实可以不用让依赖它的库重新打包。如果接口和行为没有改变的话是很不错的,但是也是可能带来兼容性问题。比如,底层库做了个 breaking change,那后续的库如果不改动的话也不能跑了。目前这种情况主要是包管理器来做依赖检查,然后决定你不是能更新某个底层库的。所以我觉得各有利弊吧。
        26
    kljsandjb   34 天前 via iPhone
    不说磁盘,内存这玩意不管多大都是稀缺资源😂
        27
    dalieba   34 天前 via Android
    降低开发成本,尤其是几个程序或者操作都需要一个轮子的时候。
        28
    dangyuluo   34 天前
    建议读一读《程序员的自我修养-链接、装载和库》,有真相
        29
    sdijeenx   34 天前
    磁盘空间本来是够的,自从有了 SSD 之后又不够了;
    内存空间本来是够的,自从有了 DDR4 之后又不够了。😂
        30
    Ediacaran   33 天前 via Android
    插件,或者方便替换
        31
    hikkikuma1991   33 天前
    有些库没办法被静态连接,以 glibc 那一坨为代表。golang 默认也是动态链接 glibc 的。
        33
    fhc023   33 天前
    @hikkikuma1991 长知识了 具体为啥必须要动态链接 大概是因为这个 https://skarnet.org/software/nsss/nsswitch.html
        34
    enenaaa   33 天前
    静态链接一个符号重名就能折腾死你。
        35
    fhc023   33 天前
    话说这个问题原来在 YC 上就有讨论 感觉水很深呐
    http://harmful.cat-v.org/software/dynamic-linking/
    https://news.ycombinator.com/item?id=9629663
        36
    msg7086   33 天前
    @fhc023 #25 所以发行版更新底层库都会保证 API 不会出现 breaking change。
    比如 openssl 1.0.2 和 1.0.2abcdef....opqr 都是兼容的。
    而且像是 libssl libc 这种库,正是动态链接的优势所在。系统库一更新,所有依赖的软件自动受益,即使你用的软件已经好几年不更新了,只要依赖的底层库更新,一样能修正掉对应的安全漏洞。
        37
    reself   33 天前
    代码上都要做解耦,讲究代码复用呢,为啥要反其道而行?
        38
    bytelee   33 天前
    难道动态库只是为了解决磁盘和内存空间不足的问题么?
        39
    iwtbauh   33 天前 via Android
    @fhc023 #25

    这就是我为什么讨厌 windows 这种大泥球的原因之一啊。你要是 windows 用户,肯定知道臭名昭著的“ DLL 地狱”问题。DLL 地狱即一个新软件可以随意升级(或降级)现有软件依赖的 DLL 库,而应用程序通常需要特定版本的库,一旦没有特定版本的库,应用程序就会崩溃。

    这就是因为 windows 技术上一开始没有做好共享库版本控制问题导致的。也就是你说的这个原因。现在为了保证前向兼容采用了一种极其丑陋的方法规避问题,但没能实际解决。

    而 Unix 的世界里,共享库版本控制做的非常好,一种方法是库文件名后戳通常带有版本号,应用程序依赖 libxxx.so.1 然后系统将 libxxx.so.1 符号链接到 libxxx.so.1.2.3 等版本上,系统只管升级 libxxx.so.1.x.x,库开发者保证小版本变化不会引入回归。而引入回归的大版本通常也可以和旧版本库共存。除了这种方法,还有很多种方法,比如 glibc 的符号版本控制,还有 qt 的库版本控制。。
        40
    littlewing   33 天前
    你是不是对 shared library 有什么误解? shared library 从来都是不使用从来解决内存和磁盘不够的问题的。
        41
    hilbertz   33 天前
    确实没有太大意义,共享库主要是为了商业分发
        42
    lcdtyph   33 天前 via iPhone
    @littlewing 还是解决了一些内存问题的吧?
        43
    XIVN1987   33 天前
    python 可以很方便的调用 C/C++编写的 dll 库,,如果是静态连接库的话,,必须得装 C/C++编译器才能使用,,
        44
    BXIA   33 天前 via iPhone
    想起了被 glibc 支配的恐惧
        45
    w01230   33 天前
    够用了也别浪费呀, 也有成本问题, ……看看 OPENWRT 的路由器~
        46
    ysc3839   33 天前 via Android
    @iwtbauh
    Windows 没有共享库版本控制,那么应用需要用的库不都是自己打包吗?再怎么升级也不会影响到别的软件呀?
    你可能会说 VC++ 运行库是共享的,但是 VC++ 本身不同版本是分开的,文件名中就包含有主版本号,同一个主版本要保证兼容的。

    你说 Unix 共享库版本控制做的非常好,本质不是 Unix 做得好,而是大多数类 Unix 系统有包管理,通过包管理能很好地做到版本控制。像 macOS 这种没有自带包管理的系统,也是像 Windows 这样软件需要什么就自己打包的。
        47
    janxin   33 天前
    编译快算不算优点?
        48
    est   33 天前   ♥ 1
    @iwtbauh dll 地狱早就被 winsxs 解决了。win98 时代说这个还有道理,现在说就是老黄历了。

    linux 下不同 distro、甚至同一 distro 不同版本 之间根本谈不上 .so 兼容。那种加版本的 trick 就不要拿出来 show 了。
        49
    fhc023   33 天前
    @iwtbauh 我觉得是有道理的 但是 linux 上的版本问题就算被解决了 但是还是感觉很奇怪 因为如果上层都各自用各自的版本了,那干嘛还要 shared library。 反而为了解决这些版本问题增加了复杂度 感觉不值得。不过像 @w01230 说的这种内存特别紧缺的是很有用的。而且还有像 glibc 这种不知道是有历史包袱还是故意为之的情况存在。所以我觉得看情况,像我能用 static 的时候就尽量用 static。虽然最终出来的 executable 里还是有 so 只要解决了生产环境的兼容问题 我就能接受了。
        50
    fhc023   33 天前
    感觉学到了很多哈 谢谢大家 如果大家有各种奇妙的关于这问题的链接都可以 po 出来
        51
    est   33 天前
    @fhc023 尽量 static 有一个特别的坑。就是遇到大规模安全事故需要普遍升级的时候

    那个时候你就哭吧。2333
        52
    behanga   33 天前
    当你吐槽 XXX 这破 app 都 100/200 多 MB 的时候 有可能里面的 so 就没用 shared library
        53
    IdontWanToBeBan   33 天前
    随意用这不好吗。。
        54
    iwtbauh   33 天前 via Android
    @ysc3839 #46

    你怕是不知道以前很多应用程序安装时直接升级(降级)系统库。

    而且这种行为的应用程序到现在也是存在的。

    @est #48

    这个问题和 distro 之间不兼容没有半点关系。

    所以说我说是“现在为了保证前向兼容采用了一种极其丑陋的方法规避问题”啊。

    @fhc023 #49

    比如我为 Debian 的某个版本提供二进制包,我可以直接在系统里依赖库,比如 libcurl3。而且基于共享库版本控制,不用担心 API/ABI 变化。安全更新直接由发行版负责了。我也不用自己去编译一份 curl,为什么不用呢。
        55
    fhc023   33 天前
    @est 嗯 谢谢提醒 自己写的哪些项目分别有哪些依赖都在自动化脚本里 如果有哪个出了问题 grep 下就知道哪些需要重新 link 之后重新编译有 bug 的库 然后 link 一下就完了 不需要全部重新编译 我觉得问题应该不大。
        56
    fhc023   33 天前
    @iwtbauh # 54
    你说的很有道理啊,可惜我的开发环境和部署环境不是同一个 distro。比如我在 arch 上依赖 ffmpeg 某个 shared lib 写了程序 在部署环境的 debian 里跑不起来 debian 官方可能都不提供我依赖的这个 lib 版本。
        57
    fhc023   33 天前
    @behanga 感觉更可能是图片啥的,毕竟一个 linux kernel image 也才几十 MB
        58
    ysc3839   33 天前 via Android
    @iwtbauh 那也不能怪操作系统啊,应用程序随意修改系统文件,在任何系统上都有可能出问题吧?
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   740 人在线   最高记录 4346   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 19ms · UTC 21:24 · PVG 05:24 · LAX 13:24 · JFK 16:24
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1