C 语言编译

475 阅读4分钟

1.  使用 gcc 命令

1.  可执行文件

  1.  项目结构

    exec_demo
      - bin
      - include
        - head.h
      - src
        - fun.c
      - main.c
    
  2.  文件内容

    # head.h
    int add(int a, int b);
    int sub(int a, int b);
    
    # fun.c
    #include "head.h"
    int add(int a, int b)
    {
      return a + b;
    }
    
    # main.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "head.h"
    int main(int argc, char **args)
    {
      int n1 = atoi(args[1]);
      int n2 = atoi(args[2]);
      int ret = add(n1, n2);
      printf("%d + %d = %d\n", n1, n2, ret);
    }
    
  3.  执行编译

    # 分步编译可执行文件
    1. 预处理 main.c 和 fun.c
    gcc -E main.c -I ./include -o main.i
    gcc -E src/fun.c -I ./include -o src/fun.i
    
    2. 汇编 main.i 和 fun.i
    gcc -S main.i -o main.s
    gcc -S src/fun.i -o src/fun.s
    
    3. 编译 main.s 和 fun.s
    gcc -c main.s -o main.o
    gcc -c fun.s -o fun.o
    
    4. 链接 main.o 和 fun.o (其中隐式包含了链接 libc.so 等动态库)
    gcc main.o fun.o -o bin/app
    
    # 一步编译
    gcc main.c src/fun.c -I ./include -o bin/app
    
    # 安装
    install -m 755 ./bin/app /usr/local/bin
    

