Skip to content

Commit

Permalink
Windows: define UNICODE and _UNICODE and link against -municode when …
Browse files Browse the repository at this point in the history
…using g++. Also provide a wmain entry
  • Loading branch information
MrKepzie committed Oct 6, 2016
1 parent 1df9627 commit 0025874
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 40 deletions.
14 changes: 11 additions & 3 deletions App/NatronApp_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@

NATRON_NAMESPACE_USING

int
main(int argc,
char *argv[])
#ifdef Q_OS_WIN
// g++ knows nothing about wmain
// https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/
extern "C" {
int wmain(int argc, wchar_t** argv)
#else
int main(int argc, char *argv[])
#endif
{
#if defined(Q_OS_UNIX) && defined(RLIMIT_NOFILE)
/*
Expand Down Expand Up @@ -103,4 +108,7 @@ main(int argc,
//exec() is called within the GuiApplicationManager
}
} // main
#ifdef Q_OS_WIN
} // extern "C"
#endif

52 changes: 21 additions & 31 deletions Engine/AppManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,37 +384,9 @@ AppManager::releaseNatronGIL()
_imp->natronPythonGIL.unlock();
}


bool
AppManager::load(int &argc,
char *argv[],
const CLArgs& cl)
AppManager::loadFromArgs(const CLArgs& cl)
{
// Ensure the arguments are Utf-8 encoded
std::vector<std::string> utf8Args;
if (argv) {
CLArgs::ensureCommandLineArgsUtf8(argc, argv, &utf8Args);
} else {
// If the user didn't specify launch arguments (e.g unit testing),
// At least append the binary path
QString path = ProcInfo::applicationDirPath(0);
utf8Args.push_back(path.toStdString());
}

// Copy command line args to local members that live throughout the lifetime of AppManager
#ifndef IS_PYTHON_2
_imp->commandLineArgsWide.resize(utf8Args.size());
#endif
_imp->commandLineArgsUtf8.resize(utf8Args.size());
_imp->nArgs = (int)utf8Args.size();
for (std::size_t i = 0; i < utf8Args.size(); ++i) {
_imp->commandLineArgsUtf8[i] = strdup(utf8Args[i].c_str());

// Python 3 needs wchar_t arguments
#ifndef IS_PYTHON_2
_imp->commandLineArgsWide[i] = char2wchar(utf8Args[i].c_str());
#endif
}

// This needs to be done BEFORE creating qApp because
// on Linux, X11 will create a context that would corrupt
Expand Down Expand Up @@ -468,9 +440,27 @@ AppManager::load(int &argc,
assert(qApp);

bool ret = loadInternal(cl);

return ret;
} // AppManager::load
} // loadFromArgs

bool
AppManager::load(int argc,
char **argv,
const CLArgs& cl)
{
_imp->handleCommandLineArgs(argc, argv);
return loadFromArgs(cl);
}

bool
AppManager::load(int argc,
wchar_t **argv,
const CLArgs& cl)
{
_imp->handleCommandLineArgsW(argc, argv);
return loadFromArgs(cl);
}

AppManager::~AppManager()
{
Expand Down
9 changes: 8 additions & 1 deletion Engine/AppManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,14 @@ GCC_DIAG_SUGGEST_OVERRIDE_ON
* @param cl The parsed arguments passed to the command line
* main process.
**/
bool load( int &argc, char **argv, const CLArgs& cl);
bool load( int argc, char **argv, const CLArgs& cl);
bool load( int argc, wchar_t **argv, const CLArgs& cl);

private:

bool loadFromArgs(const CLArgs& cl);

public:

virtual ~AppManager();

Expand Down
57 changes: 57 additions & 0 deletions Engine/AppManagerPrivate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ GCC_DIAG_ON(unused-parameter)
#include "Global/QtCompat.h" // for removeRecursively
#include "Global/GlobalDefines.h"
#include "Global/GLIncludes.h"
#include "Global/ProcInfo.h"

#include "Engine/FStreamsSupport.h"
#include "Engine/CacheSerialization.h"
#include "Engine/CLArgs.h"
#include "Engine/ExistenceCheckThread.h"
#include "Engine/Format.h"
#include "Engine/FrameEntry.h"
Expand Down Expand Up @@ -858,4 +860,59 @@ AppManagerPrivate::tearDownGL()
#endif
}

void
AppManagerPrivate::copyUtf8ArgsToMembers(const std::vector<std::string>& utf8Args)
{
// Copy command line args to local members that live throughout the lifetime of AppManager
#ifndef IS_PYTHON_2
commandLineArgsWide.resize(utf8Args.size());
#endif
commandLineArgsUtf8.resize(utf8Args.size());
nArgs = (int)utf8Args.size();
for (std::size_t i = 0; i < utf8Args.size(); ++i) {
commandLineArgsUtf8[i] = strdup(utf8Args[i].c_str());

// Python 3 needs wchar_t arguments
#ifndef IS_PYTHON_2
commandLineArgsWide[i] = char2wchar(utf8Args[i].c_str());
#endif
}
}

void
AppManagerPrivate::handleCommandLineArgs(int argc, char** argv)
{
// Ensure the arguments are Utf-8 encoded
std::vector<std::string> utf8Args;
if (argv) {
CLArgs::ensureCommandLineArgsUtf8(argc, argv, &utf8Args);
} else {
// If the user didn't specify launch arguments (e.g unit testing),
// At least append the binary path
QString path = ProcInfo::applicationDirPath(0);
utf8Args.push_back(path.toStdString());
}

copyUtf8ArgsToMembers(utf8Args);
}

void
AppManagerPrivate::handleCommandLineArgsW(int argc, wchar_t** argv)
{
std::vector<std::string> utf8Args;
if (argv) {
for (int i = 0; i < argc; ++i) {
std::wstring ws(argv[i]);
utf8Args.push_back(Global::utf16_to_utf8(ws));
}
} else {
// If the user didn't specify launch arguments (e.g unit testing),
// At least append the binary path
QString path = ProcInfo::applicationDirPath(0);
utf8Args.push_back(path.toStdString());
}

copyUtf8ArgsToMembers(utf8Args);
}

NATRON_NAMESPACE_EXIT;
5 changes: 5 additions & 0 deletions Engine/AppManagerPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,11 @@ struct AppManagerPrivate
void tearDownGL();

void setViewerCacheTileSize();

void handleCommandLineArgs(int argc, char** argv);
void handleCommandLineArgsW(int argc, wchar_t** argv);

void copyUtf8ArgsToMembers(const std::vector<std::string>& utf8Args);
};

