changed 4 years ago
Linked with GitHub

如何用現代的手段,編譯石器時代的原始碼?

tags: misc

分成三個段落:

  • 構建環境
  • 排除問題
  • 部署服務

構建環境

棄用 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

🎬 展示影片
👉 專案下載

(題外話:我手上的 2.5 版似乎有 bug,耐久力/氣力恢復藥沒辦法使用 QQ)

Select a repo