如何用现代的手段,编译石器时代的原始码?

构建环境

弃用 CentOS 改用 Debian 来运行服务端,Debian 相对将要停止维护的 CentOS 而言是更好的选择,而且常听到的 Ubuntu 也是其分支,版本则採用 buster,也就是当前最稳定的版本,加上编译 C 所需要的套件,于是我直接在 Dockerhub 上找封装好的 Docker Image 来用,我们可以从其 Dockerfile(定义档)中知道装了哪些套件。


资料库部分,由于 MySQL 已经被 Oracle 收购,开源社群转而投向保持著和 MySQL 有高度相容性且更为开放的 MariaDB 的怀抱,也因此我们直接选用 MariaDB 作为资料库引擎。


排除问题

首先我遇到的第一个问题,就是在非 c99 标准之下不允许我们在 for loop 中宣告变数。

for (int i=1;i<10;i++) { // error

int i;
for (i=1;i<10;i++) {  // ok

虽然直接改 Code 就可以解决,但是因为要改的太多,所以选择直接在 CMake 设定档中加上 flag,就可以启动 c99 标准而顺利编译。

CMakeLists.txt

macro(use_c99)
  if (CMAKE_VERSION VERSION_LESS "3.1")
    if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
      set (CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
    endif ()
  else ()
    set (CMAKE_C_STANDARD 99)
  endif ()
endmacro(use_c99)


第二个问题就是当我们使用 MariaDB 的时候,在编译阶段编译器会告诉我们找不到 mysql/mysql.h ,这很明显是因为我们换了资料库,所以相应的函式库也得调整。


saac/src/sasql.c

#include <mysql/mysql.h> // error

#include <mariadb/mysql.h> // ok


saac/CMakeLists.txt

target_link_libraries(saac mysqlclient) // error

target_link_libraries(saac mariadbclient) // ok



部署服务

最后就是把服务串连起来,服务端的架设就算完成了,这边我们写了 docker-compose.yml(定义档),简单来说就是把服务的 Port、关联性以及设定都写进定义档中,而这种将系统架构用 YAML 或 Code 的方式描述,就是所谓的 Infrastracture as code(IaC)。


这样做的好处就是只要一个指令就可以完整的启动服务端,因为在透过定义档启动后,事情都会交由工具本身去做,这边是利用 Docker Compose 来完成。


docker-compose.yml

version: '3.5'

services:
  net:
    image: alpine:3.7
    network_mode: bridge
    ports:
      - 9065:9065
    command: tail -f /dev/null
    restart: always
  gmsv:
    image: tonypai/sa25_gmsv
    network_mode: service:net
    depends_on:
      - saac
    command: /bin/bash -i ./wait-for-it.sh 127.0.0.1:9300 -- ./gmsv
  saac:
    image: tonypai/sa25_saac
    network_mode: service:net
    depends_on:
      - db
    command: /bin/bash -i ./wait-for-it.sh 127.0.0.1:3306 -- ./saac
  db:
    image: mariadb:10
    network_mode: service:net
    volumes:
      - db-data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_DATABASE: sa
      MYSQL_USER: user
      MYSQL_PASSWORD: pass
      MYSQL_ROOT_PASSWORD: admin

volumes:
  db-data:

结论

如果大家想玩看看的话,先去下载 Docker Desktop 把 Docker 环境建置起来,建立 docker-compose.yml 定义档。


然后下一行指令服务端就启动完成了。

docker-compose up gmsv saac


发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。