windows: Trick to get UTF-8 encoded argv in main entry point
- Adapt exifprint to the new wmain strategy - Delete have_unicode_path - wmain does not work with MSYS & MinGW - cmake: entry point via cmake instead of pragma - cmake: better doc for MSVC flags - Fix entry point in sample apps - Adapt CMake code to work with MSVC & MinGW
This commit is contained in:
parent
7933ff401d
commit
fdfb295cc4
@ -9,7 +9,7 @@ project(exiv2 # use TWEAK to categorize the build
|
||||
# 1.00.0.20 = RC2 Preview
|
||||
# 1.00.0.29 = RC2 Development
|
||||
DESCRIPTION "Exif/IPTC/Xmp C++ metadata library and tools plus ICC Profiles, Previews and more."
|
||||
LANGUAGES CXX
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
@ -167,13 +167,7 @@ if(MSVC)
|
||||
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
endif ()
|
||||
|
||||
# Object Level Parallelism
|
||||
add_compile_options(/MP)
|
||||
add_definitions(-DNOMINMAX) # This definition is not only needed for Exiv2 but also for xmpsdk
|
||||
|
||||
# https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
|
||||
if (MSVC_VERSION GREATER_EQUAL "1910") # VS2017 and up
|
||||
add_compile_options("/Zc:__cplusplus")
|
||||
endif()
|
||||
|
||||
add_compile_options(/MP) # Object Level Parallelism
|
||||
add_compile_options(/utf-8) # Set source and execution character sets to UTF-8
|
||||
add_definitions(-DNOMINMAX) # This definition is not only needed for Exiv2 but also for xmpsdk
|
||||
endif()
|
||||
|
||||
@ -114,11 +114,20 @@ list(APPEND APPLICATIONS remotetest)
|
||||
# ******************************************************************************
|
||||
foreach(application ${APPLICATIONS})
|
||||
target_link_libraries(${application} PRIVATE exiv2lib)
|
||||
if(MSVC)
|
||||
target_link_libraries(${application} PRIVATE wmain)
|
||||
target_link_options(${application} PRIVATE "/ENTRY:wWinMainCRTStartup")
|
||||
endif()
|
||||
if (MINGW)
|
||||
target_link_libraries(${application} PRIVATE wmain)
|
||||
target_compile_options(${application} PRIVATE -municode)
|
||||
target_link_options(${application} PRIVATE -municode)
|
||||
endif()
|
||||
if( EXIV2_ENABLE_PNG )
|
||||
target_link_libraries(${application} PRIVATE ${ZLIB_LIBRARIES} )
|
||||
if (MSVC)
|
||||
set_target_properties(${application} PROPERTIES LINK_FLAGS "/ignore:4099") # Ignore missing PDBs
|
||||
endif()
|
||||
if (MSVC)
|
||||
set_target_properties(${application} PROPERTIES LINK_FLAGS "/ignore:4099") # Ignore missing PDBs
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
@ -25,25 +25,6 @@
|
||||
#include <cassert>
|
||||
#include <regex>
|
||||
|
||||
// https://github.com/Exiv2/exiv2/issues/468
|
||||
#if defined(EXV_UNICODE_PATH) && defined(__MINGW__)
|
||||
#undef EXV_UNICODE_PATH
|
||||
#endif
|
||||
|
||||
#ifdef EXV_UNICODE_PATH
|
||||
#define _tchar wchar_t
|
||||
#define _tstrcmp wcscmp
|
||||
#define _t(s) L##s
|
||||
#define _tcout wcout
|
||||
#define _tmain wmain
|
||||
#else
|
||||
#define _tchar char
|
||||
#define _tstrcmp strcmp
|
||||
#define _t(s) s
|
||||
#define _tcout cout
|
||||
#define _tmain main
|
||||
#endif
|
||||
|
||||
// copied from src/tiffvisitor_int.cpp
|
||||
static const Exiv2::TagInfo* findTag(const Exiv2::TagInfo* pList,uint16_t tag)
|
||||
{
|
||||
@ -52,31 +33,32 @@ static const Exiv2::TagInfo* findTag(const Exiv2::TagInfo* pList,uint16_t tag)
|
||||
}
|
||||
|
||||
|
||||
int _tmain(int argc, _tchar* const argv[])
|
||||
int main(int argc, char* const argv[])
|
||||
try {
|
||||
setlocale(LC_CTYPE, ".utf8");
|
||||
Exiv2::XmpParser::initialize();
|
||||
::atexit(Exiv2::XmpParser::terminate);
|
||||
#ifdef EXV_ENABLE_BMFF
|
||||
Exiv2::enableBMFF();
|
||||
#endif
|
||||
|
||||
const _tchar* prog = argv[0];
|
||||
const char* prog = argv[0];
|
||||
if (argc == 1) {
|
||||
std::_tcout << _t("Usage: ") << prog << _t(" [ [--lint] path | --version | --version-test ]") << std::endl;
|
||||
std::cout << "Usage: " << prog << " [ [--lint] path | --version | --version-test ]" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rc = 0 ;
|
||||
const _tchar* file = argv[1];
|
||||
bool bLint = _tstrcmp(file,_t("--lint")) == 0 && argc == 3;
|
||||
const char* file = argv[1];
|
||||
bool bLint = strcmp(file, "--lint") == 0 && argc == 3;
|
||||
if ( bLint ) file= argv[2];
|
||||
|
||||
|
||||
if ( _tstrcmp(file,_t("--version")) == 0 ) {
|
||||
if ( strcmp(file,"--version") == 0 ) {
|
||||
std::vector<std::regex> keys;
|
||||
Exiv2::dumpLibraryInfo(std::cout,keys);
|
||||
return rc;
|
||||
} else if ( _tstrcmp(file,_t("--version-test")) == 0 ) {
|
||||
} else if ( strcmp(file,"--version-test") == 0 ) {
|
||||
// verifies/test macro EXIV2_TEST_VERSION
|
||||
// described in include/exiv2/version.hpp
|
||||
std::cout << "EXV_PACKAGE_VERSION " << EXV_PACKAGE_VERSION << std::endl
|
||||
|
||||
@ -287,6 +287,23 @@ if(EXIV2_BUILD_EXIV2_COMMAND)
|
||||
target_include_directories(exiv2 PRIVATE ${Intl_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if(MSVC OR MINGW)
|
||||
# Trick to get properly UTF-8 encoded argv
|
||||
# More info at: https://github.com/huangqinjin/wmain
|
||||
add_library(wmain STATIC wmain.c)
|
||||
target_link_libraries(exiv2 PRIVATE wmain)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
target_link_options(wmain INTERFACE /WHOLEARCHIVE:$<TARGET_FILE:wmain>)
|
||||
target_link_options(exiv2 PRIVATE "/ENTRY:wWinMainCRTStartup")
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
target_compile_options(exiv2 PRIVATE -municode)
|
||||
target_link_options(exiv2 PRIVATE -municode)
|
||||
endif()
|
||||
|
||||
if (USING_CONAN AND WIN32 AND EXISTS ${PROJECT_BINARY_DIR}/conanDlls)
|
||||
# In case of using conan recipes with their 'shared' option turned on, we will have dlls of
|
||||
# the 3rd party dependencies in the conanDlls folder.
|
||||
|
||||
@ -120,6 +120,8 @@ namespace {
|
||||
// Main
|
||||
int main(int argc, char* const argv[])
|
||||
{
|
||||
setlocale(LC_CTYPE, ".utf8");
|
||||
|
||||
Exiv2::XmpParser::initialize();
|
||||
::atexit(Exiv2::XmpParser::terminate);
|
||||
#ifdef EXV_ENABLE_BMFF
|
||||
|
||||
@ -332,7 +332,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const std::vector<std::regex>& keys
|
||||
int have_strings =0;
|
||||
int have_sys_types =0;
|
||||
int have_unistd =0;
|
||||
int have_unicode_path=0;
|
||||
|
||||
int enable_bmff =0;
|
||||
int enable_webready =0;
|
||||
@ -512,7 +511,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const std::vector<std::regex>& keys
|
||||
output(os,keys,"have_strings" ,have_strings );
|
||||
output(os,keys,"have_sys_types" ,have_sys_types );
|
||||
output(os,keys,"have_unistd" ,have_unistd );
|
||||
output(os,keys,"have_unicode_path" ,have_unicode_path);
|
||||
output(os,keys,"enable_bmff" ,enable_bmff );
|
||||
output(os,keys,"enable_webready" ,enable_webready );
|
||||
output(os,keys,"enable_nls" ,enable_nls );
|
||||
|
||||
40
src/wmain.c
Normal file
40
src/wmain.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include <windows.h>
|
||||
|
||||
extern int __cdecl main();
|
||||
|
||||
int wmain(int argc, wchar_t* argv[])
|
||||
{
|
||||
char** args;
|
||||
int nbytes = sizeof(char*) * (argc + 1);
|
||||
HANDLE heap = GetProcessHeap();
|
||||
|
||||
for (int i = 0; i < argc; ++i)
|
||||
nbytes += WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL);
|
||||
|
||||
args = HeapAlloc(heap, 0, nbytes);
|
||||
args[0] = (char*)(args + argc + 1);
|
||||
|
||||
for (int i = 0; i < argc; ++i)
|
||||
args[i+1] = args[i] + WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, args[i], nbytes, NULL, NULL);
|
||||
|
||||
args[argc] = NULL;
|
||||
|
||||
argc = main(argc, args);
|
||||
HeapFree(heap, 0, args);
|
||||
return argc;
|
||||
}
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
(void) hInstance;
|
||||
(void) hPrevInstance;
|
||||
(void) lpCmdLine;
|
||||
(void) nCmdShow;
|
||||
|
||||
int argc;
|
||||
wchar_t** argv;
|
||||
argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
argc = wmain(argc, argv);
|
||||
LocalFree(argv);
|
||||
return argc;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user