就算浏览器上 es5 这种没有依赖注入容器,但也有 requirejs 这种管理依赖的东西,
C 语言是怎么管理代码执行时依赖关系?
这里我指的不是 makefile 这种只能算是文件层面的依赖管理。
1
neoblackcap 2018-01-17 09:29:16 +08:00
动态库?不是系统默认的包管理器吗?
|
2
crysislinux 2018-01-17 09:31:48 +08:00
哈哈,对啊,包管理就是。C 这种比较麻烦的地方是有 ABI 兼容问题
|
3
GuangXiN 2018-01-17 09:35:13 +08:00 via Android 1
谁说没有,RedHat 发展了 rpm,debian 发展了 apt,BSD 有 port
|
4
Juggernaut 2018-01-17 09:42:04 +08:00
C 一直在做底层有差别硬件的无差别化服务支持,一门心思走到底了
|
5
snnn 2018-01-17 09:56:39 +08:00
有。
去 google 的 github 里面找。 |
6
wellsc 2018-01-17 09:58:18 +08:00
pacman 啊
|
7
xd314697475 2018-01-17 10:24:30 +08:00 1
|
8
dychenyi 2018-01-17 10:27:18 +08:00
还用管理?可能没看懂题目。一个 setenv LD_LIBRARY_PATH XXX 不是解决了所有问题吗? 而且这是操作系统管理的。
|
9
mooncakejs 2018-01-17 10:30:15 +08:00
C 的跨平台是源码级跨平台,所以依赖就是源代码,动态库基本的依赖交给系统管理了。
yum/apt install libxxx 安装动态库 yum/apt install xxx-dev[el] 安装开发包 |
10
rogerchen 2018-01-17 10:32:13 +08:00
朋友,所有发行版的包管理器都是为了管理 C 系语言的依赖开发出来的,管理器多得一匹好吗。。。
|
11
sinxccc 2018-01-17 10:41:27 +08:00
UNIX 就是 C 的 runtime 啊ˊ_>ˋ
|
12
zj299792458 2018-01-17 10:43:52 +08:00 via iPhone
Apt-get ? brew ? macport ?
|
13
feather12315 2018-01-17 10:47:26 +08:00 via Android
autoconf 算不算
|
14
mengyaoss77 2018-01-17 11:12:20 +08:00
-L -l 算是依赖吧
包管理就用系统自带的啊 那么多! |
15
feverzsj 2018-01-17 11:18:20 +08:00
因为 c/c++是应用平台最广的原生语言,无法在标准层面做出限制,即使 c++即将加入的 module,也不是和编译器绑定的
|
16
GeruzoniAnsasu 2018-01-17 11:52:07 +08:00
C 的代码是不可运行时改变的
编译生成可执行文件时就需要把所有的依赖包含进来 说白了 include 就是复制粘贴把所有用到的库的代码都粘贴进一个文件然后再开始编译 编译完了再生成可执行文件 作为静态语言的 C 压根就没有运行时代码注入和扩展的可能,自然不会有什么代码中间来一行 import,更不会有 try import raise,也更不可能在运行时来引入新的全局符号,静态语言的变量和代码符号都只是地址而已,当我们需要动态生成 /访问一个变量我们有指针,这是 C 的做法,跟有虚拟机的语言是很不一样的。 这跟 O 不 OO 半点关系都没有,你用 C++也不会存在你概念中那种所谓依赖管理框架,对于静态语言来说,依赖管理即库文件管理,即包管理 |
17
veelog 2018-01-17 11:56:11 +08:00 via iPhone
pkg-config 算吗
|
18
hitmanx 2018-01-17 12:00:28 +08:00
@GeruzoniAnsasu
> "编译生成可执行文件时就需要把所有的依赖包含进来 " 动态库链接可以是 stub 的呀 > "C 的代码是不可运行时改变的" 如果是来自动态链接的库可以啊,一是可以热更新,二是可以用 LD_PRELOAD(intercept)之类的手段在运行时先于真正的符号库加载 |
19
gnaggnoyil 2018-01-17 12:00:55 +08:00
然而讽刺的是,Makefile 等东西恰恰在 C 的所谓"依赖管理"中起到了主要作用——函数位置的确定都是靠 linker 来完成的,而 linker 的输入嘛……一般都是实现指定好的 object file.
|
20
yksoft1 2018-01-17 12:03:41 +08:00
毕竟 C 标准下要考虑到十几 K 内存的单片机的需求。
|
21
northisland 2018-01-17 12:08:33 +08:00 via iPhone
历史包袱。
当年内存还是几十 k,硬盘百十 M 的时代。 你生成个 20M 的 LAPACK 库比取经都难。 所以所有执行文件,都链接这个宝贝库。 不像现在,很多语言能随便打包模块。 解决方法很多人都说了。 |
22
northisland 2018-01-17 12:13:48 +08:00 via iPhone
这点黑 C 不过分。
C 系列里库的管理,很屎,比较吃经验。也叫技术门槛。 但因为贴近底层,真心离不开这些"专家" 所以对公司里某套东西现状比较熟的人比较不容易丢饭碗 |
23
htfy96 2018-01-17 12:22:31 +08:00
conan + CMake
|
24
northisland 2018-01-17 12:31:04 +08:00 via iPhone
仔细看了一下你的描述,你需要了解
1. 目标文件的代码段,数据段,只读数据段是干嘛的。 2. 二进制文件是怎么动态装载,成为运行的程序。 懂了以后你就会发现,你下的 C 要处理数据依赖只能靠手动传结构体指针,完全是胡扯。你学过 extern 关键字么? |
25
zjsxwc OP |
26
zhicheng 2018-01-17 12:42:13 +08:00
看了问题和补充,楼主你是硬把编译型语言往解释型语言的概念上套。有些概念是互相通用的,有些则不是,解释型语言可以在 Runtime 检查依赖,但编译型不行,它必须在 Run 之前解决依赖 (Linker & Loader )。所以你说的那种东西目前在语言层是不存在的。
动态库是可以减少内存使用,但它还有另一个主要作用,如果一个库有更新(比如 libc ),只需要更新这个库就可以了,不需要把所有依赖这个库的程序全部更新一遍。所以很多 OS 现在已经不提供静态库了。 |
28
zhicheng 2018-01-17 13:10:47 +08:00
@zjsxwc 这种方法就是把所有的代码全编译到一个 binary 里完全不使用动态库,可以看一下我回复里关于动态库的解释。这在 C 语言里是不可能的,因为现在很多新的 OS 里没有静态库,只提供动态库。
|
29
GeruzoniAnsasu 2018-01-17 13:49:40 +08:00
@hitmanx 动态链接库只是动态链接而已,但链接时的函数签名 ABI 都是固定不可改的,在编译的那一刻起就已经从附带的.h 里编译解析成导入符号写进了 binary 的符号表,说的不可改是指源码意义上无法存在 exec(void* code)这种东西,导入 dll 也好,热更新 dll 也好,源码编译后固定下来的仍然是那些
没想较真所以也没怎么严谨,较真说的话汇编时代就有 smc 自修改用来保护软件,但那对于提升设计毫无帮助 另外怎么说,依赖管理即库 /包管理是不会错的 |
30
waruqi 2018-01-17 14:24:53 +08:00 via Android
用 xmake
|
31
kimown 2018-01-17 18:51:44 +08:00 via Android
所以说 c 一直没进步,一点没错,吃老本都能吃十几年,哪个语言赶得上
|
32
akann 2018-01-17 23:03:53 +08:00
微软的 visual studio 有 nuget.
|
33
akann 2018-01-17 23:08:16 +08:00
google 有 gclient , gyp 一大堆
|
34
linux40 2018-01-18 10:37:47 +08:00 via Android
你说的这个不就是加载吗?操作系统帮你把加载的事情做了,远程的加载的话有分布式系统支持远程传输共享库啊,你去补一下操作系统的知识吧。
|