{"id":22100246,"url":"https://github.com/turesnake/cpp_empty_project","last_synced_at":"2026-03-04T19:01:34.394Z","repository":{"id":54267124,"uuid":"253391306","full_name":"turesnake/Cpp_Empty_Project","owner":"turesnake","description":"一个跨平台的，基于cmake的 C++空项目","archived":false,"fork":false,"pushed_at":"2021-02-28T10:54:28.000Z","size":3347,"stargazers_count":133,"open_issues_count":1,"forks_count":25,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-07-25T03:38:40.840Z","etag":null,"topics":["c-plus-plus","cmake","cpp11","cpp17","cross-platform"],"latest_commit_sha":null,"homepage":null,"language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/turesnake.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-06T04:08:10.000Z","updated_at":"2025-05-30T19:12:22.000Z","dependencies_parsed_at":"2022-08-13T10:30:53.216Z","dependency_job_id":null,"html_url":"https://github.com/turesnake/Cpp_Empty_Project","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/turesnake/Cpp_Empty_Project","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turesnake%2FCpp_Empty_Project","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turesnake%2FCpp_Empty_Project/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turesnake%2FCpp_Empty_Project/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turesnake%2FCpp_Empty_Project/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/turesnake","download_url":"https://codeload.github.com/turesnake/Cpp_Empty_Project/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turesnake%2FCpp_Empty_Project/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30090037,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T18:31:08.343Z","status":"ssl_error","status_checked_at":"2026-03-04T18:31:07.708Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-plus-plus","cmake","cpp11","cpp17","cross-platform"],"created_at":"2024-12-01T05:12:40.874Z","updated_at":"2026-03-04T19:01:34.375Z","avatar_url":"https://github.com/turesnake.png","language":"CMake","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cpp_Empty_Project\n**Cpp_Empty_Project** 是一个 跨平台的，基于cmake工具的，C++17空项目。\n\n这是一个面相 C++ 新手的，辅助用项目。\n\n你可以以此项目为基础，搭建出自己的 跨平台 C++ 程序。\n\n\n## 我该下载哪个分支\n直接下载 Branch:**master** 即可。\n\n## 此项目支持哪些平台\n- **Win10**\n- **MacOSX** (10.12 或更高版本) \n- **Ubuntu** (16.04 或更高版本) \n\n也许还能支持各个平台的较早版本，但我尚未测试。\n\n\n## 支持哪款编译器\n**Clang** 是最推荐的编译器，即便是在 **Win10** 平台。\n请确保你所下载和安装的 **Clang** 版本，支持 **C++17**。\n\n\n\n## 如何安装（编译程序，把app安装到平台）\n\n### Mac OS X\n\n在 **Mac** 平台的安装非常简单。\n\n首先，确保你已经成功安装如下程序：\n- **CMake** (3.1 或更高版本; 若想使用PCH，Unity-builds 技术加速编译，推荐 3.16 或更高版本)\n- **Clang** (足以支持 **C++17** 的较新版本)\n\n然后，打开 **终端**（terminal），**\"cd\"** 至 本项目的根目录： \n\n    $ cd .../appRootDir/\n\n(**注意**，此处的 \"appRootDir\" 应替换为实际的根目录名字) \n\n接着，运行一份 shell 脚本程序：\n\n    $ ./unix_release.sh\n\n脚本 `unix_release.sh` 将会自动化地帮我们完成程序的 **build** 和本地化部署工作。\n你也可以选择运行另一份脚本：`unix_debug.sh`， 正如名字所示，它将生成一份 **DEBUG** 版的程序。\n\n现在，所有的安装工作都已经 **完成**!!!\n\n你可以在目录： **.../appRootDir/build/publish/** 中找到可执行文件：**emptyApp**。\n双击它，运行我们的程序!!!\n(**注意**，此处的 \"appRootDir\" 应替换为实际的根目录名字)\n\n\n### Ubuntu \n在 **Ubuntu** 上的安装与 **Mac OS X** 十分相似。\n\n首先，请确保你已经安装如下程序：\n\n**CMake** (3.1 或更高版本; 若想使用PCH，Unity-builds 技术加速编译，推荐 3.16 或更高版本)：\n\n    $ sudo apt-get install cmake\n\n**Clang** (足以支持 **C++17** 的较新版本)：\n\n    $ sudo apt-get install llvm\n    $ sudo apt-get install clang \n\n重设系统默认的 **C/C++编译器**：\n\n    $ sudo update-alternatives --config c++\n    $ sudo update-alternatives --config cc\n\n\n现在，打开 **终端**（terminal），**\"cd\"** 至 本项目的根目录： \n\n    $ cd .../appRootDir/\n\n(**注意**，此处的 \"appRootDir\" 应替换为实际的根目录名字)\n\n接着，运行一份 shell 脚本程序：\n\n    $ ./unix_release.sh\n\n脚本 `unix_release.sh` 将会自动化地帮我们完成程序的 **build** 和本地化部署工作。\n你也可以选择运行另一份脚本：`unix_debug.sh`， 正如名字所示，它将生存一份 **DEBUG** 版的程序。\n\n现在，所有的安装工作都已经 **完成**!!!\n\n你可以在目录： **.../appRootDir/build/publish/** 中找到可执行文件：**emptyApp**。\n(**注意**，此处的 \"appRootDir\" 应替换为实际的根目录名字)\n\n在 **终端** 中启动它：\n\n    $ build/publish/emptyApp\n\n运行我们的程序!!!\n\n\n\n### Win10\n\n\n\n为了支持 **Win10** 中的 **Clang**，我们首先要安装 **Visual Studio 2019**。\n\n\n同时，确保你的 **Visual Studio** 中也安装了如下组件:\n\n![Check Clang and Cmake](Docs/pngs/win10/clang_and_cmke_check.png)\n\n然后，启动 **Visual Studio 2019**，点选初始界面中的 `Open a local folder` 按钮，在弹出的窗口中，选择本程序的根目录 -\u003e\n\n![open a local folder](Docs/pngs/win10/000.png)\n\n\n进入主界面后，VS 会主动识别出一份根目录下的配置文件：`CMakeSettings.json`，并且根据这份文件内的描述，自动创建一份名为 `x64-Clang-Release` 的 配置方案（configurations）。此时你会看到 VS: **Output 面板**中 正在做有关 cmake Cache 的解析和生成工作。 稍等数秒后，你会在 **Output 面板** 中看到：\n\n    CMake generation finished.\n\n这表明 cmake Cache 生成成功了！\n\n\n**注意:** 如果在这一过程中发生错误，请阅读 [这份文章](Docs/how_to_handle_visual_studio.md)，学习如何以 **手动配置** 的方式，来生成 cmake Cache。\n\n\n在 cmake Cache 生成成功后。在 **Visual Studio 2019** 左上方的 `Build` 菜单中，找到 `Build All` 按钮，点击它，开始正式的 **Build** 工作。（也可以使用快捷键:`F7`） -\u003e\n\n![Build All](Docs/pngs/win10/009.png)\n\n\n**Build** 工作 将会持续数分钟，直到我们在下方的 **Output** 面板中看到 `Build All succeeded.` 的信息。这表示，**Build** 成功。我们在 **Visual Studio 2019**\n中的工作就全部结束了。\n\n\n最后的最后，回到本项目所在的根目录。寻找并双击一份名为 `win.bat` 的脚本文件。\n它将帮助我们执行本地化部署工作。\n比如将一些 根目录下的 资源性目录（如 “shaders”,\"jsons\" 复制到 \u003croot\u003e/build/publish/ 目录下）\n这个过程可能非常快，一闪而过。别担心，它已经运行了。如果你不放心，可以再次双击一遍。\n\n\n现在，安装正式**完成**!!!\n\n你可以在目录 **.../appRootDir/build/publish/** 中，找到可执行文件 **emptyApp.exe**，\n它就是我们的程序本体。\n(**注意**，此处的 \"appRootDir\" 应替换为实际的根目录名字)\n\n由于本程序的 main() 函数中只有一些 命令行打印函数。如果直接双击运行此 .exe 程序，它可能只会闪出一个命令框，然后立马结束。\n为了有效测试程序，你其实可以将这个 .exe 文件，拖进一个 命令行窗口中，然后按回车键来启动程序。如果一切正常，命令行窗口会打印如下信息：\n\n![Build All](Docs/pngs/screenShots/show_1.png)\n\n\n\n# 使用方式\n接下来，我们将介绍，如何使用这个空项目，来制作自己的 C++ 项目。\n\n\n\n## 如何添加 C++ 代码文件（.h/.hpp/.c/.cpp）\n\n### .c/.cpp 文件\n\n请将所有 C++ 代码文件，放入 `.../appRootDir/src/` 目录（或其递归子目录）下。这个目录的默认设置如下：\n\n![src folder](Docs/pngs/use/src_folder.png)\n\n- 目录：`main` 放置程序的主文件 `main.cpp`\n- 目录：`_pch_` 放置一个加速编译效率的文件 `pch.h`(下文会提及)\n- 目录：`debug` 放置一个推荐的 终端打印函数 **debug::log()**, 用来代替 `std::iostream`\n- 目录：`classA` 放置一组示范用 class 代码\n\n\n原则上，你可以在目录 `src` 下创建任意 子目录（递归）或文件。在目前的 cmake 设置中，所以位于目录 `src` （及其递归子目录）下的 **.c/.cpp**， 都会被自动查找到并编译，正如 文件 `CMakeLists.txt` 中所写：\n\n![src files set in cmake](Docs/pngs/use/cmake_1.png)\n\n\n\n### .h/.hpp 文件\n\n与 `.c/.cpp` 文件一致, `.h/.hpp` 文件也请全部放到 `src/` 目录（或其递归子目录）中。一种推荐的做法是：**将同一个模块的代码文件，放在同一个目录下**。\n\n\n我们已经在 `CMakeLists.txt` 下准备了一个宏函数 `collect_head_dirs`, 它将自动遍历 `src/` 及其所有递归子目录。如果某个目录内含 `.h/.hpp` 文件，这个目录就会被收集到一个 `list` 中。最后,这个 `list` 会被自动添加进 **include路径列表**。\n\n所以，当你在 `src/` 或其递归子目录 下的任何位置添加 `.h/.hpp` 文件时，你不需要对 cmake 配置文件做任何修改。cmake 会自动帮你处理好一切。\n\n比方说，当你在目录 `.../src/a/b/c/` 下，新建一个文件 `koko.h` 时。 那么你就能在 `src/` 目录下的任一代码文件内，inlcude 到它：\n    \n    #include \"koko.h\"\n\n而不是需要繁琐地写为：\n\n    #include \"a/b/c/koko.h\"\n\n当然，这种实现存在一个代价，就是要求你在 `src/` 目录下创建的所有 `.h/.hpp` 文件，都不能重名。\n\n最后，如果你不喜欢这种实现，你可以在 `CMakeLists.txt` 中放弃这个 宏函数 的使用，通过手动添加 include 路径的方式，来精细化地管理 **include路径列表**。具体方法请搜索 cmake: `target_include_directories` 的使用。\n\n\n\n## 项目构建规则\n我们使用 cmake 工具自动编译和构建项目。最终，项目的可执行目录，就是 `.../appRootDir/build/publish/`。\n在编译构建完毕后，你可以将这个 `publish` 目录，复制到电脑中的任意位置，都不会影响程序的运行。\n\n目录 `publish/` 下的 `emptyApp/emptyApp.exe` 文件，就是程序的可执行文件。\n\n程序所依赖的一切附加数据，比如 shaders，jsons，pngs，都将在构建过程中，被复制到 `publish/` 目录下。在 Mac/Linux 中，这个复制操作是由 脚本程序 `unix_release.sh, unix_debug.sh` 实现的。在 win10 中，这个复制操作是由 `win.bat` 实现的。整个操作也很简单，就是将 根目录下的 一些文件夹（及其体内的所有文件）复制进 `publish/` 目录下。（在目前的示例中，我已经在根目录放入两个空目录：`jsons/, shaders/`, 以此来示范整个复制效果。当你成功编译构建项目后，你会在 `publish/` 目录下，看到这两个 空目录 ）\n\n（如果你不愿意修改这些烦人的 脚本程序，你甚至可以手动复制，没有任何问题...）\n\n\n#### 这种构建方法，还存在另一层优点：\n如果你希望，彻彻底底地重编译自己的项目，你可以直接删除 `.../appRootDir/build/` 目录。（对，整个儿删除它！）然后按照上文提到的方法重新编译。整个编译过程所产生的中间件，以及最终生成件，都只会存储在这个 `build/` 目录内，不会污染到项目中的其它目录。\n\n\n如果你发现自己每次编译的速度足够快，我推荐你在大型修改后，都来一次彻彻底底地重编译，它能清除掉很多奇怪的运行时问题。\n\n\n## 如何在代码层实现跨平台\n\n最简单的跨平台方式就是：\n    让代码检查一组宏，从而得知，自己当前正运行在哪个平台。然后根据这层判断，跳入不同的分支，执行对应的代码。\n\n那么这组宏是从哪里来的呢？一个方式是，在项目编译阶段，由 cmake 工具写入某个 .h文件：\n\n在根目录中，我们会找到一个名为 `sysconfig/` 的目录。它的体内包含一个名为 `SysConfig.h.in` 的文件。这个文件就是提供给 cmake，用来生成平台相关信息 用的。在编译阶段中，cmake 会根据当前平台信息，在目录 `.../publish/sysconfig/` 中，自动创建一个文件 `SysConfig.h`，并且：\n\n- 如果当前处于 Mac 系统，这个.h文件中 会生成宏：TPR_OS_MACOSX_\n- 如果当前处于 Linux 系统，这个.h文件中 会生成宏：TPR_OS_LINUX_\n- 如果当前处于 win  系统，这个.h文件中 会生成宏：TPR_OS_WIN32_\n\n通过这个机制，你可以在自己的程序代码中，先 `#include \"SysConfig.h\"`，然后检查是否存在某个宏，来确定自己所处的 操作系统类型。对于那些跨平台的，且依赖平台API 的代码来说，这会是个有用的功能。\n\n\n\n\n## pch.h 到底是什么\n我们注意到，我在 `src/` 目录下放置了个 `_pch_/pch.h` 文件。并且，它还被写进了 `CMakeLists.txt` 中：\n    \n    target_precompile_headers( emptyApp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/_pch_/pch.h )\n\n这其实是借用了一个 cmake 3.16 以来支持的新功能：**Precompiled headers (PCH) 预编译头文件**。通俗地讲，如果有一组 `.h`文件，使用频率特别高，比如标准库的那些头文件，那你可以把这些头文件写入这个 `pch.h` 文件中。然后，当 cmake 开启相应功能后，将会在编译阶段，预先将这组 **头文件** 编译成一个 **中间件**，然后把这个 **中间件**, 自动添加进你的每一个 `.cpp` 文件中（是的，你什么都不用做）最终的目的就是 加快编译速度。\n\n当然，如果你安装的 cmake 尚未达到 3.16, 这个功能并不会被触发。所以，保险起见，你也可以手动将 `#include \"pch.h\"` 这句话写到每个 .cpp 文件头部。\n\n**pch** 文件的使用还有其它注意事项，推荐阅读 [**这篇文章**](https://onqtam.com/programming/2019-12-20-pch-unity-cmake-3-16/)\n\n当然，你也有权彻底不用这个功能...\n\n\n## Unity Build\n在上面推荐的文章中，还介绍了 cmake 3.16 以来的另一个新功能：**Unity Build**。简单说，它也是用来加快编译速度的。\n我已经将这部分代码写入 `CMakeLists.txt` 文件中，你将自动获得这个加速功能。\n\n当然，如果你安装的 cmake 尚未达到 3.16, 这个功能也是不会被触发的...\n\n\n## debug::log();\n在 main()函数中，我们发现一个奇怪的 打印函数：`debug::log();` 这是我在整个空项目中，**唯一夹带的私货～** 这个函数被定义在 `.../src/debug/` 目录下。通过使用一组类似 **python** 语法的 **格式化参数** 来将信息打印到 命令行终端（console）。这组参数的规则与 第三方库 **fmt** 一致。感兴趣的可以学习 **fmt** 的使用：[fmt](https://fmt.dev/latest/index.html) 通俗地讲，就是用这个 `debug::log();`，来代替标准库中 `std::cout\u003c\u003c\"koko\"\u003c\u003cstd::end;` 的功能。\n\n当然，您依旧有权不使用它，甚至彻底删除 `debug` 目录。\n\n\n## 已经安装的 第三方库\n所有的第三方库，推荐安装在 `.../appRootDir/deps/` 目录下。我已帮你安装了3个常用的库：\n- **fmt**: 用来便捷地拼接字符串\n- **glm**: 用来支持数学运算\n- **RapidJSON**: 用来解析 json 文件\n\n在 C++ 中，每一个第三方库，都有其独特的安装方式（包括如何写入 `CMakeLists.txt` 文件）在此暂不展开....\n\n\n\n## 更多描述有待未来写入\n...\n\n\n\n## 版权协议遵守 [MIT License](LICENSE)\n\n\n## 欢迎反馈与建议\n本程序的初衷是为了帮助大家，更便捷地搭建 C++项目。由于我也是爱好者，水平有限，这个项目还存在一些不足。比方说，这个项目似乎更适合 Mac/Linux 平台的开发者，对于 Win 开发者来说，它的调试和编译过程都有点繁琐。\n此外，它的 cmake 文件写得也很业余。这方面欢迎高玩改进。\n\n如果您有任何反馈或建议，都可以通过下方联系方式联系开发者本人。\n*   E-mail: [turesnake@gmail.com](mailto:turesnake@gmail.com)\n*   E-mail: [turesnake@icloud.com](mailto:turesnake@icloud.com)\n*   QQ: 651700603\n*   WeChat：turesnake\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturesnake%2Fcpp_empty_project","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fturesnake%2Fcpp_empty_project","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturesnake%2Fcpp_empty_project/lists"}