#include #include #include #include #include #ifdef _WIN32 #include #elif defined(__clang__) && defined(__APPLE__) #include #include #else #include #endif #ifndef PATH_MAX #define PATH_MAX 256 #endif namespace fs = std::filesystem; /// @brief /// @param source 原文件路径 /// @param dest 目标目录,注意是目录,已存在则会被覆盖 bool copy_file(const fs::path& source, const fs::path& dest, const std::string& spre = "", const std::string& safter = "") { try { if (spre.empty()) { std::string name = fs::path(source).filename().string(); return fs::copy_file(source, fs::path(dest).append(name), fs::copy_options::overwrite_existing); } // 读入文件 std::ifstream file(source.string()); if (!file.is_open()) { std::cout << "打开文件失败:" << source.string() << std::endl; return false; } std::istreambuf_iterator iterf(file); std::istreambuf_iterator iter; std::string content(iterf, iter); // 替换 std::size_t start_pos = 0; while ((start_pos = content.find(spre, start_pos)) != std::string::npos) { content.replace(start_pos, spre.length(), safter); start_pos += safter.length(); } // 写入 fs::path desFile(dest); desFile.append(source.filename().string()); std::ofstream ofile(desFile); ofile << content; return true; } catch (const fs::filesystem_error& e) { std::cerr << e.what() << '\n'; return false; } } bool handle_work(const std::string& source_dir, const std::string& purpose) { if (!fs::exists(purpose)) { fs::create_directories(purpose); } std::string project_name = fs::path(purpose).filename().string(); std::cout << "工程名:" << project_name << std::endl; auto cp = [&](const std::string& relative_path, const std::string& spre = "", const std::string& safter = "") -> bool { fs::path fsource(source_dir); fsource.append(relative_path); return copy_file(fsource.string(), purpose, spre, safter); }; std::vector ret(5, 0); ret[0] = static_cast(cp("CMakeLists.txt", "demo", project_name)); ret[1] = static_cast(cp("main.cpp")); ret[2] = static_cast(cp(".clang-format")); ret[3] = static_cast(cp(".gitignore")); ret[4] = static_cast(cp("CMakeSettings.json")); fs::path vscodeConfig(source_dir); vscodeConfig.append(".vscode/settings.json"); fs::path purpose2(purpose); purpose2.append(".vscode"); if (!fs::exists(purpose2)) { fs::create_directories(purpose2); } ret[4] = static_cast(copy_file(vscodeConfig.string(), purpose2.string())); auto r = std::find(ret.begin(), ret.end(), 0); return r == ret.end(); } std::string get_exe_path() { std::string path; #ifdef _WIN32 char buffer[MAX_PATH]; DWORD length = GetModuleFileName(NULL, buffer, MAX_PATH); if (length == 0) { return ""; } return std::string(buffer, length); #elif defined(__clang__) && defined(__APPLE__) uint32_t size = 0; _NSGetExecutablePath(NULL, &size); // 获取路径缓冲区的大小 std::vector buffer(size); // 创建缓冲区 if (_NSGetExecutablePath(buffer.data(), &size) != 0) { return ""; } return std::string(buffer.data()); #else char buffer[PATH_MAX]; ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1); if (len == -1) { return ""; } buffer[len] = '\0'; // 确保字符串以null终止 return std::string(buffer); #endif } int main(int argc, char* argv[]) { if (argc < 2) { std::cout << "第二个参数为创建的项目路径。" << std::endl; return -1; } try { fs::path cmdPath(argv[1]); fs::path curWorkPath; if (cmdPath.is_relative()) { // std::cout << "相对路径:" << cmdPath.string() << std::endl; curWorkPath = fs::current_path(); curWorkPath.append(cmdPath.string()); } else { // std::cout << "绝对路径:" << cmdPath.string() << std::endl; curWorkPath = cmdPath; } // 转换为标准路径: fs::path standardPath = fs::absolute(curWorkPath); std::cout << "创建工程目录为:" << standardPath.string() << std::endl; fs::path exe_path(get_exe_path()); std::string template_dir = exe_path.parent_path().append("template").string(); if (handle_work(template_dir, standardPath.string())) { std::cout << "创建工程成功....!!!&&&" << std::endl; } } catch (const fs::filesystem_error& err) { std::cerr << err.what() << '\n'; return -1; } return 0; }