Skip to content

Commit

Permalink
Make this program more configurable for compilers with incomplete sta…
Browse files Browse the repository at this point in the history
…ndard C++ library support.
  • Loading branch information
JPeterMugaas committed Jun 30, 2024
1 parent 695cfaf commit 91ccdf6
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 32 deletions.
55 changes: 53 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

cmake_minimum_required (VERSION 3.21)

set(EFXC2_VERSION 0.0.13.259)
set(EFXC2_VERSION 0.0.13.261)
project (efxc2 VERSION ${EFXC2_VERSION}
DESCRIPTION "Enhanced fxc2"
HOMEPAGE_URL "https://github.com/JPeterMugaas/efxc2"
Expand All @@ -34,8 +34,59 @@ list(APPEND CMAKE_MODULE_PATH "${EFXC2_FMT_PATH}/lib/cmake")
list(APPEND CMAKE_INCLUDE_PATH "${EFXC2_FMT_PATH}/include")
list(APPEND CMAKE_LIBRARY_PATH "${EFXC2_FMT_PATH}/lib")

message(STATUS "Check for C++20 formatting library")
message(STATUS "Check for C++20 std::bit_cast support")
file(WRITE
${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp
"#include <iostream>\r\n"
"#include <string>\r\n"
"#include <bit>\r\n"
"\r\n"
"int main()\r\n"
"{\r\n"
"int number = -1;\r\n"
"std::cout << std::to_string(std::bit_cast<unsigned int>(number));\r\n"
"return 0;\r\n"
"}\r\n")
try_compile(BIT_CAST_SUPPORTED
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp
OUTPUT_VARIABLE OUTPUT)
if (BIT_CAST_SUPPORTED)
message(STATUS "Check for C++20 std::bit_cast support - yes")
else()
message(STATUS "Check for C++20 std::bit_cast support - no")
endif()


message(STATUS "Check for C++20 std::ranges support")
file(WRITE
${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp
"#include <algorithm>\r\n"
"#include <iostream>\r\n"
"#include <ranges>\r\n"
"#include <vector>\r\n"
"\r\n"
"int main()\r\n"
"{\r\n"
"std::vector<int> numbers = { 1, 2, 3, 4, 5, 6 };\r\n"
"\r\n"
"auto print = [](const int& n) { std::cout << n << ' '; };\r\n"
"\r\n"
"std::ranges::for_each (numbers.begin(), numbers.end(), print);\r\n"
"return 0;\r\n"
"}\r\n")
try_compile(RANGES_SUPPORTED
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp
OUTPUT_VARIABLE OUTPUT)
if (RANGES_SUPPORTED)
message(STATUS "Check for C++20 std::ranges support - yes")
else()
message(STATUS "Check for C++20 std::ranges support - no")
endif()

set(USE_FMT_LIBRARY OFF)
message(STATUS "Check for C++20 formatting library")
file(WRITE
${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp
"#include <iostream>\r\n"
Expand Down
34 changes: 17 additions & 17 deletions efxc2Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void efxc2Compiler::SetupDefines(efxc2Utils::M_COMPILER_DEFINES _defines, std::v
_def.Name = a.Name.c_str();
(void)defines.insert(defines.end(), _def); };

(void)std::ranges::for_each(_defines->begin(), _defines->end(), insert_def);
(void)M_FOR_EACH(_defines->begin(), _defines->end(), insert_def);

_def.Definition = nullptr;
_def.Name = nullptr;
Expand All @@ -35,7 +35,7 @@ void efxc2Compiler::SetupDefines(efxc2Utils::M_COMPILER_DEFINES _defines, std::v

void efxc2Compiler::print_defines(std::vector<D3D_SHADER_MACRO> const& defines) {
std::cout << "\t";
(void)std::ranges::for_each(defines, print_D3D_SHADER_MACRO);
(void)M_FOR_EACH(defines, print_D3D_SHADER_MACRO);
std::cout << ",\n";
}

Expand Down Expand Up @@ -106,7 +106,7 @@ void efxc2Compiler::Compiler::Preprocess() {
std::cerr << "Preprocess error";
console.std_out_pink();
if (errors) {
auto* error = std::bit_cast<char*>(errors->GetBufferPointer());
auto* error = M_BIT_CAST<char*>(errors->GetBufferPointer());
std::cout << M_FORMAT("Got an error while preprocessing:\n{}\n", error);
(void)errors->Release();
std::cout << M_FORMAT("Error Code: {:#08x}", hr);
Expand Down Expand Up @@ -210,7 +210,7 @@ void efxc2Compiler::Compiler::Compile() {
console.std_out_pink();
std::cerr << "Compile error";
if (errors) {
auto* error = std::bit_cast<char*>(errors->GetBufferPointer());
auto* error = M_BIT_CAST<char*>(errors->GetBufferPointer());
std::cout << M_FORMAT("Got an error while compiling:\n{}\n", error);
(void)errors->Release();
std::cout << M_FORMAT("Error Code: {:#08x}", hr);
Expand All @@ -227,7 +227,7 @@ void efxc2Compiler::Compiler::Compile() {
}

void efxc2Compiler::Compiler::Disassemble() {
auto const* compiledString = std::bit_cast<unsigned char*>(compilerOutput->GetBufferPointer());
auto const* compiledString = M_BIT_CAST<unsigned char*>(compilerOutput->GetBufferPointer());
size_t compiledLen = compilerOutput->GetBufferSize();
auto disassembly_flags = params.get_disassembly_flags();
HRESULT hr = 0;
Expand Down Expand Up @@ -288,7 +288,7 @@ void efxc2Compiler::Compiler::StripShader() {
#pragma warning( push )
#pragma warning( disable : 6387)
#endif
auto const* compiledString = std::bit_cast<char*>(compilerOutput->GetBufferPointer());
auto const* compiledString = M_BIT_CAST<char*>(compilerOutput->GetBufferPointer());
size_t compiledLen = compilerOutput->GetBufferSize();
HRESULT hr = 0;
auto ptr = api.get_ptr_D3DStripShader();
Expand All @@ -309,7 +309,7 @@ size_t efxc2Compiler::Compiler::WriteAssemblyCode(std::ofstream& f) {
size_t outputLen = 0;

if (disassemblyCodeBlob != nullptr) {
outputString = std::bit_cast<char*>(disassemblyCodeBlob->GetBufferPointer());
outputString = M_BIT_CAST<char*>(disassemblyCodeBlob->GetBufferPointer());
outputLen = disassemblyCodeBlob->GetBufferSize();
(void)f.write(outputString, outputLen);
}
Expand Down Expand Up @@ -341,19 +341,19 @@ size_t efxc2Compiler::Compiler::WriteObjectFile(std::ofstream& f) {
char const* outputString;
size_t outputLen = 0;
if (strippedBlob == nullptr) {
outputString = std::bit_cast<char*>(compilerOutput->GetBufferPointer());
outputString = M_BIT_CAST<char*>(compilerOutput->GetBufferPointer());
outputLen = compilerOutput->GetBufferSize();
}
else {
outputString = std::bit_cast<char*>(strippedBlob->GetBufferPointer());
outputString = M_BIT_CAST<char*>(strippedBlob->GetBufferPointer());
outputLen = strippedBlob->GetBufferSize();
}
(void)f.write(outputString, outputLen);
return outputLen;
}

size_t efxc2Compiler::Compiler::WritePreprocessFile(std::ofstream& f) {
const char* outputString = std::bit_cast<char*>(pPreprocessOutput->GetBufferPointer());
const char* outputString = M_BIT_CAST<char*>(pPreprocessOutput->GetBufferPointer());
size_t outputLen = pPreprocessOutput->GetBufferSize();
(void)f.write(outputString, outputLen);
return outputLen;
Expand All @@ -367,7 +367,7 @@ std::string efxc2Compiler::Compiler::GetPDBFileName() {
*/

auto const* compiledString = std::bit_cast<unsigned char*>(compilerOutput->GetBufferPointer());
auto const* compiledString = M_BIT_CAST<unsigned char*>(compilerOutput->GetBufferPointer());
size_t compiledLen = compilerOutput->GetBufferSize();
HRESULT hr = 0;
/*Get filename*/
Expand All @@ -394,7 +394,7 @@ std::string efxc2Compiler::Compiler::GetPDBFileName() {
efxc2Utils::print_hresult_error(hr);
throw efxc2Exception::Win32HLSLFailure();
}
char* pName = std::bit_cast<char*>(pPDBName->GetBufferPointer());
char* pName = M_BIT_CAST<char*>(pPDBName->GetBufferPointer());
/* Skip over reserved feild - uint_16 and length field uint_16*/
for (int i = 0; i <= 3; i++) {
++pName;
Expand All @@ -406,7 +406,7 @@ std::string efxc2Compiler::Compiler::GetPDBFileName() {
}

void efxc2Compiler::Compiler::EmbedPrivateData() {
auto const* compiledString = std::bit_cast<unsigned char*>(compilerOutput->GetBufferPointer());
auto const* compiledString = M_BIT_CAST<unsigned char*>(compilerOutput->GetBufferPointer());
size_t compiledLen = compilerOutput->GetBufferSize();
auto private_data = params.get_PrivateData();
size_t private_data_size = private_data->size();
Expand Down Expand Up @@ -459,7 +459,7 @@ void efxc2Compiler::Compiler::SetPDBFileName(_In_ const std::string_view _fileNa
pNameBlobContent.resize(nameBlobPartSize + sizeof(ShaderDebugName));
// Ensure bytes after name are indeed zeroes:
(void)std::ranges::fill(pNameBlobContent, 0);
auto* header = std::bit_cast<ShaderDebugName*>(&pNameBlobContent[0]);
auto* header = M_BIT_CAST<ShaderDebugName*>(&pNameBlobContent[0]);

header->Flags = 0;
// declared length does not include the null terminator:
Expand All @@ -470,7 +470,7 @@ void efxc2Compiler::Compiler::SetPDBFileName(_In_ const std::string_view _fileNa
pNameBlobContent[sizeof(ShaderDebugName) + i] = _fileName[i];
}

auto const* compiledString = std::bit_cast<unsigned char*>(compilerOutput->GetBufferPointer());
auto const* compiledString = M_BIT_CAST<unsigned char*>(compilerOutput->GetBufferPointer());
size_t compiledLen = compilerOutput->GetBufferSize();

if (params.get_verbose() && params.get_debug()) {
Expand Down Expand Up @@ -508,7 +508,7 @@ size_t efxc2Compiler::Compiler::WritePDBFile(std::ofstream& f) {
ID3DBlob* PDBData = nullptr;
char const* compiledString = nullptr;
size_t compiledLen = 0;
compiledString = std::bit_cast<char*>(compilerOutput->GetBufferPointer());
compiledString = M_BIT_CAST<char*>(compilerOutput->GetBufferPointer());
compiledLen = compilerOutput->GetBufferSize();
if (params.get_verbose() && params.get_debug()) {
std::cout << "Calling D3DGetBlobPart(\n";
Expand All @@ -532,7 +532,7 @@ size_t efxc2Compiler::Compiler::WritePDBFile(std::ofstream& f) {
efxc2Utils::print_hresult_error(hr);
throw efxc2Exception::Win32HLSLFailure();
}
auto outputString = std::bit_cast<char*>(PDBData->GetBufferPointer());
auto outputString = M_BIT_CAST<char*>(PDBData->GetBufferPointer());
size_t outputLen = PDBData->GetBufferSize();
(void)f.write(outputString, outputLen);
return compiledLen;
Expand Down
16 changes: 8 additions & 8 deletions efxc2CompilerAPIContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() {
#pragma warning( push )
#pragma warning( disable : 6387)
#endif
ptr_D3DCompile2 = std::bit_cast<pD3DCompile2g>(GetProcAddress(h, FCN_D3DCompile2));
ptr_D3DCompile2 = M_BIT_CAST<pD3DCompile2g>(GetProcAddress(h, FCN_D3DCompile2));
#ifdef _MSC_VER
#pragma warning( pop )
#endif
Expand All @@ -37,55 +37,55 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() {
efxc2Utils::print_windows_error();
throw efxc2Exception::Win32APIFailure();
}
ptr_D3DStripShader = std::bit_cast<pD3DStripShaderg>(GetProcAddress(h, FCN_D3DStripShader));
ptr_D3DStripShader = M_BIT_CAST<pD3DStripShaderg>(GetProcAddress(h, FCN_D3DStripShader));
if (ptr_D3DStripShader == nullptr) {
console.PinkOutput();
std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DStripShader);
console.ResetOutput();
efxc2Utils::print_windows_error();
throw efxc2Exception::Win32APIFailure();
}
ptr_D3DGetBlobPart = std::bit_cast<pD3DGetBlobPartg>(GetProcAddress(h, FCN_D3DGetBlobPart));
ptr_D3DGetBlobPart = M_BIT_CAST<pD3DGetBlobPartg>(GetProcAddress(h, FCN_D3DGetBlobPart));
if (ptr_D3DGetBlobPart == nullptr) {
console.PinkOutput();
std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DGetBlobPart);
console.ResetOutput();
efxc2Utils::print_windows_error();
throw efxc2Exception::Win32APIFailure();
}
ptr_D3DSetBlobPart = std::bit_cast<pD3DSetBlobPartg>(GetProcAddress(h, FCN_D3DSetBlobPart));
ptr_D3DSetBlobPart = M_BIT_CAST<pD3DSetBlobPartg>(GetProcAddress(h, FCN_D3DSetBlobPart));
if (ptr_D3DSetBlobPart == nullptr) {
console.PinkOutput();
std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DSetBlobPart);
console.ResetOutput();
efxc2Utils::print_windows_error();
throw efxc2Exception::Win32APIFailure();
}
ptr_D3DDisassemble = std::bit_cast<pD3DDisassembleg>(GetProcAddress(h, FCN_D3DDisassemble));
ptr_D3DDisassemble = M_BIT_CAST<pD3DDisassembleg>(GetProcAddress(h, FCN_D3DDisassemble));
if (ptr_D3DDisassemble == nullptr) {
console.PinkOutput();
std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DDisassemble);
console.ResetOutput();
efxc2Utils::print_windows_error();
throw efxc2Exception::Win32APIFailure();
}
ptr_D3DLoadModule = std::bit_cast<gD3DLoadModulep>(GetProcAddress(h, FCN_D3DLoadModule));
ptr_D3DLoadModule = M_BIT_CAST<gD3DLoadModulep>(GetProcAddress(h, FCN_D3DLoadModule));
if (ptr_D3DLoadModule == nullptr) {
console.PinkOutput();
std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DLoadModule);
console.ResetOutput();
efxc2Utils::print_windows_error();
throw efxc2Exception::Win32APIFailure();
}
ptr_D3DCreateLinker = std::bit_cast<gD3DCreateLinkerp>(GetProcAddress(h, FCN_D3DCreateLinker));
ptr_D3DCreateLinker = M_BIT_CAST<gD3DCreateLinkerp>(GetProcAddress(h, FCN_D3DCreateLinker));
if (ptr_D3DCreateLinker == nullptr) {
console.PinkOutput();
std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DCreateLinker);
console.ResetOutput();
efxc2Utils::print_windows_error();
throw efxc2Exception::Win32APIFailure();
}
ptr_D3DCreateFunctionLinkingGraph = std::bit_cast<gD3DCreateFunctionLinkingGraphp>(GetProcAddress(h, FCN_D3DCreateFunctionLinkingGraph));
ptr_D3DCreateFunctionLinkingGraph = M_BIT_CAST<gD3DCreateFunctionLinkingGraphp>(GetProcAddress(h, FCN_D3DCreateFunctionLinkingGraph));
if (ptr_D3DCreateFunctionLinkingGraph == nullptr) {
console.PinkOutput();
std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DCreateFunctionLinkingGraph);
Expand Down
2 changes: 1 addition & 1 deletion efxc2CompilerIncludes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ namespace efxc2CompilerIncludes {
std::cout << "\tpData: nullptr\n";
}
}
auto buf = std::bit_cast<char*>(pData);
auto buf = M_BIT_CAST<char*>(pData);
delete[] buf; //-V2511
return S_OK;
}
Expand Down
8 changes: 4 additions & 4 deletions efxc2Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void efxc2Utils::print_hresult_error(const HRESULT hr) {
console.std_out_pink();
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), std::bit_cast<char*>(&messageBuffer), 0, nullptr);
nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), M_BIT_CAST<char*>(&messageBuffer), 0, nullptr);
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(suppress : 6387)
Expand Down Expand Up @@ -129,7 +129,7 @@ void efxc2Utils::print_windows_error() {
nullptr,
dLastError,
0,
std::bit_cast<wchar_t*>(&strErrorMessage),
M_BIT_CAST<wchar_t*>(&strErrorMessage),
0,
nullptr);

Expand Down Expand Up @@ -157,7 +157,7 @@ void efxc2Utils::WriteByteArrayConst(_In_ std::ofstream& f, ID3DBlob* data,
_In_ const int outputHex) {
size_t len = data->GetBufferSize();
f << M_FORMAT("const BYTE {}[] =\n{{\n", variableName);
auto p = std::bit_cast<unsigned char*>(data->GetBufferPointer());
auto p = M_BIT_CAST<unsigned char*>(data->GetBufferPointer());
for (size_t i = 0; i < len; i++) {
if (outputHex) {
f << M_FORMAT(" 0x{:02x}", *p);
Expand Down Expand Up @@ -388,7 +388,7 @@ std::wstring efxc2Utils::utf8_to_wstring(std::string const& str)
}
auto _wstr = std::make_unique<std::vector<char>>();
_wstr->resize((nchars + 1) * sizeof(wchar_t));
auto* wstr = std::bit_cast<wchar_t*>(_wstr->data());
auto* wstr = M_BIT_CAST<wchar_t*>(_wstr->data());
wstr[nchars] = L'\0'; //-V3539 //-V2563
if (terminate_function == false) {
err = _mbstowcs_s_l(&nchars, wstr, nchars, str.c_str(), str.length() + 1, locale);
Expand Down
22 changes: 22 additions & 0 deletions efxc2Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,28 @@
namespace efxc2Utils {
using M_BUFFER = std::shared_ptr<std::vector<char>>;

#ifndef RANGES_SUPPORTED
#define M_FOR_EACH std::for_each
#else
#define M_FOR_EACH std::ranges::for_each
#endif

#ifndef BIT_CAST_SUPPORTED
template <class T2, class T1>
T2 cpp11_bit_cast(T1 t1) {
static_assert(sizeof(T1) == sizeof(T2), "Types must match sizes");
static_assert(std::is_pod<T1>::value, "Requires POD input");
static_assert(std::is_pod<T2>::value, "Requires POD output");

T2 t2;
std::memcpy(std::addressof(t2), std::addressof(t1), sizeof(T1));
return t2;
}
#define M_BIT_CAST bit_cast
#else
#define M_BIT_CAST std::bit_cast
#endif

#ifdef _WIN32
using M_CMD_PARAMS = std::vector<std::wstring>;
using M_STRING = std::wstring;
Expand Down

0 comments on commit 91ccdf6

Please sign in to comment.