Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows, build-runfiles: Implement build-runfiles for Windows #6024

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 24 additions & 25 deletions src/main/tools/build-runfiles-windows.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ using std::string;
using std::wstring;
using std::stringstream;

#define ManifestFileMap unordered_map<std::wstring, std::wstring>

#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2
#endif
Expand All @@ -40,6 +38,8 @@ using std::stringstream;
#define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
#endif

namespace {

const wchar_t *manifest_filename;
const wchar_t *runfiles_base_dir;

Expand Down Expand Up @@ -99,16 +99,18 @@ wstring GetParentDirFromPath(const wstring& path) {
return path.substr(0, path.find_last_of(L"\\/"));
}

inline wstring Trim(const wstring& str){
wstring result = str;
result.erase(0, result.find_first_not_of(' '));
result.erase(result.find_last_not_of(' ') + 1);
return result;
inline void Trim(wstring& str){
str.erase(0, str.find_first_not_of(' '));
str.erase(str.find_last_not_of(' ') + 1);
}

} // namespace

class RunfilesCreator {
typedef std::unordered_map<std::wstring, std::wstring> ManifestFileMap;

public:
explicit RunfilesCreator(const wstring &manifest_path,
RunfilesCreator(const wstring &manifest_path,
const wstring &runfiles_output_base)
: manifest_path_(manifest_path),
runfiles_output_base_(runfiles_output_base) {
Expand Down Expand Up @@ -149,8 +151,8 @@ class RunfilesCreator {
}

// Removing leading and trailing spaces
link = Trim(link);
target = Trim(target);
Trim(link);
Trim(target);

if (!allow_relative && !target.empty()
&& !blaze_util::IsAbsolute(target)) {
Expand All @@ -161,7 +163,6 @@ class RunfilesCreator {

manifest_file_map.insert(make_pair(link, target));
laszlocsomor marked this conversation as resolved.
Show resolved Hide resolved
}
manifest_file.close();
}

void CreateRunfiles() {
Expand Down Expand Up @@ -304,40 +305,38 @@ class RunfilesCreator {
? 0
: SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;

for (ManifestFileMap::const_iterator it = manifest_file_map.begin();
it != manifest_file_map.end(); ++it) {

for (const auto &it : manifest_file_map) {
// Ensure the parent directory exists
wstring parent_dir = GetParentDirFromPath(it->first);
wstring parent_dir = GetParentDirFromPath(it.first);
if (!DoesDirectoryPathExist(parent_dir.c_str())) {
MakeDirectoriesOrDie(parent_dir);
}

if (it->second.empty()) {
if (it.second.empty()) {
// Create an empty file
HANDLE h = CreateFileW(it->first.c_str(), // name of the file
HANDLE h = CreateFileW(it.first.c_str(), // name of the file
GENERIC_WRITE, // open for writing
0, // sharing mode, none in this case
0, // use default security descriptor
CREATE_ALWAYS, // overwrite if exists
FILE_ATTRIBUTE_NORMAL,
0);
if (h) {
if (h != INVALID_HANDLE_VALUE) {
CloseHandle(h);
} else {
die(L"CreateFileW failed (%s): %hs",
it->first.c_str(), GetLastErrorString().c_str());
it.first.c_str(), GetLastErrorString().c_str());
}
} else {
DWORD create_dir = 0;
if (blaze_util::IsDirectoryW(it->second.c_str())) {
if (blaze_util::IsDirectoryW(it.second.c_str())) {
create_dir = SYMBOLIC_LINK_FLAG_DIRECTORY;
}
if (!CreateSymbolicLinkW(it->first.c_str(),
it->second.c_str(),
if (!CreateSymbolicLinkW(it.first.c_str(),
it.second.c_str(),
privilege_flag | create_dir)) {
die(L"CreateSymbolicLinkW failed (%s -> %s): %hs",
it->first.c_str(), it->second.c_str(),
it.first.c_str(), it.second.c_str(),
GetLastErrorString().c_str());
}
}
Expand All @@ -348,7 +347,7 @@ class RunfilesCreator {
wstring new_manifest_file = runfiles_output_base_ + L"\\MANIFEST";
if (!CopyFileW(manifest_path_.c_str(),
new_manifest_file.c_str(),
/*bFailIfExists=*/ false
/*bFailIfExists=*/ FALSE
)) {
die(L"CopyFileW failed (%s -> %s): %hs",
manifest_path_.c_str(), new_manifest_file.c_str(),
Expand Down Expand Up @@ -381,7 +380,7 @@ int wmain(int argc, wchar_t** argv) {

if (argc != 2) {
fprintf(stderr, "usage: [--allow_relative] [--use_metadata] "
"INPUT RUNFILES\n");
"manifest_file runfiles_base_dir\n");
laszlocsomor marked this conversation as resolved.
Show resolved Hide resolved
return 1;
}

Expand Down
37 changes: 17 additions & 20 deletions src/test/shell/integration/runfiles_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,17 @@ esac
if "$is_windows"; then
export MSYS_NO_PATHCONV=1
export MSYS2_ARG_CONV_EXCL="*"
export EXT=".exe"
export EXTRA_BUILD_FLAGS="--experimental_enable_runfiles --build_python_zip=0"
else
export EXT=""
export EXTRA_BUILD_FLAGS=""
fi

#### SETUP #############################################################

set -e

function set_up() {
if "$is_windows"; then
export EXT=".exe"
export EXTRA_BUILD_FLAGS="--experimental_enable_runfiles --build_python_zip=0"
else
export EXT=""
export EXTRA_BUILD_FLAGS=""
fi
}

function create_pkg() {
local -r pkg=$1
mkdir -p $pkg
Expand Down Expand Up @@ -199,14 +194,15 @@ EOF
fi

for i in $(find ${WORKSPACE_NAME} \! -type d); do
if readlink "$i" > /dev/null; then
target="$(readlink "$i" || true)"
if [[ -z "$target" ]]; then
echo "$i " >> ${TEST_TMPDIR}/MANIFEST2
else
if "$is_windows"; then
echo "$i $(cygpath -m $(readlink "$i"))" >> ${TEST_TMPDIR}/MANIFEST2
echo "$i $(cygpath -m $target)" >> ${TEST_TMPDIR}/MANIFEST2
else
echo "$i $(readlink "$i")" >> ${TEST_TMPDIR}/MANIFEST2
echo "$i $target" >> ${TEST_TMPDIR}/MANIFEST2
fi
else
echo "$i " >> ${TEST_TMPDIR}/MANIFEST2
fi
done
sort MANIFEST > ${TEST_TMPDIR}/MANIFEST_sorted
Expand Down Expand Up @@ -274,14 +270,15 @@ EOF
rm -f ${TEST_TMPDIR}/MANIFEST
rm -f ${TEST_TMPDIR}/MANIFEST2
for i in $(find ${WORKSPACE_NAME} \! -type d); do
if readlink "$i" > /dev/null; then
target="$(readlink "$i" || true)"
if [[ -z "$target" ]]; then
echo "$i " >> ${TEST_TMPDIR}/MANIFEST2
else
if "$is_windows"; then
echo "$i $(cygpath -m $(readlink "$i"))" >> ${TEST_TMPDIR}/MANIFEST2
echo "$i $(cygpath -m $target)" >> ${TEST_TMPDIR}/MANIFEST2
else
echo "$i $(readlink "$i")" >> ${TEST_TMPDIR}/MANIFEST2
echo "$i $target" >> ${TEST_TMPDIR}/MANIFEST2
fi
else
echo "$i " >> ${TEST_TMPDIR}/MANIFEST2
fi
done
sort MANIFEST > ${TEST_TMPDIR}/MANIFEST_sorted
Expand Down