diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..9cfcbcc --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,55 @@ +name: build and test cv2pdb + +on: [push, pull_request] + +env: + # Path to the solution file relative to the root of the project. + SOLUTION_FILE_PATH: src/cv2pdb.vcxproj + + # Configuration type to build. + BUILD_CONFIGURATION: Release + BUILD_PLATFORM: x64 + BUILD_PLATFORM_TOOLSET: v142 + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + - name: Build + working-directory: ${{env.GITHUB_WORKSPACE}} + run: msbuild /m /p:PlatformToolset=${{env.BUILD_PLATFORM_TOOLSET}} /p:Platform=${{env.BUILD_PLATFORM}} /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} + - name: Upload bin/ + uses: actions/upload-artifact@v2 + with: + name: bin + path: bin + test-with-g4w-sdk: + runs-on: windows-latest + needs: build + steps: + - name: Download bin/ + uses: actions/download-artifact@v2 + with: + name: bin + path: bin + - uses: git-for-windows/setup-git-for-windows-sdk@v1 + - name: verify using Git for Windows' GCC + shell: bash + run: | + set -x && + cat >hello.c <<-\EOF && + #include + + int main(int argc, char **argv) + { + printf("Hello, world\n"); + return 0; + } + EOF + + gcc -g -o hello.exe hello.c && + bin/${{env.BUILD_CONFIGURATION}}*/cv2pdb.exe hello.exe world.exe && + ls -l hello* world* diff --git a/src/mspdb.cpp b/src/mspdb.cpp index 4267ac8..9f23d15 100644 --- a/src/mspdb.cpp +++ b/src/mspdb.cpp @@ -9,6 +9,8 @@ #include #include #include "packages/Microsoft.VisualStudio.Setup.Configuration.Native.1.16.30/lib/native/include/Setup.Configuration.h" +#include +#include _COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration)); _COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance)); @@ -165,6 +167,69 @@ bool tryLoadMsPdbVS2017(const char* mspdb, const char* path = 0) return modMsPdb != 0; } +inline std::string& rtrim(std::string& s, const char* t = "\t\n\r ") +{ + s.erase(s.find_last_not_of(t) + 1); + return s; +} + +bool tryLoadMsPdbVSWhere(const char* mspdb) +{ + HANDLE read; + HANDLE write; + + SECURITY_ATTRIBUTES securityAttributes = { 0 }; + securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + securityAttributes.lpSecurityDescriptor = NULL; + securityAttributes.bInheritHandle = TRUE; + if(!CreatePipe(&read, &write, &securityAttributes, 0) || + !SetHandleInformation(read, HANDLE_FLAG_INHERIT, 0)) + return false; + + STARTUPINFOA startupInfo = { 0 }; + startupInfo.cb = sizeof(startupInfo); + startupInfo.dwFlags = STARTF_USESTDHANDLES; + startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + startupInfo.hStdOutput = write; + startupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); + PROCESS_INFORMATION processInformation = { 0 }; + ZeroMemory(&processInformation, sizeof(PROCESS_INFORMATION)); + + std::string vsPath; + char buffer[1024] = ""; + char commandLine[] = "vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath"; + if(CreateProcessA("C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\vswhere.exe", commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &processInformation)) + { + CloseHandle(processInformation.hProcess); + CloseHandle(processInformation.hThread); + + DWORD length; + if (ReadFile(read, buffer, sizeof(buffer) - 1, &length, NULL)) + { + buffer[length] = '\0'; + vsPath += buffer; + } + } + CloseHandle(read); + CloseHandle(write); + rtrim(vsPath); + if (vsPath.empty()) + return false; + + // Read the version + std::ifstream versionFile(vsPath + "\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt"); + if (versionFile.fail()) + return false; + std::string contents; + contents.assign(std::istreambuf_iterator(versionFile), std::istreambuf_iterator()); + versionFile.close(); + rtrim(contents); + + std::string dllPath = vsPath + "\\VC\\Tools\\MSVC\\" + contents + "\\bin\\" + (sizeof(void*) == 8 ? "Hostx64\\x64\\" : "Hostx86\\x86\\") + mspdb; + tryLoadLibrary(dllPath.c_str()); + return modMsPdb != 0; +} + #ifdef _M_X64 #define BIN_DIR_GE_VS12 "..\\..\\VC\\bin\\amd64\\" #define BIN_DIR_LT_VS12 BIN_DIR_GE_VS12 @@ -247,6 +312,8 @@ void tryLoadMsPdb140(bool throughPath) tryLoadMsPdb("VisualStudio\\14.0", mspdb140_dll, BIN_DIR_GE_VS12); if (!modMsPdb && !throughPath) tryLoadMsPdb("VSWinExpress\\14.0", mspdb140_dll, BIN_DIR_GE_VS12); + if (!modMsPdb && !throughPath) + tryLoadMsPdbVSWhere(mspdb140_dll); if (modMsPdb) mspdb::vsVersion = 14; }