From dbb06eac9bae1b8dbc50275b66c975da09b1d09a Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 25 Sep 2018 23:22:08 +0200 Subject: Fix build with msvc (windows) Fix freeze when sub process (exec) returns a lot of data (in stdout) --- README.md | 2 + backend/ninja/Ninja.cpp | 59 ++++++-- depends/libninja | 2 +- include/PkgConfig.hpp | 2 - msvc/locate_windows_sdk.exe | Bin 18432 -> 19968 bytes msvc/locate_windows_sdk/locate_sdk.cpp | 86 +++++++++--- msvc/locate_windows_sdk/locate_sdk.hpp | 5 + .../locate_windows_sdk.vcxproj.user | 5 +- msvc/locate_windows_sdk/main.cpp | Bin 1504 -> 2304 bytes msvc/sibs.exe | Bin 321024 -> 356352 bytes src/Exec.cpp | 10 +- src/FileUtil.cpp | 154 ++++++++------------- src/PkgConfig.cpp | 28 ++-- src/main.cpp | 64 +++++++-- 14 files changed, 247 insertions(+), 170 deletions(-) diff --git a/README.md b/README.md index 2a62768..7bc8d2f 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ List of packages can be found at https://gitlab.com/DEC05EBA/sibs_packages/raw/m Newest version of sibs builds itself. If you don't already have sibs installed and you are using Windows then you can find prebuilt binary under msvc folder. On Linux you need to build from source by running install.sh under cmake directory. After you've installed sibs once, you can install new versions by running install.sh (or use `sibs.exe build --release` if you are on windows, and sibs binary will be located under sibs-build/release/sibs.exe). +For easiest usage of sibs under windows, add msvc subdirectory to PATH environment variable. msvc subdirectory also contains additional libraries and software that is needed for sibs to run +with the only missing software being cmake. Dependencies that are required to build sibs from source are: `libcurl, libarchive, libgit2` diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp index 9220593..05bb16d 100644 --- a/backend/ninja/Ninja.cpp +++ b/backend/ninja/Ninja.cpp @@ -747,7 +747,7 @@ namespace backend } globalIncDir += dependencyExportIncludeDirs; - globalIncDir += TINYDIR_STRING(" ") + getIncludeOptionFlag(config.getCompiler(), toUtf8(generatedHeadersDir)); + globalIncDir += " " + getIncludeOptionFlag(config.getCompiler(), toUtf8(generatedHeadersDir)); ninjaBuildFile.defineGlobalVariable("globalIncDir", globalIncDir); // TODO: Find a better way to convert includes, this could be slow... ninjaBuildFile.defineGlobalVariable("globalIncDirZig", convertCIncludeSyntaxToZigInclude(config.getCompiler(), globalIncDir)); @@ -774,10 +774,10 @@ namespace backend { // TODO: Executable type does not guarantee the executable should be a console on windows. Find a way to define window type as well case LibraryType::EXECUTABLE: - defines.push_back(ninja::NinjaArg(" _CONSOLE")); + defines.push_back(ninja::NinjaArg::createRaw(" _CONSOLE")); break; case LibraryType::STATIC: - defines.push_back(ninja::NinjaArg(" _LIB")); + defines.push_back(ninja::NinjaArg::createRaw(" _LIB")); break; } } @@ -825,15 +825,15 @@ namespace backend compileCCommand.insert(compileCCommand.end(), baseCompileCArgs.begin(), baseCompileCArgs.end()); compileCCommand.insert(compileCCommand.end(), { - ninja::NinjaArg("-fdiagnostics-show-option"), - ninja::NinjaArg("-fdiagnostics-color=always"), - ninja::NinjaArg("-pipe"), - ninja::NinjaArg("-D_FILE_OFFSET_BITS=64"), - ninja::NinjaArg("-Winvalid-pch"), - ninja::NinjaArg("-fstack-protector"), - ninja::NinjaArg("-MMD"), + ninja::NinjaArg::createRaw("-fdiagnostics-show-option"), + ninja::NinjaArg::createRaw("-fdiagnostics-color=always"), + ninja::NinjaArg::createRaw("-pipe"), + ninja::NinjaArg::createRaw("-D_FILE_OFFSET_BITS=64"), + ninja::NinjaArg::createRaw("-Winvalid-pch"), + ninja::NinjaArg::createRaw("-fstack-protector"), + ninja::NinjaArg::createRaw("-MMD"), ninja::NinjaArg("-I" + config.getPackageName() + "@exe"), - ninja::NinjaArg("$globalIncDir") + ninja::NinjaArg::createRaw("$globalIncDir") }); compileCCommand.insert(compileCCommand.end(), cflags.begin(), cflags.end()); @@ -872,7 +872,8 @@ namespace backend ninja::NinjaArg::createRaw("cl.exe /showIncludes"), ninja::NinjaArg::createRaw("/c"), ninja::NinjaArg::createRaw("$in"), - ninja::NinjaArg::createRaw("/Fo$out") + ninja::NinjaArg::createRaw("/Fo$out"), + ninja::NinjaArg::createRaw("$globalIncDir") }); compileCCommand.insert(compileCCommand.end(), cflags.begin(), cflags.end()); @@ -1101,7 +1102,7 @@ namespace backend buildExeArgs.insert(buildExeArgs.end(), zigLibraryFlags.begin(), zigLibraryFlags.end()); ninja::NinjaRule *buildExeRule = ninjaBuildFile.createRule("build_exec", buildExeArgs); - buildExeRule->build(objectNames, config.getPackageName(), { zigObjectArgsValue }); + buildExeRule->build(objectNames, OS_FAMILY == OS_FAMILY_POSIX ? config.getPackageName() : config.getPackageName() + ".exe", { zigObjectArgsValue }); } else { @@ -1151,6 +1152,16 @@ namespace backend ninja::NinjaArg::createRaw("GlU32.lib"), ninja::NinjaArg::createRaw("Shell32.lib") }); + + switch (SYSTEM_PLATFORM) + { + case PLATFORM_WIN32: + buildExeArgs.push_back(ninja::NinjaArg::createRaw("/MACHINE:X86")); + break; + case PLATFORM_WIN64: + buildExeArgs.push_back(ninja::NinjaArg::createRaw("/MACHINE:X64")); + break; + } break; } } @@ -1159,7 +1170,7 @@ namespace backend buildExeArgs.push_back(ninja::NinjaArg::createRaw(allLinkerFlags)); ninja::NinjaRule *buildExeRule = ninjaBuildFile.createRule("build_exec", buildExeArgs); - buildExeRule->build(objectNames, config.getPackageName(), {}); + buildExeRule->build(objectNames, config.getPackageName() + ".exe", {}); } projectGeneratedBinary += config.getPackageName(); @@ -1221,6 +1232,16 @@ namespace backend ninja::NinjaArg::createRaw("/OUT:$out"), ninja::NinjaArg::createRaw("$in") }); + + switch (SYSTEM_PLATFORM) + { + case PLATFORM_WIN32: + buildStaticArgs.push_back(ninja::NinjaArg::createRaw("/MACHINE:X86")); + break; + case PLATFORM_WIN64: + buildStaticArgs.push_back(ninja::NinjaArg::createRaw("/MACHINE:X64")); + break; + } break; } } @@ -1318,6 +1339,16 @@ namespace backend ninja::NinjaArg::createRaw("GlU32.lib"), ninja::NinjaArg::createRaw("Shell32.lib") }); + + switch (SYSTEM_PLATFORM) + { + case PLATFORM_WIN32: + buildDynamicArgs.push_back(ninja::NinjaArg::createRaw("/MACHINE:X86")); + break; + case PLATFORM_WIN64: + buildDynamicArgs.push_back(ninja::NinjaArg::createRaw("/MACHINE:X64")); + break; + } break; } } diff --git a/depends/libninja b/depends/libninja index f414fe5..45e57bb 160000 --- a/depends/libninja +++ b/depends/libninja @@ -1 +1 @@ -Subproject commit f414fe587cef52cb8ff2b73a320ee0ce481170b6 +Subproject commit 45e57bb16903902a39045fa5e49027d1b6c7af6d diff --git a/include/PkgConfig.hpp b/include/PkgConfig.hpp index 43f7d91..2a52f2b 100644 --- a/include/PkgConfig.hpp +++ b/include/PkgConfig.hpp @@ -2,7 +2,6 @@ #define SIBS_PKGCONFIG_HPP #include "env.hpp" -#if OS_FAMILY == OS_FAMILY_POSIX #include "Result.hpp" #include #include @@ -28,6 +27,5 @@ namespace sibs static Result getDynamicLibsFlags(const std::vector &libs); }; } -#endif // OS_FAMILY_POSIX #endif // SIBS_PKGCONFIG_HPP diff --git a/msvc/locate_windows_sdk.exe b/msvc/locate_windows_sdk.exe index 6da61ac..10ad369 100644 Binary files a/msvc/locate_windows_sdk.exe and b/msvc/locate_windows_sdk.exe differ diff --git a/msvc/locate_windows_sdk/locate_sdk.cpp b/msvc/locate_windows_sdk/locate_sdk.cpp index b025bdd..a79d032 100644 --- a/msvc/locate_windows_sdk/locate_sdk.cpp +++ b/msvc/locate_windows_sdk/locate_sdk.cpp @@ -12,7 +12,7 @@ // See the comments for how to use this library just below the includes. // -// Modified by dec05eba to support x86 +// Modified by dec05eba to support locating include path #include "locate_sdk.hpp" #include @@ -314,16 +314,36 @@ void find_windows_kit_root(Find_Result *result) { if (windows10_root) { defer{ free(windows10_root); }; - Version_Data data = { 0 }; - auto windows10_lib = concat(windows10_root, L"Lib"); - defer{ free(windows10_lib); }; - - visit_files_w(windows10_lib, &data, win10_best); - if (data.best_name) { - result->windows_sdk_version = 10; - result->windows_sdk_root = data.best_name; - return; - } + + bool foundPaths = false; + { + auto windows10_lib = concat(windows10_root, L"Lib"); + defer{ free(windows10_lib); }; + + Version_Data data = { 0 }; + visit_files_w(windows10_lib, &data, win10_best); + if (data.best_name) { + result->windows_sdk_version = 10; + result->windows_sdk_root = data.best_name; + foundPaths = true; + } + } + + { + auto windows10_include = concat(windows10_root, L"Include"); + defer{ free(windows10_include); }; + + Version_Data data = { 0 }; + visit_files_w(windows10_include, &data, win10_best); + if (data.best_name) { + result->windows_sdk_version = 10; + result->windows_include_root = data.best_name; + foundPaths = true; + } + } + + if (foundPaths) + return; } // Look for a Windows 8 entry. @@ -332,16 +352,29 @@ void find_windows_kit_root(Find_Result *result) { if (windows8_root) { defer{ free(windows8_root); }; - auto windows8_lib = concat(windows8_root, L"Lib"); - defer{ free(windows8_lib); }; - - Version_Data data = { 0 }; - visit_files_w(windows8_lib, &data, win8_best); - if (data.best_name) { - result->windows_sdk_version = 8; - result->windows_sdk_root = data.best_name; - return; - } + { + auto windows8_lib = concat(windows8_root, L"Lib"); + defer{ free(windows8_lib); }; + + Version_Data data = { 0 }; + visit_files_w(windows8_lib, &data, win8_best); + if (data.best_name) { + result->windows_sdk_version = 8; + result->windows_sdk_root = data.best_name; + } + } + + { + auto windows8_include = concat(windows10_root, L"Include"); + defer{ free(windows8_include); }; + + Version_Data data = { 0 }; + visit_files_w(windows8_include, &data, win8_best); + if (data.best_name) { + result->windows_sdk_version = 8; + result->windows_include_root = data.best_name; + } + } } // If we get here, we failed to find anything. @@ -426,6 +459,7 @@ void find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res auto link_exe_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\bin\\Hostx64\\x64"); result->vs_exe_path = link_exe_path; result->vs_library_path = library_path; + result->vs_include_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\include"); return; } @@ -479,6 +513,7 @@ void find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res if (os_file_exists(vcruntime_filename)) { result->vs_exe_path = concat(buffer, L"VC\\bin"); result->vs_library_path = lib_path; + result->vs_include_path = concat(buffer, L"\\VC\\Include"); return; } @@ -498,6 +533,11 @@ Find_Result find_visual_studio_and_windows_sdk(SdkArch sdkArch) { result.windows_sdk_ucrt_library_path = concat(result.windows_sdk_root, L"\\ucrt\\x64"); } + if (result.windows_include_root) { + result.windows_include_um_path = concat(result.windows_include_root, L"\\um"); + result.windows_include_ucrt_path = concat(result.windows_include_root, L"\\ucrt"); + } + find_visual_studio_by_fighting_through_microsoft_craziness(&result); return result; @@ -507,6 +547,10 @@ void free_resources(Find_Result *result) { free(result->windows_sdk_root); free(result->windows_sdk_um_library_path); free(result->windows_sdk_ucrt_library_path); + free(result->windows_include_root); + free(result->windows_include_um_path); + free(result->windows_include_ucrt_path); free(result->vs_exe_path); free(result->vs_library_path); + free(result->vs_include_path); } diff --git a/msvc/locate_windows_sdk/locate_sdk.hpp b/msvc/locate_windows_sdk/locate_sdk.hpp index 6446aa4..49e0dd4 100644 --- a/msvc/locate_windows_sdk/locate_sdk.hpp +++ b/msvc/locate_windows_sdk/locate_sdk.hpp @@ -10,8 +10,13 @@ struct Find_Result { wchar_t *windows_sdk_um_library_path = NULL; wchar_t *windows_sdk_ucrt_library_path = NULL; + wchar_t *windows_include_root = NULL; + wchar_t *windows_include_um_path = NULL; + wchar_t *windows_include_ucrt_path = NULL; + wchar_t *vs_exe_path = NULL; wchar_t *vs_library_path = NULL; + wchar_t *vs_include_path = NULL; }; enum SdkArch diff --git a/msvc/locate_windows_sdk/locate_windows_sdk.vcxproj.user b/msvc/locate_windows_sdk/locate_windows_sdk.vcxproj.user index be25078..e6bd7b3 100644 --- a/msvc/locate_windows_sdk/locate_windows_sdk.vcxproj.user +++ b/msvc/locate_windows_sdk/locate_windows_sdk.vcxproj.user @@ -1,4 +1,7 @@  - + + x64 + WindowsLocalDebugger + \ No newline at end of file diff --git a/msvc/locate_windows_sdk/main.cpp b/msvc/locate_windows_sdk/main.cpp index 7f9b0a4..7fb5657 100644 Binary files a/msvc/locate_windows_sdk/main.cpp and b/msvc/locate_windows_sdk/main.cpp differ diff --git a/msvc/sibs.exe b/msvc/sibs.exe index 21b3e83..7898953 100644 Binary files a/msvc/sibs.exe and b/msvc/sibs.exe differ diff --git a/src/Exec.cpp b/src/Exec.cpp index 6c1a72e..659d812 100644 --- a/src/Exec.cpp +++ b/src/Exec.cpp @@ -99,13 +99,8 @@ namespace sibs if (!CreateProcessW(nullptr, (LPWSTR)cmdNonConst.data(), nullptr, nullptr, TRUE, 0, nullptr, nullptr, &siStartInfo, &piProcInfo)) goto cleanupAndExit; - WaitForSingleObject(piProcInfo.hProcess, INFINITE); - GetExitCodeProcess(piProcInfo.hProcess, &exitCode); - CloseHandle(piProcInfo.hProcess); - CloseHandle(piProcInfo.hThread); CloseHandle(childStdoutHandle); childStdoutHandle = nullptr; - DWORD bytesRead; CHAR buffer[BUFSIZE]; while (true) @@ -119,6 +114,11 @@ namespace sibs printf("%.*s", bytesRead, buffer); } + WaitForSingleObject(piProcInfo.hProcess, INFINITE); + GetExitCodeProcess(piProcInfo.hProcess, &exitCode); + CloseHandle(piProcInfo.hProcess); + CloseHandle(piProcInfo.hThread); + { ExecResult execResult; execResult.execStdout = move(execStdout); diff --git a/src/FileUtil.cpp b/src/FileUtil.cpp index 77669e5..e29ed36 100644 --- a/src/FileUtil.cpp +++ b/src/FileUtil.cpp @@ -16,6 +16,19 @@ using namespace std; +#if OS_FAMILY == OS_FAMILY_POSIX +static int makedir(const _tinydir_char_t *dir) +{ + return mkdir(dir, S_IRWXU); +} +#elif OS_FAMILY == OS_FAMILY_WINDOWS + +static int makedir(const _tinydir_char_t *dir) +{ + return _wmkdir(dir); +} +#endif + namespace sibs { #if OS_FAMILY == OS_FAMILY_POSIX @@ -263,45 +276,21 @@ namespace sibs fclose(file); return Result::Ok(true); } -#if OS_FAMILY == OS_FAMILY_POSIX - Result getHomeDir() - { - const char *homeDir = getenv("HOME"); - if(!homeDir) - { - passwd *pw = getpwuid(getuid()); - homeDir = pw->pw_dir; - } - return Result::Ok(homeDir); - } - - Result getCwd() - { - FileString cwd; - cwd.resize(_TINYDIR_PATH_MAX); - if(getcwd(&cwd[0], _TINYDIR_PATH_MAX) != 0) - { - if(cwd.empty()) cwd = "."; - cwd.resize(_tinydir_strlen(cwd.c_str())); - return Result::Ok(cwd); - } - return Result::Err(strerror(errno)); - } Result createDirectory(const _tinydir_char_t *path) { - size_t pathLength = strlen(path); - if(pathLength > _TINYDIR_PATH_MAX - 1) + size_t pathLength = _tinydir_strlen(path); + if (pathLength > _TINYDIR_PATH_MAX - 1) { string errMsg = "Directory path too long: "; - errMsg += string(path, pathLength); + errMsg += toUtf8(FileString(path, pathLength)); return Result::Err(errMsg, ENAMETOOLONG); } - if(mkdir(path, S_IRWXU) != 0) + if (makedir(path) != 0) { int error = errno; - if(error != EEXIST) + if (error != EEXIST) { string errMsg = "Failed to create directory: "; errMsg += toUtf8(path); @@ -315,47 +304,46 @@ namespace sibs Result createDirectoryRecursive(const _tinydir_char_t *path) { - char pathBuffer[_TINYDIR_PATH_MAX]; - size_t pathLength = strlen(path); - if(pathLength > sizeof(pathBuffer) - 1) + _tinydir_char_t pathBuffer[_TINYDIR_PATH_MAX]; + size_t pathLength = _tinydir_strlen(path); + if (pathLength > sizeof(pathBuffer) - 1) { string errMsg = "Directory path too long: "; - errMsg += string(path, pathLength); + errMsg += toUtf8(FileString(path, pathLength)); return Result::Err(errMsg, ENAMETOOLONG); } - strcpy(pathBuffer, path); + _tinydir_strcpy(pathBuffer, path); - char *p = pathBuffer; - for(size_t i = 0; i < pathLength; ++i) + _tinydir_char_t *p = pathBuffer; + for (size_t i = 0; i < pathLength; ++i) { - char c = *p; - if(i > 0 && (c == '/' || c == '\\')) + if (i > 0 && *p == '/') { *p = '\0'; - if(mkdir(pathBuffer, S_IRWXU) != 0) + if (makedir(pathBuffer) != 0) { int error = errno; - if(error != EEXIST) + if (error != EEXIST) { string errMsg = "Failed to create directory: "; - errMsg += pathBuffer; + errMsg += toUtf8(pathBuffer); errMsg += "; reason: "; errMsg += strerror(error); return Result::Err(errMsg, error); } } - *p = c; + *p = '/'; } ++p; } - if(mkdir(pathBuffer, S_IRWXU) != 0) + if (makedir(pathBuffer) != 0) { int error = errno; - if(error != EEXIST) + if (error != EEXIST) { string errMsg = "Failed to create directory: "; - errMsg += pathBuffer; + errMsg += toUtf8(pathBuffer); errMsg += "; reason: "; errMsg += strerror(error); return Result::Err(errMsg, error); @@ -365,6 +353,31 @@ namespace sibs return Result::Ok(true); } +#if OS_FAMILY == OS_FAMILY_POSIX + Result getHomeDir() + { + const char *homeDir = getenv("HOME"); + if(!homeDir) + { + passwd *pw = getpwuid(getuid()); + homeDir = pw->pw_dir; + } + return Result::Ok(homeDir); + } + + Result getCwd() + { + FileString cwd; + cwd.resize(_TINYDIR_PATH_MAX); + if(getcwd(&cwd[0], _TINYDIR_PATH_MAX) != 0) + { + if(cwd.empty()) cwd = "."; + cwd.resize(_tinydir_strlen(cwd.c_str())); + return Result::Ok(cwd); + } + return Result::Err(strerror(errno)); + } + Result getRealPath(const _tinydir_char_t *path) { // TODO: Verify NULL can be passed as 'resolved' argument with different compilers and operating systems (clang, freebsd etc) @@ -420,57 +433,6 @@ namespace sibs return Result::Ok(cwd); } - Result createDirectoryRecursive(const _tinydir_char_t *path) - { - _tinydir_char_t pathBuffer[_TINYDIR_PATH_MAX]; - size_t pathLength = _tinydir_strlen(path); - if (pathLength > sizeof(pathBuffer) - 1) - { - string errMsg = "Directory path too long: "; - errMsg += toUtf8(FileString(path, pathLength)); - return Result::Err(errMsg, ENAMETOOLONG); - } - _tinydir_strcpy(pathBuffer, path); - - _tinydir_char_t *p = pathBuffer; - for (size_t i = 0; i < pathLength; ++i) - { - if (i > 0 && *p == '/') - { - *p = '\0'; - if (_wmkdir(pathBuffer) != 0) - { - int error = errno; - if (error != EEXIST) - { - string errMsg = "Failed to create directory: "; - errMsg += toUtf8(pathBuffer); - errMsg += "; reason: "; - errMsg += strerror(error); - return Result::Err(errMsg, error); - } - } - *p = '/'; - } - ++p; - } - - if (_wmkdir(pathBuffer) != 0) - { - int error = errno; - if (error != EEXIST) - { - string errMsg = "Failed to create directory: "; - errMsg += toUtf8(pathBuffer); - errMsg += "; reason: "; - errMsg += strerror(error); - return Result::Err(errMsg, error); - } - } - - return Result::Ok(true); - } - Result getRealPath(const _tinydir_char_t *path) { FileString fullPath; diff --git a/src/PkgConfig.cpp b/src/PkgConfig.cpp index 3a36f39..faed146 100644 --- a/src/PkgConfig.cpp +++ b/src/PkgConfig.cpp @@ -1,5 +1,4 @@ #include "../include/PkgConfig.hpp" -#if OS_FAMILY == OS_FAMILY_POSIX #include "../include/Exec.hpp" #include "../include/Dependency.hpp" @@ -35,9 +34,9 @@ namespace sibs Result PkgConfig::validatePackageExists(const string &name) { - string command = "pkg-config --exists '"; - command += name; - command += "'"; + FileString command = TINYDIR_STRING("pkg-config --exists '"); + command += toFileString(name); + command += TINYDIR_STRING("'"); Result execResult = exec(command.c_str()); if(execResult.isErr()) return Result::Err(execResult.getErrMsg()); @@ -69,11 +68,11 @@ namespace sibs // Use --modversion instead and check if the version returned is newer or equal to dependency version. // This way we can output installed version vs expected dependency version - string command = "pkg-config '--atleast-version="; - command += version; - command += "' '"; - command += name; - command += "'"; + FileString command = TINYDIR_STRING("pkg-config '--atleast-version="); + command += toFileString(version); + command += TINYDIR_STRING("' '"); + command += toFileString(name); + command += TINYDIR_STRING("'"); Result execResult = exec(command.c_str()); if(execResult.isErr()) return Result::Err(execResult.getErrMsg()); @@ -112,8 +111,8 @@ namespace sibs args += "'"; } - string command = "pkg-config --libs"; - command += args; + FileString command = TINYDIR_STRING("pkg-config --libs"); + command += toFileString(args); Result execResult = exec(command.c_str()); if(execResult.isErr()) return Result::Err(execResult.getErrMsg()); @@ -155,8 +154,8 @@ namespace sibs args += "'"; } - string command = "pkg-config --cflags"; - command += args; + FileString command = TINYDIR_STRING("pkg-config --cflags"); + command += toFileString(args); Result execResult = exec(command.c_str()); if(execResult.isErr()) return Result::Err(execResult.getErrMsg()); @@ -202,5 +201,4 @@ namespace sibs flags.cflags = move(cflagsResult.unwrap()); return Result::Ok(flags); } -} -#endif // OS_FAMILY_POSIX +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index cb1c611..1da5202 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -227,15 +227,32 @@ static bool isPathSubPathOf(const FileString &path, const FileString &subPathOf) } #if OS_FAMILY == OS_FAMILY_WINDOWS -static char* join(const char *str1, const char *str2, const char separator) +static char* join(const vector &strs, const char separator) { - int str1len = strlen(str1); - int str2len = strlen(str2); - char *result = new char[str1len + 1 + str2len + 1]; - memcpy(result, str1, str1len); - result[str1len] = separator; - memcpy(result + str1len + 1, str2, str2len); - result[str1len + 1 + str2len] = '\0'; + vector lengths; + lengths.reserve(strs.size()); + int totalLength = strs.size() - 1; + for (const char *str : strs) + { + int length = strlen(str); + totalLength += length; + lengths.push_back(length); + } + + char *result = new char[totalLength + 1]; + result[totalLength] = '\0'; + int offset = 0; + for (int i = 0; i < strs.size(); ++i) + { + if (i > 0) + { + result[offset] = separator; + ++offset; + } + memcpy(result + offset, strs[i], lengths[i]); + offset += lengths[i]; + } + return result; } @@ -246,9 +263,17 @@ struct MicrosoftBuildTool // empty if not found char binPath[_TINYDIR_PATH_MAX]; // empty if not found + char vsLibPath[_TINYDIR_PATH_MAX]; + // empty if not found char umLibPath[_TINYDIR_PATH_MAX]; // empty if not found char ucrtLibPath[_TINYDIR_PATH_MAX]; + // empty if not found + char vsIncludePath[_TINYDIR_PATH_MAX]; + // empty if not found + char umIncludePath[_TINYDIR_PATH_MAX]; + // empty if not found + char ucrtIncludePath[_TINYDIR_PATH_MAX]; bool found() { @@ -259,32 +284,41 @@ struct MicrosoftBuildTool static MicrosoftBuildTool locateLatestMicrosoftBuildTool() { MicrosoftBuildTool result = { 0 }; - Result execResult = exec(TINYDIR_STRING("locate_windows_sdk")); + Result execResult = exec(TINYDIR_STRING("locate_windows_sdk x64")); if (execResult && execResult.unwrap().exitCode == 0) { auto &str = execResult.unwrap().execStdout; - sscanf(execResult.unwrap().execStdout.c_str(), "%d %[^\r\n] %[^\r\n] %[^\r\n]", &result.version, result.binPath, result.umLibPath, result.ucrtLibPath); + sscanf(execResult.unwrap().execStdout.c_str(), "%d %[^\r\n] %[^\r\n] %[^\r\n] %[^\r\n] %[^\r\n] %[^\r\n] %[^\r\n]", + &result.version, + result.binPath, + result.vsLibPath, + result.umLibPath, + result.ucrtLibPath, + result.vsIncludePath, + result.umIncludePath, + result.ucrtIncludePath); } return result; } +// We do not free allocated data here because they needs to live as long as they're used as env (in _putenv) static void appendMicrosoftBuildToolToPathEnv() { MicrosoftBuildTool msBuildTool = locateLatestMicrosoftBuildTool(); if (msBuildTool.found()) { fprintf(stderr, "Located microsoft build tools at %s\n", msBuildTool.binPath); - fprintf(stderr, "Located microsoft build libraries at %s;%s\n", msBuildTool.umLibPath, msBuildTool.ucrtLibPath); if (const char *pathEnv = getenv("PATH")) { - // We do not free this because it needs to live as long as it's used as env (in _putenv) - if (_putenv_s("PATH", join(pathEnv, msBuildTool.binPath, ';')) != 0) + if (_putenv_s("PATH", join({ pathEnv, msBuildTool.binPath }, ';')) != 0) fprintf(stderr, "Warning: Failed to add microsoft build tools to PATH env\n"); } - // We do not free this because it needs to live as long as it's used as env (in _putenv) - if (_putenv_s("LIB", join(msBuildTool.umLibPath, msBuildTool.ucrtLibPath, ';')) != 0) + if (_putenv_s("INCLUDE", join({ msBuildTool.vsIncludePath, msBuildTool.umIncludePath, msBuildTool.ucrtIncludePath }, ';')) != 0) + fprintf(stderr, "Warning: Failed to add microsoft build libraries to INCLUDE env\n"); + + if (_putenv_s("LIB", join({ msBuildTool.vsLibPath, msBuildTool.umLibPath, msBuildTool.ucrtLibPath }, ';')) != 0) fprintf(stderr, "Warning: Failed to add microsoft build libraries to LIB env\n"); } } -- cgit v1.2.3