V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhng920823
V2EX  ›  C

一个简单实用的 C 工程示例, 附简洁的 Makefile

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

    Makefile 可以做到如下简洁, 实际用时只要修改 EXE 和 OBJ 的列表值, 无需关心其它的东西

    EXE=\
    exe1\
    a/exe2\
    a/exe3\
    
    OBJ=\
    mod1\
    liba/mod2\
    liba/mod3\
    
    include inc.mak
    

    工程源码 https://github.com/webd90kb/webd/tree/master/codes/c_project_template

    27 条回复    2024-07-09 17:53:37 +08:00
    augustheart
        1
    augustheart  
       145 天前
    看了一下,分享精神可嘉,不过聊胜于无吧,用处很狭窄。
    实际上照本宣科写个 makefile ,目录分好。然后一个通配符也差不多效果了,最后每次就拷贝这 makefile ,修改一下输出目标名。
    w568w
        2
    w568w  
       145 天前   ❤️ 4
    要我说 Makefile 这种东西早就应该扔进历史垃圾桶了。

    多亏了 Autotools 家族:

    1. 直到今天 C/C++ 项目的构建和编译还是充满了不在文档中的命令行参数、不知名的环境变量、随心所欲的模块管理和依赖地狱;
    2. 甚至每个项目都不得不自己编写一个 INSTALL 或 BUILD 文档来专门教别人如何编译;
    3. Autotools 既不通用也不思进取,直到今天依然和 GCC 、glibc 强绑定,AM 宏语法残缺不全、极难理解,并且只支持「 GNU 认为你只需要」的寥寥几门语言和功能,充满了 quirks ,和其他语言的互操作更是无解问题。说是公共构建工具,更像是一群 geeks 自己开发自娱自乐的产物;
    4. Makefile 完全没有考虑不同 Shell 和 Platform 的问题,想要跨平台编译,开发者不得不自己考虑并编写几百行的 boilerplates 来适配新的构建平台(例如 Windows )。

    CMake is better, and Meson is even better.

    如果你需要一个命令行运行器,你应该用 just 或 ninja 。
    zhng920823
        3
    zhng920823  
    OP
       145 天前
    @w568w #2 所以不用 Autotools 那套东西, 直接用 Makefile, 我这个 Makefile 也可以同时用在 windows 上的 mingw
    zhng920823
        4
    zhng920823  
    OP
       145 天前
    @augustheart #1 这个是从我自己用的项目里抽出来的, 可以一个工程里多个可执行文件, 久而久之这个工程里的东西就越来越多越来越杂, 依赖关系越来复杂, 编译越来越慢. 因为每一个 EXE 依赖所有的 OBJ.
    w568w
        5
    w568w  
       145 天前
    @zhng920823 是啊,我知道可以用,我自己也不是没干过这事。后来换到 CMake 、Meson 才发现:干,这些事原来根本不用自己操心维护。Makefile 里判断平台大多是白忙活!

    别人写了十几年的轮子了,兼容性自然远高于我们手写的几行 Makefile 。与其遇到一个不兼容问题修复一个,不如直接用现代化构建工具。

    另外,只有第 3 个缺点和 autotools 有关啊,1 、2 、4 点 Makefile 都有。
    zhng920823
        6
    zhng920823  
    OP
       145 天前
    @w568w #5 一直不太喜欢 cmake 等这种"大"公司推行的东西
    我觉得 xmake 非常好, @waruqi 但是 xmake 没有很广泛流行开来.
    w568w
        7
    w568w  
       145 天前
    @zhng920823 #6 CMake 被大公司推行的好处是能统一。另外,Meson 作为纯社区项目,其实没有被大公司裹挟吧?

    我也喜欢 xmake ,还贡献过代码。xmake 的问题可能是包装得太深了,想要做一些自定义很困难,以及没有一个 CMake 级别的 behavior reference 文档。
    zhng920823
        8
    zhng920823  
    OP
       145 天前
    @w568w #7 我也觉得 xmake 搞的越来越强大了, 早期简单的版本就够用.
    Meson/Ninja 目前看来还行.
    个人而言, 还是继续坚持手写 Makefile, 我觉得这样最透彻, (或者说是和已有项目绑定太深)
    ipwx
        9
    ipwx  
       145 天前   ❤️ 1
    @zhng920823 我曾经也排斥用别人包了一层又一层的东西,觉得什么东西都自己写底层很舒服。

    直到我毕业了,从兴趣驱动到工资驱动……
    augustheart
        10
    augustheart  
       145 天前
    @zhng920823 xmake 是愿景太大了,它想覆盖的每个场景都会有很多具体问题,需要各种针对修正。比如我个人的场合比较非主流,就是 msys2 那套在 win 下面编译,前后就提了好些 issue 。(其实最严重的问题是文档失修)
    至于 makefile ,没必要坚持,早改早好。makefile 所代表的那点知识没啥好透彻的。
    GeruzoniAnsasu
        11
    GeruzoniAnsasu  
       145 天前
    我就提一个小问题:

    怎么写单元测试?
    zhng920823
        12
    zhng920823  
    OP
       145 天前
    @GeruzoniAnsasu #11 再加个 exe, 或者现有的 exe 里面根据参数进入测试分支.
    zhng920823
        13
    zhng920823  
    OP
       145 天前
    @augustheart #10 不是说 makefile 的知识透彻, 而是说这套东西简单透彻,
    GeruzoniAnsasu
        14
    GeruzoniAnsasu  
       145 天前
    @zhng920823

    10 个 lib source, 10 个单测 source

    我需要写 _ 个 makefile, 每个 makefile 里复制粘贴 _ 行 source

    新增 1 个 lib source 的时候 我需要修改 _ 个文件中的 _ 行?
    zhng920823
        15
    zhng920823  
    OP
       145 天前
    @GeruzoniAnsasu #14
    10 个 lib source, 10 个单测 source
    我需要写 1 个 makefile, 每个 makefile 里复制粘贴 20 行 source
    新增 1 个 lib source 的时候 我需要修改 1 个文件中的 1 行

    不过我还有一套和 IDE 结合的工具, 能把这些工作自动化. 这个 Makefile 是单独提取出来展示给大家的.
    cnbatch
        16
    cnbatch  
       144 天前
    虽然我也不那么喜欢 cmake ,但更不喜欢 GNU Makefile ,因为我需要兼顾 BSD 系统( BSD Makefile 稍有不同),所以最后还是要用 cmake 兜底
    proxytoworld
        17
    proxytoworld  
       144 天前
    我用 xmake 尝试引入 cmake ,但编译错误,搞了半天,太难了,最后还是用了 cmake 的 hunter
    424778940
        18
    424778940  
       144 天前
    makefile 早就该被淘汰了, 又是写他都不如写个 shell 脚本方便, 或者说这东西就是个特别一点的 shell 脚本
    makefile, 尤其是 autotools 沾边的, 语法奇怪, 文档残废, 每次改点啥都要进去看代码, 因为变量名和选项都没有标准

    我现在一律使用 cmake, 虽说也没有特别先进, 有些地方还是有"无法指定这个操作到底 config 还是 build 时候执行"的问题, 但配合任何 shell 脚本基本都能解决 90%以上的场景需求了

    楼主你这个 makefile, 用 cmake 应该不到一半的行数就能写完
    zhng920823
        19
    zhng920823  
    OP
       144 天前
    @proxytoworld #17 可惜 xmake 不能直接支持 cmake

    @424778940 #18 Makefile 肯定比 shell 方便的, 这点不用质疑, 毕竟是专门干这个的.
    所以我说 Makefile\可以单独使用, 不碰 autotools 那些东西可以做到很简单的.
    augustheart
        20
    augustheart  
       144 天前
    @proxytoworld 通过 xmake 调用 cmake ,其实只是把传给 cmake 的参数给复制过去就好了,xmake 使用 package.tools.cmake ,等价于通过命令行调用 cmake 。需要注意的只有环境问题( xmake 的执行环境和 cmake 的执行环境并不一定是一样的)。
    zhng920823
        21
    zhng920823  
    OP
       144 天前
    @augustheart #20 我的意思是 xmake 不能在没有 cmake 的情况下编译简单的 cmake 工程, 一直没这个功能
    augustheart
        22
    augustheart  
       144 天前
    @zhng920823 哦,那是自然的。想替代 cmake 就得解析 cmake 那一大坨东西,这个工作量比 xmake 本身还大
    我个人觉得 xmake 现在这个状态已经很合我用了,写个东西各种不同编译方式的库能在同一个方案下面集成到一起,挺方便。
    zhng920823
        23
    zhng920823  
    OP
       144 天前
    @augustheart #22 也没必要支持 cmake 的全部特性, 一些项目的 CMakelists.txt 看着非常简单的, 只要能支持这种的编译就行.

    那些导出各种工程的功能很少用的
    yolee599
        24
    yolee599  
       144 天前 via Android
    我用的 cmake ,就因为 cmake 大家都用,生态比较好,比如 esp-idf ,lvgl ,mbedtls ,lwip …… 都在用
    zhng920823
        25
    zhng920823  
    OP
       144 天前
    @yolee599 # 活捉使用 lwip lvgl 的大佬
    hitmanx
        26
    hitmanx  
       144 天前
    我工作中遇到的项目 cmake 通常都是比较复杂的,各种 custom command 、custom target 乱飞,调用各种工具、python 等等生成中间文件,再由中间文件生成其它的中间文件等等,再加上 cmake 的字符串操作、对文件系统的操作,以及各种平台*feature list 的排列组合等等……需要理解大量业务逻辑才能明白这个工作流程。

    相比之下,新增文件时要更新一个文件列表,或者指定一个库的依赖等等,反而是其中最简单的环节,并不需要费太多的脑细胞。

    在这种复杂的系统里,用的 build 的语言是否足够“expressive”,让读的人能轻易明白你想干什么变得更关键了。另外就是效率,现在每改一行 cmake ,重新 config 一次要好几分钟……
    zhng920823
        27
    zhng920823  
    OP
       143 天前
    @hitmanx #26 一般太复杂的东西, 我会选择用 shell 或其它语言的脚本进行额外处理, 而不是融合进 build 系统里面.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2843 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 09:00 · PVG 17:00 · LAX 01:00 · JFK 04:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.