Skip to content

Commit

Permalink
Delete object files after linking and always get project directory fr…
Browse files Browse the repository at this point in the history
…om common source path (#11)
  • Loading branch information
suVrik authored and crosire committed Dec 27, 2018
1 parent 6ee4121 commit 171d683
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
27 changes: 16 additions & 11 deletions source/blink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@
#include <unordered_map>
#include <Windows.h>

static std::filesystem::path longest_path(const std::vector<std::filesystem::path> &paths)
static std::filesystem::path common_path(const std::vector<std::filesystem::path> &paths)
{
if (paths.empty())
return std::filesystem::path();

const std::wstring base_path = paths[0].parent_path().native() + std::filesystem::path::preferred_separator;
size_t length = base_path.size();
std::filesystem::path all_common_path = paths[0].parent_path();

for (auto it = paths.begin() + 1; it != paths.end(); ++it)
length = it->native().size() < length ? it->native().size() : std::min(length, static_cast<size_t>(
std::distance(base_path.begin(),
std::mismatch(base_path.begin(), base_path.end(), it->native().begin(), it->native().end()).first)));
for (auto it = paths.begin() + 1; it != paths.end(); ++it) {
std::filesystem::path common_path;
std::filesystem::path file_directory = it->parent_path();
for (auto it2 = file_directory.begin(), it3 = all_common_path.begin(); it2 != file_directory.end() && it3 != all_common_path.end() && *it2 == *it3; ++it2, ++it3) {
common_path /= *it2;
}
all_common_path = common_path;
}

return base_path.substr(0, base_path.rfind(std::filesystem::path::preferred_separator, length != 0 ? length : std::string::npos));
return all_common_path;
}

blink::application::application()
Expand Down Expand Up @@ -145,9 +148,8 @@ void blink::application::run()
}
}

// Fall back to extracting project directory from source files if the link info stream is missing in the PDB
if (std::error_code ec; _source_dir.empty() || !std::filesystem::exists(_source_dir, ec))
_source_dir = longest_path(cpp_files);
// The linker is invoked in solution directory, which may be out of source directory. Use source common path instead.
_source_dir = common_path(cpp_files);
}
else
{
Expand Down Expand Up @@ -289,6 +291,9 @@ void blink::application::run()
break;
}
}

// The OBJ file is not needed anymore.
DeleteFileW(object_file.c_str());
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions source/blink_linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ bool blink::application::link(const std::filesystem::path &path)
// Read COFF header from input file and check that it is of a valid format
IMAGE_FILE_HEADER header;
if (DWORD read; !ReadFile(file, &header, sizeof(header), &read, nullptr))
{
print("Failed to read an image file header.");
return false;
}

#ifdef _M_IX86
if (header.Machine != IMAGE_FILE_MACHINE_I386)
Expand All @@ -151,21 +154,30 @@ bool blink::application::link(const std::filesystem::path &path)
// Read section headers from input file (there is no optional header in COFF files, so it is right after the header read above)
std::vector<IMAGE_SECTION_HEADER> sections(header.NumberOfSections);
if (DWORD read; !ReadFile(file, sections.data(), header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), &read, nullptr))
{
print("Failed to read an image file sections.");
return false;
}

// Read symbol table from input file
SetFilePointer(file, header.PointerToSymbolTable, nullptr, FILE_BEGIN);

std::vector<IMAGE_SYMBOL> symbols(header.NumberOfSymbols);
if (DWORD read; !ReadFile(file, symbols.data(), header.NumberOfSymbols * sizeof(IMAGE_SYMBOL), &read, nullptr))
{
print("Failed to read an image file symbols.");
return false;
}

// The string table follows after the symbol table and is usually at the end of the file
const DWORD string_table_size = GetFileSize(file, nullptr) - (header.PointerToSymbolTable + header.NumberOfSymbols * sizeof(IMAGE_SYMBOL));

std::vector<char> strings(string_table_size);
if (DWORD read; !ReadFile(file, strings.data(), string_table_size, &read, nullptr))
{
print("Failed to read a string table.");
return false;
}

// Calculate total module size
SIZE_T allocated_module_size = 0;
Expand Down Expand Up @@ -217,7 +229,10 @@ bool blink::application::link(const std::filesystem::path &path)
SetFilePointer(file, section.PointerToRawData, nullptr, FILE_BEGIN);

if (DWORD read; !ReadFile(file, section_base, section.SizeOfRawData, &read, nullptr))
{
print("Failed to read a section raw data.");
return false;
}
}

section.PointerToRawData = static_cast<DWORD>(section_base - module_base);
Expand All @@ -229,7 +244,10 @@ bool blink::application::link(const std::filesystem::path &path)
SetFilePointer(file, section.PointerToRelocations, nullptr, FILE_BEGIN);

if (DWORD read; !ReadFile(file, section_base, section.NumberOfRelocations * sizeof(IMAGE_RELOCATION), &read, nullptr))
{
print("Failed to read relocations.");
return false;
}
}

section.PointerToRelocations = static_cast<DWORD>(section_base - module_base);
Expand Down

0 comments on commit 171d683

Please sign in to comment.