2.  静态库文件

  1.  项目结构

    static_demo
      - lib
      - include
        - head.h
      - src
        - add.c
        - div.c
        - sub.c
        - mul.c
    
  2.  文件内容

    # head.h
    int add(int a, int b);
    int div(int a, int b);
    int sub(int a, int b);
    int mul(int a, int b);
    
    # add.c
    int add(int a, int b)
    {
      return a + b;
    }
    
    # mul.c
    int mul(int a, int b)
    {
      return a * b;
    }
    
    # sub.c
    int sub(int a, int b)
    {
      return a - b;
    }
    
    # div.c
    int div(int a, int b)
    {
      return a / b;
    }
    
  3.  执行编译

    # 编译源文件
    gcc -c src/add.c src/div.c src/mul.c src/sub.c -I ./include
    gcc -c src\/*.c -I ./include
    
    # 打包
    ar rcs lib/demo.lib src/add.o src/div.o src/mul.o src/sub.o (windows 下)
    ar rcs lib/demo.lib src\/*.o
    
    ar rcs lib/libDemo.a src/add.o src/div.o src/mul.o src/sub.o (linux 下)
    ar rcs lib/libDemo.a src\/*.o
    
    # 安装
    install -m 755 ./lib/libDemo.a /usr/local/lib/ (linux 下)
    
  4.  使用静态库

    # 根目录创建 main.c
    cd static_demo && touch main.c
    
    # 内容如下
    #include <stdio.h>
    #include <stdlib.h>
    #include "head.h"
    int main(int argc, char **args)
    {
      int n1 = atoi(args[1]);
      int n2 = atoi(args[2]);
      int ret = add(n1, n2);
      printf("%d + %d = %d\n", n1, n2, ret);
    }
    
    # 编译
    gcc main.c -o app -I ./include -L ./lib/ -l demo (windows 下)
    gcc main.c -o app -I ./include -L ./lib/ -l Demo (linux 下)
    

3.  动态库文件

  1.  项目结构

    share_demo
      - lib
      - include
        - head.h
      - src
        - add.c
        - mul.c
        - div.c
        - sub.c
    
  2.  文件内容

    不再赘述
    
  3.  执行编译

    # 编译 (fPIC 作用:http://tny.im/kkuoz)
    gcc -c -fPIC src\add.c src\div.c src\sub.c src\mul.c -I ./include
    gcc -c -fPIC src\/*.c -I ./include
    
    # 打包
    gcc -shared -o lib/demo.dll src\/*.o (windows 下)
    gcc -shared -o lib/libDemo.so src\/*.o (linux 下)
    
    # 安装
    install -m 755 ./lib/libDemo.so /usr/local/lib/
    
  4.  使用动态库

    # 根目录创建 main.c
    cd share_demo && touch main.c
    
    # 内容如下
    #include <stdio.h>
    #include <stdlib.h>
    #include "head.h"
    int main(int argc, char **args)
    {
      int n1 = atoi(args[1]);
      int n2 = atoi(args[2]);
      int ret = add(n1, n2);
      printf("%d + %d = %d\n", n1, n2, ret);
    }
    
    # 编译
    gcc main.c -o app -I ./include -L ./lib/ -l demo (windows 下)
    gcc main.c -o app -I ./include -L ./lib/ -l Demo (linux 下)
    
    # 额外操作
    windows 下:拷贝 demo.dll 文件到 c:/windows/system32/
    linux 下:修改 /etc/ld.so.conf
    

2. Makefile 方式

1. 可执行文件

  1. 项目结构

    exec_demo
      - bin
      - include
        - head.h
      - src
        - fun.c
      - main.c
      - makefile
    
  2. 文件内容

    # makefile
    app: main.o func.o
      gcc main.o ./src/func.o -o ./bin/app
    main.o: main.c
      gcc -c main.c -I ./include
    func.o: ./src/func.c
      gcc -c ./src/func.c -I ./include -o ./src/func.o
    clean:
      -@rm ./*.o ./src/*.o ./bin/*
    install:
      install -m 755 ./bin/app /usr/local/bin/
    
  3. 执行编译

    # 编译
    make app
    
    # 清理
    make clean
    
    # 安装
    make install
    

2. 静态库文件

  1. 项目结构

    static_demo
      - lib
      - include
        - head.h
      - src
        - add.c
        - div.c
        - mul.c
        - sub.c
      - main.c
      - makefile
    
  2. 文件内容

    # makefile
    src_dir = ./src
    dest_dir = ./lib
    include_dir = ./include
    bin_dir = ./bin
    app_name = app
    lib_name = libDemo
    lib_suffix = .lib
    objects = add.o sub.o mul.o div.o
    
    lib: ${objects}
      ar rcs ${dest_dir}/${lib_name}${lib_suffix} ${objects}
      -@rm ${objects}
    add.o: ${src_dir}/add.c
      gcc -c ${src_dir}/add.c -I ${include_dir}
    sub.o: ${src_dir}/sub.c
      gcc -c ${src_dir}/sub.c -I ${include_dir}
    mul.o: ${src_dir}/mul.c
      gcc -c ${src_dir}/mul.c -I ${include_dir}
    div.o: ${src_dir}/div.c
      gcc -c ${src_dir}/div.c -I ${include_dir}
    test: ${dest_dir}/${lib_name}${lib_suffix}
      gcc main.c -o ${bin_dir}/${app_name} -I ${include_dir} -L ${dest_dir} -l ${lib_name}
    clean:
      -@rm ${dest_dir}/* ${bin_name}/*
    install:
      install -m 755 ${dest_dir}/${lib_name}${lib_suffix} /usr/local/lib
    
  3. 执行编译

    # 编译成静态库文件
    make lib
    
    # 测试库静态库文件
    make test
    
    # 清理
    make clean
    
    # 安装
    make install
    

3. 动态库文件

  1. 项目结构

    share_demo
      - lib
      - bin
      - include
        - head.h
      - src
        - add.c
        - mul.c
        - div.c
        - sub.c
      - main.c
      - makefile
    
  2. 文件内容

    # makefile
    src_dir = ./src
    dest_dir = ./lib
    include_dir = ./include
    bin_dir = ./bin
    app_name = app
    lib_name = libDemo
    lib_suffix = .dll
    objects = add.o sub.o mul.o div.o
    
    lib: ${objects}
            gcc -shared -o ${dest_dir}/${lib_name}${lib_suffix} ${objects}
            -rm ${objects}
    add.o: ${src_dir}/add.c
            gcc -c -fPIC ${src_dir}/add.c -I ${include_dir}
    sub.o: ${src_dir}/sub.c
            gcc -c -fPIC ${src_dir}/sub.c -I ${include_dir}
    mul.o: ${src_dir}/mul.c
            gcc -c -fPIC ${src_dir}/mul.c -I ${include_dir}
    div.o: ${src_dir}/div.c
            gcc -c -fPIC ${src_dir}/div.c -I ${include_dir}
    test: ${dest_dir}/${lib_name}${lib_suffix}
            gcc main.c -o ${bin_dir}/${app_name} -I ${include_dir} -L ${dest_dir} -l ${lib_name}
    clean:
            -@rm ${dest_dir}/* ${bin_dir}/*
    install:
            install -m 755 ${dest_dir}/${lib_name}${lib_suffix} /usr/local/lib
    
  3. 执行编译

    # 编译动态库
    make lib
    
    # 测试动态库
    make test
    
    # 清理
    make clean
    
    # 安装
    make install
    

3. CMake 方式

1. 可执行文件

  1. 项目结构

    exec_demo
      - bin
      - build
      - include
      - src
      - main.c
      - CMakeLists.txt
    
  2. 文件内容

    # CMakeLists.txt
    cmake_minimum_required(VERSION 3.17)
    project(exec_demo C)
    
    set(CMAKE_C_STANDARD 99)
    set(EXECUTABLE_OUTPUT_PATH ../bin)
    include_directories(include)
    add_executable(app main.c src/func.c)
    INSTALL(TARGETS app RUNTIME DESTINATION bin)
    
  3. 执行编译

    # 进入 build 目录
    cd build
    
    # 执行cmake
    cmake ..
    
    # 编译
    make
    
    # 安装
    make install (windows 默认安装到 Cygwin/usr/local/bin linux 默认安装到 /usr/local/bin)
    
    # 自定义安装
    cmake -DCMAKE_INSTALL_PREFIX=/usr .. 
    make install (linux 指定安装到 /usr/bin)
    
    # 清理
    make clean
    

2. 静态库文件

  1. 项目结构

    static_demo
      - lib
      - bin
      - build
      - include
        - head.h
      - src
        - add.c
        - div.c
        - sub.c
        - mul.c
      - CMakeLists.txt
    
  2. 文件内容

    # CMakeLists.txt
    cmake_minimum_required(VERSION 3.17)
    project(static_lib C)
    set(CMAKE_C_STANDARD 99)
    set(LIBRARY_OUTPUT_PATH ../lib)
    
    include_directories(include)
    add_library(libDemo src/add.c src/div.c src/mul.c src/sub.c)
    INSTALL(TARGETS Demo ARCHIVE DESTINATION lib)
    INSTALL(FILES include/head.h DESTINATION include/static_lib)
    
    add_executable(app main.c)
    target_link_libraries(app Demo.a)
    
  3. 执行编译

    # 进入 build 目录
    cd build
    
    # cmake
    cmake ..
    
    # 编译
    make
    
    # 安装
    make install (windows 默认安装到 Cygwin/usr/local/lib linux 默认安装到 /usr/local/lib)
    
    # 自定义安装
    cmake -DCMAKE_INSTALL_PREFIX=/usr
    make install (linux 安装到 /usr/lib)
    
    # 清理
    make clean
    

3. 动态库文件

  1. 项目结构

    share_demo
      - bin
      - lib
      - build
      - include
        - head.h
      - src
        - div.c
        - mul.c
        - add.c
        - sub.c
      - main.c
      - CMakelists.txt
    
  2. 文件内容

    # CMakelists.txt
    cmake_minimum_required(VERSION 3.17)
    project(share_lib C)
    set(CMAKE_C_STANDARD 99)
    set(LIBRARY_OUTPUT_PATH ../lib)
    include_directories(include)
    
    add_library(Demo SHARED src/add.c src/div.c src/sub.c src/mul.c)
    INSTALL(TARGETS Demo LIBRARY DESTINATION lib)
    INSTALL(FILES include/head.h DESTINATION include/shared_lib)
    
    add_executable(app main.c)
    target_link_libraries(app Demo)
    
    
  3. 执行编译

    # 进入 build 目录
    cd build
    
    # cmake
    cmake ..
    
    # 编译
    make
    
    # 安装
    make install (windows 安装到 Cygwin/usr/local/lib linux 安装到 /usr/local/lib)
    
    # 自定义安装
    cmake -DCMAKE_INSTALL_PREFIX=/usr ..
    make install (安装到 /usr/lib)
    
    # 清理
    make clean
    

4. 参考

gcc.gnu.org/onlinedocs/…

stackoverflow.com/questions/5…

www.gnu.org/software/ma…

www.ruanyifeng.com/blog/2015/0…

cmake.org/cmake/help/…