Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <filesystem>
- #include <cstdlib>
- #include <vector>
- #include <windows.h>
- #include <tlhelp32.h>
- #include <zlib.h>
- #include <cstdint>
- #include <thread>
- #include <yy981/dll.h>
- namespace fs = std::filesystem;
- std::string option, exename, sourceFile, mocFilePath, include_qt6, addlibrary, original, iconPath, icon, dllCompileCMD;
- std::string temp(std::string(std::getenv("temp")));
- std::string mkpath = temp + "/_.mk";
- bool enableOriginal_qt(false), enableIcon(false), isCompiling(false), compilerCPPMode(true), dllMode(false);
- int cmd(const std::string& command) {return std::system(command.c_str());}
- constexpr std::string compilerM() {if (compilerCPPMode) return "g++"; else return "gcc";}
- int taskLevel = 3;
- uint32_t hash;
- inline void flags() {
- if (enableIcon) {
- std::ofstream(temp+".rc") << "IDI_ICON1 ICON \"" << original << "\"";
- cmd("windres.exe -i " + temp+"/icon.rc" + " -o " + temp+"/icon.o");
- icon = temp+"/icon.o";
- }
- }
- // ファイルハッシュ計算
- uint32_t calculateCRC32(const std::string &filePath) {
- std::ifstream file(filePath, std::ios::binary);
- if (!file.is_open()) {
- std::cerr << "Failed to open file!" << std::endl;
- return 0;
- }
- uint32_t crc = crc32(0L, Z_NULL, 0); // 初期化
- char buffer[4096];
- while (file.read(buffer, sizeof(buffer)) || file.gcount() > 0) {
- crc = crc32(crc, reinterpret_cast<const Bytef *>(buffer), file.gcount());
- }
- return crc;
- }
- // プロセス名からプロセスIDを取得
- DWORD GetProcessIDByName(const std::string& processName) {
- PROCESSENTRY32 entry;
- entry.dwSize = sizeof(PROCESSENTRY32);
- HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (Process32First(snapshot, &entry)) {
- do {
- if (processName == entry.szExeFile) {
- CloseHandle(snapshot);
- return entry.th32ProcessID;
- }
- } while (Process32Next(snapshot, &entry));
- }
- CloseHandle(snapshot);
- return 0;
- }
- // プロセス優先度を変更
- bool SetProcessPriority(const std::string& processName, DWORD priorityClass) {
- DWORD processID = GetProcessIDByName(processName);
- if (processID == 0) {
- std::cout << "プロセスが見つかりません" << std::endl;
- return false;
- }
- HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
- if (hProcess == NULL) {
- std::cout << "プロセスを開けません" << std::endl;
- return false;
- }
- if (!SetPriorityClass(hProcess, priorityClass)) {
- std::cout << "優先度を変更できません" << std::endl;
- CloseHandle(hProcess);
- return false;
- }
- std::cout << "優先度を正常に変更しました" << std::endl;
- CloseHandle(hProcess);
- return true;
- }
- constexpr void task() {
- DWORD priorityClass;
- switch (taskLevel) {
- case 1: priorityClass = HIGH_PRIORITY_CLASS; break;
- case 2: priorityClass = ABOVE_NORMAL_PRIORITY_CLASS; break;
- case 3: return;
- case 4: priorityClass = BELOW_NORMAL_PRIORITY_CLASS; break;
- case 5: priorityClass = IDLE_PRIORITY_CLASS; break;
- }
- // プロセスの優先度を変更
- std::thread([priorityClass]{
- bool continueLoop = true;
- while (continueLoop&&isCompiling) if (SetProcessPriority("cc1plus.exe", priorityClass)) {continueLoop = false;std::cout << "y\n";}
- }).detach();
- }
- std::vector<std::string> findString(std::string& input, std::string start, std::string end) {
- std::vector<std::string> output;
- int startpos = 0;
- while(true) {
- // start 検索
- size_t f = input.find(start,startpos);
- if (f == std::string::npos) break;
- // end 検索
- size_t b = input.find(end, f);
- if (b == std::string::npos) break;
- // 部分文字列を抽出
- output.emplace_back(input.substr(f, b-f+1));
- startpos = b+1;
- }
- return output;
- }
- void userInput() {
- std::cout << "独自オプション: ";
- std::getline(std::cin,original);
- std::cout << "実行ファイル名(拡張子除く): ";
- std::getline(std::cin,exename);
- std::cout << "追加ライブラリ(各ファイル名の前に-lを追加): ";
- std::getline(std::cin,addlibrary);
- std::cout << "オプション: ";
- std::getline(std::cin,option);
- }
- void readYBP(char* argv[]) {
- std::string line;
- std::ifstream file(argv[1]);
- int loop = 0;
- // ファイルから1行ずつ読み込む
- while (std::getline(file, line)) {
- loop++;
- // std::cout << "読み込んだ行[" << loop << "]: " << line << '\n';
- switch (loop) {
- case 1: if (line=="null") {std::cerr << "必須要素のSourceFileがnullです";exit(3);} else sourceFile = line; break;
- case 2: if (line=="null") exename = sourceFile; else exename = line; break;
- case 3: if (line=="null") addlibrary = ""; else addlibrary = line; break;
- case 4: if (line=="null") option = ""; else option = line; break;
- case 5: if (line=="null") original = ""; else original = line; break;
- default:
- std::cout << "ybp読み取りエラー: 必要な行数以上の行が存在しますが無視します\n";
- return; // 5行読み込んだら終了
- }
- }
- if (loop < 5) {
- std::cerr << "ybp読み取りエラー: 行数不足 " << loop << "行しかありません\n";
- exit(3);
- }
- }
- void createYBP() {
- std::cout << "[ybp生成モード]\nソースコードファイル名(拡張子除く): ";
- std::getline(std::cin,sourceFile);
- userInput();
- std::ofstream(sourceFile + ".ybp2") << (sourceFile.empty()? "null" : sourceFile) << "\n"
- << (exename.empty()? "null" : exename) << "\n"
- << (addlibrary.empty()? "null" : addlibrary) << "\n"
- << (option.empty()? "null" : option) << "\n"
- << (original.empty()? "null" : original);
- }
- void writeMK() {
- std::string stdcpp23, cp932, icon;
- if (exename.empty()) exename=sourceFile;
- // 入力処理
- if (!original.contains("nocp932")) cp932 = "-fexec-charset=cp932";
- if (original.contains("qt")) {
- addlibrary = addlibrary + " -lQt6Core -lQt6Widgets -lQt6Gui";
- include_qt6 = "-Ic:/msys64/mingw64/include/qt6";
- enableOriginal_qt = true;
- }
- if (!original.contains("nocpp23")) stdcpp23 = "-std=c++23";
- if (original.contains("icon")) {
- if (original.substr(4,1) != "=") std::cerr << "使い方が違います icon=<ファイルパス>";
- original.erase(0,original.find("icon")+5);
- iconPath = original;
- }
- if (original.contains("gcc")) compilerCPPMode = false;
- if (original.contains("dll")) {
- dllCompileCMD =
- compilerM() + " -shared -o " + exename + ".dll " + sourceFile + ".cpp " + (enableOriginal_qt? mocFilePath : "") +
- cp932 + " " + stdcpp23 + " " + option + " -Ic:/msys64/mingw64/include " + include_qt6 + " -Lc:/msys64/mingw64/lib " + addlibrary;
- bool dllMode = true;
- return;
- }
- std::ofstream(mkpath)
- << "CC = " << compilerM()
- << "\nCFLAGS = " << cp932 << " " << stdcpp23 << " " << option
- << "\nTARGET = " << exename << ".exe"
- << "\nSRCS = " << sourceFile << ".cpp " << (enableOriginal_qt? mocFilePath : "") << (enableIcon? icon : "")
- << "\nOBJS = " << sourceFile << ".o"
- << "\nINCDIR = -Ic:/msys64/mingw64/include " << include_qt6
- << "\nLIBDIR = -Lc:/msys64/mingw64/lib"
- << "\nLIBS = " << addlibrary
- << "\n$(TARGET): $(OBJS)"
- << "\n\t$(CC) -o $@ $^ $(LIBDIR) $(LIBS)"
- << "\n%.o: %.cpp"
- << "\n\t$(CC) $(CFLAGS) $(INCDIR) -c $< -o $@";
- hash = calculateCRC32(mkpath);
- }
- inline void core() {
- task();
- flags();
- if (calculateCRC32(mkpath) != hash) writeMK();
- int returnCode = cmd((dllMode? dllCompileCMD : "c:/GnuWin32/bin/make.exe -B -f " + mkpath)); // 核
- if (returnCode==0) std::cout << "成功\n"; else std::cout << "エラー[" << returnCode << "]\n\n";
- }
- inline void compile() {
- core();
- std::string input;
- while(true) {
- std::cout << "> ";
- std::getline(std::cin,input); //指示
- if (input == "help")
- std::cout << "moc: .mocファイルを生成\n"
- << "write: .mkファイルを生成\n"
- << "exit: 終了\n"
- << "set: 変数を変更(詳細はcustomと入力してください)\n"
- << " 例: set sou test";
- else if (input == "moc") cmd("c:/msys64/mingw64/share/qt6/bin/moc.exe " + mocFilePath);
- else if (input == "write") writeMK();
- else if (input.starts_with("icon")) {
- if (input.size()==4) std::cout << "Icon: 現在" << (enableIcon? "有効" : "無効") << "です フラグの変更を行いたい場合は、後ろにONやOFFをつけたコマンドを使用してください";
- else {
- input.erase(0,5);
- if (input=="ON"||input=="on") enableIcon = true;
- else if (input=="OFF"||input=="off") enableIcon = false;
- else std::cerr << "第二層入力エラー";
- }
- }
- else if (input.size() >= 4 && input.starts_with("task")) {
- if (input == "task") input += " help";
- if (input == "task ") input += "help";
- input.erase(0,5);
- if (input.substr(0,4)=="help") std::cout << "例: task [1:高 2:通常以上 3:通常 4:通常以下 5:低]\n現在: " << taskLevel;
- else taskLevel = std::stoi(input.substr(0,1));
- }
- else if (input.size() >= 3 && input.starts_with("set")) { // set.begin
- if (input == "set") input += " help";
- if (input == "set ") input += "help";
- input.erase(0,4);
- char windowTitle[256];
- GetConsoleTitle(windowTitle,256);
- if (input.substr(0,4)=="help") {
- std::cout << " sou: ソースファイル名 (現在: " << sourceFile << " )\n"
- << " exe: 実行ファイル名 (現在: " << exename << " )\n"
- << " lib: 追加ライブラリ (現在: " << addlibrary << " )\n"
- << " opt: オプション (現在: " << option << " )\n"
- << " ori: 独自オプション (現在: " << original << " )\n"
- << " tit: ウィンドウタイトル (現在: " << windowTitle << " )\n"
- << " 例: set sou test";
- } else if (input.substr(3,1)==" ") {
- if (input.substr(0,3)=="sou") sourceFile = input.substr(4);
- else if (input.substr(0,3)=="exe") exename = input.substr(4);
- else if (input.substr(0,3)=="opt") sourceFile = input.substr(4);
- else if (input.substr(0,3)=="lib") addlibrary = input.substr(4);
- else if (input.substr(0,3)=="ori") original = input.substr(4);
- else if (input.substr(0,3)=="tit") SetConsoleTitle(input.substr(4).c_str());
- else std::cerr << "第三層入力エラー";
- writeMK();
- } else std::cerr << "第二層入力エラー";
- } // set.end
- else if (input == "exit") break;
- else if (input == "") core();
- else std::cerr << "有効なコマンドではありません help と打ってコマンドを確認してください";
- std::cout << "\n";
- }
- }
- inline void end(){if (fs::exists(sourceFile+".o")) fs::remove(sourceFile+".o");}
- int main(int argc, char *argv[]) {
- sourceFile = exename = addlibrary = option = original = "null";
- if (argc == 1) {
- SetConsoleTitle("Compiler-YBP");
- createYBP();
- return 0;
- }
- // set paths
- sourceFile = fs::path(argv[1]).stem().string();
- mocFilePath = sourceFile + ".cpp -o " + temp + "/" + sourceFile + ".moc";
- SetConsoleTitle(std::string("[" + sourceFile + "] MSYS2-Mingw64_New-Compiler").c_str());
- bool inputMK = false;
- if (argc > 2) {std::cerr << "コマンドライン引数エラー\n";return 1;}
- std::string inputExtention = fs::path(argv[1]).extension().string();
- if (inputExtention == ".ybp") {
- char input;
- std::cout << ".ybpファイルはMSYS2-Mingw64_Compiler(M2-M64_Compiler.bat)を使用してください\n.ybpファイルを.ybp2ファイルに変換しますか? [Y,N] ";
- std::cin >> input;
- if (input=='Y'||input=='y') case 'Y': case 'y': upgradeYBP(sourceFile);
- }
- if (inputExtention == ".cpp" || inputExtention == ".c" || inputExtention == ".ybp2" || inputExtention == ".mk") {
- if (inputExtention == ".ybp2") readYBP(argv);
- else if (inputExtention == ".mk") inputMK=true;
- else {
- if (inputExtention == ".c") compilerCPPMode = false;
- userInput();
- }
- } else {
- std::cout << "[警告] C(.c) もしくは C++(.cpp) もしくは BuildProfile2(.ybp2) もしくは MakeFile(.mk) ではありませんが、続行しますか?\n"
- << "[Y:ソースファイルとして続行 N:終了 B:BuildProfileとして続行 M:MakeFileとして続行]: ";
- char input;
- std::cin.get() >> input;
- switch(input) {
- case 'Y': case 'y': userInput(); break;
- case 'N': case 'n': return 0;
- case 'B': case 'b': readYBP(argv); break;
- case 'M': case 'm': inputMK=true; break;
- default: return 2;
- }
- }
- if (!inputMK) writeMK();
- compile();
- // 終了
- end();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement