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

C 语言开发后的软件如何分发?

  •  1
     
  •   SystemLight · 2021-03-08 10:42:58 +08:00 · 4655 次点击
    这是一个创建于 1364 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • windows 中开发编译后是否可以直接放到 linux 中运行
    • 如果有 cmake 做编译管理是不是需要把整个构建包放到目标主机再构建
    • 可不可以在 windows 上面编译出所有平台都可执行的 exe
    36 条回复    2021-03-10 11:30:31 +08:00
    dorothyREN
        1
    dorothyREN  
       2021-03-08 10:53:30 +08:00   ❤️ 1
    交叉编译
    pursuer
        2
    pursuer  
       2021-03-08 10:55:26 +08:00
    1 、没 wine 这样的模拟不行
    2 、可以
    3 、可以,但是平台很多,你需要编译出很多个版本,对应各种 CPU,ABI 和操作系统,如果动态链接了其他库 glibc 等,你可能还会碰到这些库的版本问题。。
    afirefish
        3
    afirefish  
       2021-03-08 11:09:54 +08:00
    建议 docker
    nightwitch
        4
    nightwitch  
       2021-03-08 11:12:18 +08:00
    1. 直接编译不可以,交叉编译可以
    2. 如果你有交叉编译工具链,那么可以在本机编译,目标主机运行
    3. 可以,但是需要很多 C 语言语法之外的知识,包括静态链接和动态链接,目标系统的 ABI 和目标平台的 CPU 架构和指令集等,并且最好需要你有目标平台的机子测试。
    northisland
        5
    northisland  
       2021-03-08 11:14:12 +08:00   ❤️ 2
    没有按照跨平台方法弄出来的 c 程序,要搞成跨平台,多半有很长的路。

    看楼主的问题,感觉是从 0 开始。建议找个专门弄 c / c++的来弄这个吧。
    qzhsjz
        6
    qzhsjz  
       2021-03-08 11:20:51 +08:00
    如果你的需求仅仅在于 Windows 和 Linux 跨平台的话,那么你可以在 Windows 上使用 Linux 的工具链进行开发。如 CygWin 或 WSL 等。并且编译后的程序,如果是完全静态编译的话,理论上应该是可以在和 Windows 同架构的纯 Linux 系统上直接运行的。
    但是你的需求如果涉及到其他方面,比如你在 Windows 上搞开发,但目标机器是个 ARM 或者 MIPS 或者 RISC-V 之类的,那么你在 x86 的 Windows 开发机上写程序测试倒是没有问题,但是最终运行是一定要想办法编译一个目标机器的版本才可以,也就是楼上们说的交叉编译。
    nevin47
        7
    nevin47  
       2021-03-08 11:21:41 +08:00
    LZ 的问题看上去对编译和 C 语言都不熟悉,建议看看基础的内容,或者找懂得人手把手教一下
    misaka19000
        8
    misaka19000  
       2021-03-08 11:21:55 +08:00
    交叉编译可以直接扔到 CI 平台去做吧?
    QBugHunter
        9
    QBugHunter  
       2021-03-08 11:27:21 +08:00
    1. 可以,但除非有决定的必要,否则这是给自己找麻烦,C/C++讲究的是一次编写,到处编译,而不是一次编译,到处运行。交叉编译一般是因为目标机器缺乏编译环境(通常是嵌入式设备)

    2.可以

    3 同 1,可以,但除非有绝对的必要(如目标机器缺乏编译环境,锻炼自己交叉编译水平),否则不要这么干
    pkookp8
        10
    pkookp8  
       2021-03-08 12:02:49 +08:00 via Android
    @QBugHunter 我觉得你说的 1 不对,64 位机编译同 cpu 的 32 位程序,你能说你缺少编译环境(硬件)吗
    如果你有一份源码,需要编译出 4-5 个平台的软件。

    最方便的应该是配置一套编译环境,编译 4-5 种软件
    而不是部署 4-5 个平台,clone 4-5 次代码,再去编译自己的软件

    @misaka19000
    CI 本质还是你写的脚本吧,当然可以交给 CI
    shuax
        11
    shuax  
       2021-03-08 13:03:34 +08:00
    建议改成 golang
    3dwelcome
        12
    3dwelcome  
       2021-03-08 13:17:44 +08:00
    @pkookp8 Cross-Compile 没那么完美,我就遇到过 ffmpeg 编译 elf 的时候,遇到文件句柄管道重定向的问题。可能和交叉编译工具链里面的链接库有关系,但是问题查起来就很复杂。
    简单的多平台算法移植,可能没问题。因为依赖库很少。
    ch2
        13
    ch2  
       2021-03-08 13:20:16 +08:00
    一次编写到处运行,仅限于脚本
    C 语言是多次编写,多次编译,针对每个具体的目标版本都要有不同的处理
    Jirajine
        14
    Jirajine  
       2021-03-08 13:22:55 +08:00 via Android
    工具链用这个 musl.cc 一般用来编译其他语言的 c 依赖。
    当然依赖管理和 build system 要自己处理。
    SystemLight
        15
    SystemLight  
    OP
       2021-03-08 14:53:02 +08:00
    @afirefish 但是是一个 GUI 软件,用 docker 可以把 GUI 界面显示到宿主机上么
    afirefish
        16
    afirefish  
       2021-03-08 15:34:12 +08:00
    @SystemLight 这就涉及我的知识盲区了,如果是无 GUI 的话,docker 是可行的。不是无 GUI 的,还是交差编译各个平台的吧。
    AndyAO
        17
    AndyAO  
       2021-03-08 16:48:28 +08:00
    无论什么语言,要做跨平台,比较轻松的方法就是从最初就是做,否则的话会蹩脚不堪[^1],甚至不如推倒重来。当然重来不意味着,之前做的工作全部都要重复,毕竟还有很多的设计思想和模式,甚至很多的代码段可以直接用。[^2]

    [^1]: PETERSEIBEL. 编程人生:15 位软件先驱访谈录[M]. 人民邮电出版社, 2011.

    如果你打算发布跨平台产品,历史会告诉你绝不要抱着“以后再移植”这样的想法。真想做到跨平台的话,就必须同时开发。所谓的移植只会令产品在第二平台上蹩脚不堪。 —— Jamie Zawinski

    [^2]: 格拉斯. (2006). 软件工程的事实与谬误 = Facts and fallacies of software engineering. 中国电力出版社.

    到目前为止,有关复用的讨论都相当让人失望。小规模复用已经有超过 45 年的历史了,其中的问题已经得到很好的解决。大规模复用问题似乎难以解决,只不过对于相似的问题有一点希望。修改可复用组件通常非常困难,不是一种非常好的方法。那么,当程序员面对一个新问题时,如何能避免彻底从头再来?软件实践者常用的方法之一是根据以往问题的处理方法来解决当前的问题。
    linusyang
        18
    linusyang  
       2021-03-08 17:08:52 +08:00   ❤️ 3
    C 语言一次编译到处运行?当然可以!🤪

    https://github.com/jart/cosmopolitan
    https://news.ycombinator.com/item?id=25556286
    https://justine.lol/ape.html

    实验性质的 libc,可以生成 Windows 可执行的 PE 格式二进制,在 unix 上借助 shell 跨平台。
    UserDMM
        19
    UserDMM  
       2021-03-08 17:18:09 +08:00
    @SystemLight
    要到到处都可以编译和运行
    首先,要用跨平台编译编译工具,如:CMake,QMake 这类
    其次,代码也要还是跨平台的,不能用单个平台私有的 API,跨平台的库很多,boost,qt 等
    最后,祝你好运!
    helloworld2076
        20
    helloworld2076  
       2021-03-08 18:39:11 +08:00 via iPhone
    感觉楼主经验为 0,还是和领导说下,招个人吧。
    也算增加了一个就业岗位。
    secondwtq
        21
    secondwtq  
       2021-03-08 19:27:57 +08:00
    @pkookp8 理论上是这样,但是实际做起来不仅要在多个平台上编译,还要在多个平台上测试。
    这样就必然会有多个平台的环境。

    然后“来都来了”,测试平台都有了,再弄个编译平台也不多。
    fighterhit
        22
    fighterhit  
       2021-03-08 19:50:05 +08:00
    百度网盘
    fovecifer
        23
    fovecifer  
       2021-03-08 20:01:36 +08:00
    打包成 rpm 或者 deb 啊 这是标准的分发方式
    zhuangzhuang1988
        24
    zhuangzhuang1988  
       2021-03-08 20:08:35 +08:00
    vcpkg
    SheehanChen
        25
    SheehanChen  
       2021-03-08 20:16:47 +08:00
    @SystemLight docker 运行 GUI 的话可以试试 run 的时候加这两条 -e DISPLAY=$DISPLAY -e QT_X11_NO_MITSHM=1 -v /tmp/.X11-unix:/tmp/.X11-unix
    Jooooooooo
        26
    Jooooooooo  
       2021-03-08 20:32:23 +08:00
    换成 go 吧.
    wolong
        27
    wolong  
       2021-03-08 20:51:38 +08:00
    不好使,虽然可以交叉编译,但是总会遇到这样那样的问题。
    楼主你看那些开源软件,release 文件一般都是给出两个 exe ( x86 和 x86_64 ),一个 dmg 。linux 上的一般都是给的源代码,让用户自己去编译,也有给编译好的,但是都打包成 deb 格式,而且都是很老的版本。比如说你源代码最新版本是 1.10 ,deb 版本可能只有 1.05 。
    windows 上还好说,编译成 exe,大多数电脑都可以直接运行。linux 版本太多太复杂了,测试成本太高,如果要编译好再分发,至少也要在一两个主流发行版上编译测试吧。
    csvips
        28
    csvips  
       2021-03-08 21:08:41 +08:00
    目前主流的方式是一套代码,不同平台编译。交叉编译固然可以,但是复杂度远比直接换平台编译搞得很多。有一些跨平台的库,能解决平台相关的问题,比如 QT 什么的。或者只用基础库。就可以一套代码在不同平台编译。当然,鉴于你的第三个问题,可以断定你并不了解操作系统。
    nurex
        29
    nurex  
       2021-03-08 21:41:47 +08:00
    软件分发的话一般也就是二进制或者源代码。
    关于这三个问题,回答依次是:
    不能(除非交叉编译+静态链接,动态链接都可能出问题)
    是的
    理论上可以,但现在 Windows 平台主要也就 x86 和 ARM,单独编译成本也不大
    (真的建议楼主稍微补一下这方面的知识,不然到时候做移植会很痛苦的)
    mingl0280
        30
    mingl0280  
       2021-03-09 02:15:45 +08:00 via Android
    1 巨坑(指 Linux 有时候跨个版本都能给你整出 ABI 不兼容,能搞疯人),2 可以但是坑也不小(我在上班的时候其中一个工作就是干这个,需要平台匹配的 CMakeLists ),3 可以但是也是巨坑划不来。
    综上我司用的方案是闭园部分,平台( Windows/Linux )专用两套 CMakeList+Jenkins 自动编译+CMake 打包( Linux )/NSI 打包(Windows),客户示例代码因为简单所以直接跨平台 CMakeLists
    waruqi
        31
    waruqi  
       2021-03-09 07:49:26 +08:00 via Android
    可以用 xmake 解决交叉编译工具链 自己所有包依赖问题
    xsen
        32
    xsen  
       2021-03-09 09:20:50 +08:00
    1. 不现实
    2. 可以
    3. 不现实

    注:不现实的意思就是,基本没有人这么做;除了部分用来做嵌入式开发的除外(因为第三方库及工具链都是单独编译的)
    no1xsyzy
        33
    no1xsyzy  
       2021-03-09 10:18:16 +08:00
    @SystemLight #15 docker GUI 有若干方法,排名不分先后
    1. 可以写个 Web API 然后去搞 Web 界面,那可是相当地跨平台。
    2. http://wiki.ros.org/docker/Tutorials/GUI 基本上挺全的了。
    16fat
        34
    16fat  
       2021-03-09 11:44:24 +08:00
    1.不建议
    2.如果某些模块不想暴露源码的,可以先编译成.a 或者.so ,整个工程可以用 cmake 进行管理;然后一般可以在 docker 上用专门的编译机器生成目标文件
    3.不建议
    SystemLight
        35
    SystemLight  
    OP
       2021-03-10 10:53:14 +08:00
    @no1xsyzy WEB 当然很简单,甚至 electron 打包也可以,但是都不考虑,只为了在 C 平台开发而开发,木有办法
    no1xsyzy
        36
    no1xsyzy  
       2021-03-10 11:30:31 +08:00
    @SystemLight C 平台也可以写 Web API,然后套 WebUI,参考 aria2 的成套体系,最典型的 C application + HTTP API + WebUI 。
    怪异的:emscripten (
    不然就是 2,说了很多方法,不过几乎都是 graphics over network
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2453 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 04:45 · PVG 12:45 · LAX 20:45 · JFK 23:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.