diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 00000000..f550923b --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,23 @@ +{ + "version": 4, + "env": { + "myDefaultIncludePath": [ + "${workspaceFolder}/src", + "${workspaceFolder}/src/ege" + ] + }, + "configurations": [ + { + "name": "default", + "cStandard": "c11", + "cppStandard": "c++17", + "defines": [ + "_FORTIFY_SOURCE=0" + ], + "includePath": [ + "${myDefaultIncludePath}" + ], + "configurationProvider": "ms-vscode.cmake-tools" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..a1fa6a26 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,144 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Load CMake Project", + "type": "shell", + "command": "bash", + "args": [ + "-l", + "tasks.sh", + "--debug", + "--load" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "Reload CMake Project", + "type": "shell", + "command": "bash", + "args": [ + "-l", + "tasks.sh", + "--debug", + "--reload" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "Cleanup CMake Project", + "type": "shell", + "command": "bash", + "args": [ + "-l", + "tasks.sh", + "--clean" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "Build XEGE Library", + "type": "shell", + "command": "bash", + "args": [ + "-l", + "tasks.sh", + "--debug", + "--build" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "Build Demos", + "type": "shell", + "command": "bash", + "args": [ + "-l", + "tasks.sh", + "--debug", + "--target", + "demos", + "--build" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "Load And Build XEGE Library", + "type": "shell", + "command": "bash", + "args": [ + "-l", + "tasks.sh", + "--debug", + "--load", + "--build" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "Load And Build Demos", + "type": "shell", + "command": "bash", + "args": [ + "-l", + "tasks.sh", + "--debug", + "--target", + "demos", + "--load", + "--build" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "group": "build", + "problemMatcher": "$gcc" + }, + { + "label": "Run Demo - GraphicsTest", + "type": "shell", + "command": "bash", + "args": [ + "-l", + "tasks.sh", + "--debug", + "--target", + "graphicstest", + "--build", + "--run", + "graphicstest.exe", + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "group": "build", + "problemMatcher": "$gcc" + } + ] +} \ No newline at end of file diff --git a/BUILD.md b/BUILD.md index 191c4312..b298321c 100644 --- a/BUILD.md +++ b/BUILD.md @@ -22,42 +22,51 @@ Linux 环境下运行相关程序需要使用 [wine](https://www.winehq.org/) 函数库顶替配置,方便起见,可以添加 `-static` 配置编译,免去配置过程(`CMakeLists.txt` 中在 Linux 环境下默认开启)。 -## 常见部分 Linux 发行版安装编译运行环境 +## 常见部分 Linux 发行版以及 MacOS 安装编译运行环境 + ```sh # Ubuntu 16.04及以上发行版 sudo apt-get install mignw-w64 wine # Arch Linux sudo pacman -S mingw-w64 wine + +# MacOS +brew install mingw-w64 wine ``` ## 基本编译步骤 1. 创建 build 文件夹并设为当前目录 + ```sh - $ mkdir build - $ cd build + mkdir build + cd build ``` 2. 执行 `cmake` 命令生成编译配置文件 + ```sh - $ cmake .. [编译配置] + cmake .. [编译配置] ``` `[编译配置]` 指定特定的编译平台,将在后文详述。 3. 进行编译 + ```sh - $ cmake --build . + cmake --build . ``` 编译过程将在 `build` 目录下生成相应的静态库文件。 如果想在完成编译后使用其它编译器再次编译,请先清空 `build` 目录,CMD 命令为 + ```sh -$ for /D %d in (*) do @rmdir %d /S /Q -$ del * /S /Q +for /D %d in (*) do @rmdir %d /S /Q +del * /S /Q ``` + 清空目录后再从步骤 2 继续执行。 ## 编译配置 @@ -67,7 +76,7 @@ $ del * /S /Q ### MinGW ```sh -$ cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release +cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release ``` CMake 会自动检测安装的 MinGW 编译器并生成编译配置。 @@ -79,12 +88,15 @@ CMake 会自动检测安装的 MinGW 编译器并生成编译配置。 前设置 `PATH` 环境变量指向特定的 MinGW 所在位置,CMake 在配置时会采用最先 在 PATH 中检测到的编译器进行编译。例如,Dev-C++ 安装目录为 `C:\Dev-Cpp`,则 在 CMD 中执行以下命令: + ```cmd -$ set PATH="C:\Dev-Cpp\MinGW64\bin";%PATH% +set PATH="C:\Dev-Cpp\MinGW64\bin";%PATH% ``` + 在 PowerShell 中则是: + ```ps -$ $env:PATH="C:\Dev-Cpp\MinGW64\bin;$env:PATH" +$env:PATH="C:\Dev-Cpp\MinGW64\bin;$env:PATH" ``` 注意,CodeBloks 附带的 MinGW 只能在 @@ -98,15 +110,19 @@ CodeBlocks 会自动识别已安装的 TDM-GCC。 64 位 MinGW 支持编译 32 位目标,要想达到这一效果,在以上步骤中设置 `PATH` 环境变量 之后,执行 `cmake` 之前需要设置 `CC` 和 `CXX` 环境变量。在 CMD 中命令为: + ```cmd -$ set CC="gcc -m32" -$ set CXX="g++ -m32" +set CC="gcc -m32" +set CXX="g++ -m32" ``` + 在 PowerShell 中为: + ```ps -$ $env:CC="gcc -m32" -$ $env:CXX="g++ -m32" +$env:CC="gcc -m32" +$env:CXX="g++ -m32" ``` + 之后再执行 `cmake .. -G "MinGW Makefiles"` 命令。 #### MSYS Makefiles 配置 @@ -115,12 +131,15 @@ $ $env:CXX="g++ -m32" 所需要的命令和上面描述的没有区别,但需要把 CMD 或 PowerShell 命令换成 Bash 命令, 比如设置环境变量: + ```sh -$ export PATH=/C/Dev-Cpp/MinGW64/bin:$PATH +export PATH=/C/Dev-Cpp/MinGW64/bin:$PATH ``` + 相应的 CMake 生成指令是 + ```sh -$ cmake .. -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release +cmake .. -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release ``` 注意,您需要从 `pacman` 包管理器安装或者 @@ -129,7 +148,6 @@ $ cmake .. -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release 扩展阅读:[Windows 上的编译系统](https://www.chirsz.cc/blog/2020-03/compile-sys-on-win.html) - ### Visual C++ 6.0 CMake 自 3.6 后停止了对生成 VC6 项目的支持,但仍可生成 NMake 编译系统以支持 VC6 编译。 @@ -139,6 +157,7 @@ CMake 自 3.6 后停止了对生成 VC6 项目的支持,但仍可生成 NMake `VC6PATH\VC98\Bin` 文件夹中的 `VCVARS32.BAT` 文件中开始部分的内容应和 `VC6PATH` 相一致,例如安装到 `D:\VC6` 的 VC6,在 `D:\VC6\VC98\Bin\VCVARS32.BAT` 中的开头部分 应当是: + ```bat rem Root of Visual Developer Studio installed files. rem @@ -149,17 +168,21 @@ rem Root of Visual C++ installed files. rem set MSVCDir=D:\VC6\VC98 ``` + 不一致的情况常出现于免安装版 VC6,此时需修改 `VCVARS32.BAT` 内容使其与 VC6 实际所在 目录一致。 确认 `VCVARS32.BAT` 内容正确后,在 EGE 源码的 `src\build` 目录下执行此批处理文件, 在上面的例子中就是执行: + ```sh -$ "D:\VC6\VC98\Bin\VCVARS32.BAT" +"D:\VC6\VC98\Bin\VCVARS32.BAT" ``` + 执行成功后即建立 VC6 命令行环境,就可以继续执行编译步骤二了: + ```sh -$ cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release +cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ``` 编译配置中的 `-DCMAKE_BUILD_TYPE=Release` 是构建类型(Build type),表示生成优化级别较高的 @@ -173,18 +196,21 @@ $ cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release VS2019 则与所在平台一致。可选的参数有 `Win32`,`x64`,`ARM`,`ARM64`。 因此编译 32 位 EGE 库需要执行: + ```sh -$ cmake .. -G "Visual Studio 14 2015" -A Win32 +cmake .. -G "Visual Studio 14 2015" -A Win32 ``` 编译 64 位 EGE 库: + ```sh -$ cmake .. -G "Visual Studio 14 2015" -A x64 +cmake .. -G "Visual Studio 14 2015" -A x64 ``` 另外要注意的一点是,Visual Studio 的步骤三应该是: + ```sh -$ cmake --build . --config Release +cmake --build . --config Release ``` 因为 Visual Studio 是多配置的编译系统,需要在执行编译时选择配置类型(Configuration type)。这 @@ -198,7 +224,7 @@ $ cmake --build . --config Release 项目 CMake 配置中设置了 `demos` 目标,编译时通过 `--target` 或 `-t` 指定,即在编译项目时执行: ```sh -$ cmake --build . --target demos +cmake --build . --target demos ``` 即可在构建目录下的 `demo` 文件夹中生成各可执行文件。 @@ -259,4 +285,4 @@ int main(int argc, char const *argv[]) 在 Linux 系统下,编译依赖 EGE 的程序,同样要使用 `mingw-w64` 工具链中的 `g++`,并且根据 环境可能需要添加额外的编译参数 `-D_FORTIFY_SOURCE=0` (参考链接 [undefined reference to `__memcpy_chk'](https://github.com/msys2/MINGW-packages/issues/5868)。 -为了简化单文件编译指令,EGE 根目录下提供了 `ege_g++.sh` 脚本,可按需使用。 +为了简化单文件编译指令,EGE 根目录下提供了`ege_g++.sh` 脚本,可按需使用。 diff --git a/tasks.sh b/tasks.sh new file mode 100755 index 00000000..987c942e --- /dev/null +++ b/tasks.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash + +cd "$(dirname "$0")" +PROJECT_DIR=$(pwd) + +CMAKE_VS_DIR="$PROJECT_DIR/build" + +# 如果是在 vscode 里面调用, 那么不给错误码, 否则会导致 vscode tasks 无法正常执行任务并显示错误. + +if [[ "$TERM_PROGRAM" =~ vscode ]]; then + export EXIT_WHEN_FAILED=false +else + export EXIT_WHEN_FAILED=true +fi + +export BUILD_TARGET="xege" # 默认只构建 xege 静态库 + +# 默认开Release模式 +export CMAKE_BUILD_TYPE="Release" +function MY_CMAKE_BUILD_DEFINE() { + echo "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" +} + +if ! command -v grealpath && command -v realpath; then + function grealpath() { + realpath $@ + } +fi + +function isWsl() { + [[ -d "/mnt/c" ]] || command -v wslpath &>/dev/null +} + +function isWindows() { + # check mingw and cygwin + isWsl || [[ -d "/c" ]] || [[ -d "/cygdrive/c" ]] +} + +function isMacOS() { + [[ "$(uname)" == "Darwin" ]] +} + +function loadCMakeProject() { + if mkdir -p "$CMAKE_VS_DIR" && + cd "$CMAKE_VS_DIR" && + cmake "$(MY_CMAKE_BUILD_DEFINE)" \ + ..; then + echo "CMake Project Loaded!" + else + echo "CMake Project Load Failed!" + exit 1 + fi +} + +function cmakeCleanAll() { + pushd $PROJECT_DIR + git clean -ffdx build + popd +} + +function reloadCMakeProject() { + cmakeCleanAll && loadCMakeProject +} + +function cmakeBuildAll() { + pushd "$CMAKE_VS_DIR" + if isWindows; then + + if [[ -n "$CMAKE_BUILD_TYPE" ]]; then + export WIN_CMAKE_BUILD_DEFINE="--config $CMAKE_BUILD_TYPE" + fi + + echo start: cmake.exe --build . --target "$BUILD_TARGET" $WIN_CMAKE_BUILD_DEFINE -- /m + # ref: https://stackoverflow.com/questions/11865085/out-of-a-git-console-how-do-i-execute-a-batch-file-and-then-return-to-git-conso + if ! cmd "/C cmake.exe --build . --target "$BUILD_TARGET" $WIN_CMAKE_BUILD_DEFINE -- /m" && $EXIT_WHEN_FAILED; then + exit 1 + fi + echo end: cmake.exe --build . --target "$BUILD_TARGET" $WIN_CMAKE_BUILD_DEFINE -- /m + else + if ! cmake --build . --target "$BUILD_TARGET" $(test -n "$CMAKE_BUILD_TYPE" && echo --config $CMAKE_BUILD_TYPE) -- -j $(nproc) && $EXIT_WHEN_FAILED; then + exit 1 + fi + fi + popd +} + +if [[ $# -eq 0 ]]; then + echo "usage: [--load] [--reload] [--clean] [--build]" +fi + +while [[ $# > 0 ]]; do + + PARSE_KEY="$1" + + case "$PARSE_KEY" in + --load) + echo "loadCMakeProject" + loadCMakeProject + shift # past argument + ;; + --reload) + echo "reloadCMakeProject" + reloadCMakeProject + shift # past argument + ;; + --clean) + echo "clean" + cmakeCleanAll + shift # past argument + ;; + --build) + echo "build" + cmakeBuildAll + shift # past argument + ;; + --debug) + echo "enable debug mode" + export CMAKE_BUILD_TYPE="Debug" + shift + ;; + --release) + echo "enable release mode" + export CMAKE_BUILD_TYPE="Release" + shift # past argument + ;; + --target) + echo "set build target to $2" + export BUILD_TARGET="$2" + shift + shift + ;; + --run) + if isWindows; then + echo "run $CMAKE_VS_DIR/$CMAKE_BUILD_TYPE/$2" + "$CMAKE_VS_DIR/$CMAKE_BUILD_TYPE/$2" + elif isMacOS; then + echo run "$CMAKE_VS_DIR/$2" + wine64 "$CMAKE_VS_DIR/$2" + fi + shift + shift + ;; + *) + echo "unknown option $PARSE_KEY..." + exit 1 + ;; + esac +done