Okay, here are more details of the implementation and build process.
I'm implementing a hashing module for my own private project.
The hashing algoritms are categorized by using submodules.
To quote the manual about submodules:
"For instance, when requiring a.b.c, it will search for a C library for a. If found, it looks into it for an open function for the submodule; in our example, that would be luaopen_a_b_c. With this facility, a package can pack several C submodules into one single library, with each submodule keeping its original open function."
The hashing module is written in C++.
I've my own small header only library to help binding functions to the Lua world and to reduce boilerplate when dealing with userdata.
These compiler and linker flags are used by Visual Studio when building binaries for debug mode:
Lua dll
Compile flags:
/JMC /permissive- /ifcOutput "x64\Debug\" /GS /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl /Fd"Y:\PG1003\x64\Debug\Lua54.pdb" /Zc:inline /fp:precise /D "LUA_BUILD_AS_DLL" /D "_CRT_SECURE_NO_WARNINGS" /D "_DEBUG" /D "_CONSOLE" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX /Zc:forScope /RTC1 /Gd /MDd /std:c++23preview /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\Lua54.pch" /diagnostics:column
Linker flags:
/OUT:"Y:\PG1003\x64\Debug\Lua54.dll" /MANIFEST /NXCOMPAT /PDB:"Y:\PG1003\x64\Debug\Lua54.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"Y:\PG1003\x64\Debug\Lua54.lib" /DEBUG /DLL /MACHINE:X64 /INCREMENTAL /PGD:"Y:\PG1003\x64\Debug\Lua54.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\Lua54.dll.intermediate.manifest" /LTCGOUT:"x64\Debug\Lua54.iobj" /ERRORREPORT:PROMPT /ILK:"x64\Debug\Lua54.ilk" /NOLOGO /TLBID:1
Lua exe
Compile flags:
/JMC /permissive- /ifcOutput "x64\Debug\" /GS /W4 /Zc:wchar_t /I"Y:\PG1003\LibLua54" /ZI /Gm- /Od /sdl /Fd"x64\Debug\vc143.pdb" /Zc:inline /fp:precise /D "LUA_BUILD_AS_DLL" /D "_CRT_SECURE_NO_WARNINGS" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX /Zc:forScope /RTC1 /Gd /MDd /std:c++23preview /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\Lua54.pch" /diagnostics:column
Linker flags:
/OUT:"Y:\PG1003\x64\Debug\Lua54.exe" /MANIFEST /NXCOMPAT /PDB:"Y:\PG1003\x64\Debug\Lua54.pdb" /DYNAMICBASE "Lua54.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /INCREMENTAL /PGD:"Y:\PG1003\x64\Debug\Lua54.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\Lua54.exe.intermediate.manifest" /LTCGOUT:"x64\Debug\Lua54.iobj" /ERRORREPORT:PROMPT /ILK:"x64\Debug\Lua54.ilk" /NOLOGO /LIBPATH:"Y:\PG1003\x64\Debug\" /TLBID:1
Module
Compile flags:
/JMC /permissive- /ifcOutput "x64\Debug\" /GS /W4 /Zc:wchar_t /I"Y:\PG1003\LibLua54" /ZI /Gm- /Od /sdl /Fd"x64\Debug\vc143.pdb" /Zc:inline /fp:precise /D "LUA_BUILD_AS_DLL" /D "_CRT_SECURE_NO_WARNINGS" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX /Zc:forScope /RTC1 /Gd /MDd /std:c++23preview /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\Lua54.pch" /diagnostics:column
Linker flags:
/OUT:"Y:\PG1003\x64\Debug\hash.dll" /MANIFEST /NXCOMPAT /PDB:"Y:\PG1003\x64\Debug\hash.pdb" /DYNAMICBASE "Lua54.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"Y:\PG1003\x64\Debug\hash.lib" /DEBUG /DLL /MACHINE:X64 /INCREMENTAL /PGD:"Y:\PG1003\x64\Debug\hash.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:NO /ManifestFile:"x64\Debug\hash.dll.intermediate.manifest" /LTCGOUT:"x64\Debug\hash.iobj" /ERRORREPORT:PROMPT /ILK:"x64\Debug\hash.ilk" /NOLOGO /LIBPATH:"Y:\PG1003\x64\Debug\" /TLBID:1
The Lua executable and the module are dynamically linked to Lua54.dll.
These 3 projects (as they are called in Visual Studio) compile without errors and warnings.
The following is part of the source code.
To repeat myself; there are no errors thrown by Lua or Windows when `luaopen_hash_md5` is renamed to `luaopen_hash` and `require( "hash" )` is called instead of `require( "hash.md5" )`.
//
// Includes
//
// ...
//
#if defined( _WIN32 )
# define EXPORT __declspec( dllexport )
#else
# define EXPORT
#endif
//
// Implementation
//
// ...
//
static constexpr const luaL_Reg crc_functions[] =
{
{ "crc32", crc32::calculate_crc32 },
{ NULL, NULL }
};
static constexpr const luaL_Reg md5_functions[] =
{
{ "md5", md5::calculate_md5 },
{ "digest", md5::make_digest },
{ NULL, NULL }
};
extern "C"
{
EXPORT int luaopen_hash_crc( lua_State * const L ) noexcept
{
luaL_checkversion( L );
lua_newtable( L );
luaL_setfuncs( L, crc_functions, 0 );
return 1;
}
EXPORT int luaopen_hash_md5( lua_State * const L ) noexcept
{
luaL_checkversion( L );
register_metatable< md5::digest >( L );
lua_newtable( L );
luaL_setfuncs( L, md5_functions, 0 );
return 1;
}
}