NATRON_NAMESPACE_EXIT;
Expand Down
28 changes: 28 additions & 0 deletions Engine/CLArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,34 @@ CLArgs::CLArgs(int& argc,
_imp->parse();
}

CLArgs::CLArgs(int& argc,
wchar_t* argv[],
bool forceBackground)
: _imp( new CLArgsPrivate() )
{
_imp->isEmpty = false;
if (forceBackground) {
_imp->isBackground = true;
}

std::vector<std::string> utf8Args;
for (int i = 0; i < argc; ++i) {
std::wstring ws(argv[i]);
QString str = QString::fromStdWString(ws);
if ( (str.size() >= 2) && ( str[0] == QChar::fromLatin1('"') ) && ( str[str.size() - 1] == QChar::fromLatin1('"') ) ) {
str.remove(0, 1);
str.remove(str.size() - 1, 1);
}
#ifdef DEBUG
std::cout << "argv[" << i << "] = " << str.toStdString() << std::endl;
#endif
_imp->args.push_back(str);

}
_imp->parse();

}

CLArgs:: CLArgs(const QStringList &arguments,
bool forceBackground)
: _imp( new CLArgsPrivate() )
Expand Down
4 changes: 4 additions & 0 deletions Engine/CLArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ class CLArgs //: boost::noncopyable // GCC 4.2 requires the copy constructor
char* argv[],
bool forceBackground);

CLArgs(int& argc,
wchar_t* argv[],
bool forceBackground);

CLArgs(const QStringList& arguments,
bool forceBackground);

Expand Down
16 changes: 12 additions & 4 deletions Renderer/NatronRenderer_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,15 @@

NATRON_NAMESPACE_USING

int
main(int argc,
char *argv[])

#ifdef Q_OS_WIN
// g++ knows nothing about wmain
// https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/
extern "C" {
int wmain(int argc, wchar_t** argv)
#else
int main(int argc, char *argv[])
#endif
{
#if defined(Q_OS_UNIX) && defined(RLIMIT_NOFILE)
/*
Expand Down Expand Up @@ -92,4 +98,6 @@ main(int argc,

return 0;
} //main

#ifdef Q_OS_WIN
} // extern "C"
#endif
10 changes: 9 additions & 1 deletion global.pri
Original file line number Diff line number Diff line change
Expand Up @@ -232,19 +232,27 @@ win32 {
#microsoft compiler needs _MBCS to compile with the multi-byte character set.
#DEFINES += _MBCS
DEFINES += WINDOWS COMPILED_FROM_DSP XML_STATIC NOMINMAX
DEFINES -= _UNICODE UNICODE
DEFINES += _UNICODE UNICODE

DEFINES += QHTTP_SERVER_STATIC

#System library is required on windows to map network share names from drive letters
LIBS += -lmpr



# Natron requires a link to opengl32.dll and Gdi32 for offscreen rendering
LIBS += -lopengl32 -lGdi32


}

win32-g++ {
# -municode is needed for linking because it uses wmain() instead of the traditional main()
# https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/
LIBS += -municode
}

win32-msvc* {
CONFIG(64bit){
message("Compiling for architecture x86 64 bits")
Expand Down

0 comments on commit 0025874

Please sign in to comment.