Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UE4 Editor Linux with Cross-Compilation #15

Closed
Meradrin opened this issue Oct 25, 2018 · 6 comments
Closed

UE4 Editor Linux with Cross-Compilation #15

Meradrin opened this issue Oct 25, 2018 · 6 comments
Assignees
Labels

Comments

@Meradrin
Copy link

I compile the UE4 Editor Linux v4.20 in Cross-Compilation on Windows with v11_clang-5.0.0-centos7.zip from https://docs.unrealengine.com/en-us/Platforms/Linux/GettingStarted.

Sadly this STL lib look to have a problem with all the definition for 64bit type in printf, like PRId64, PRIu64, PRIX64, etc... So SJSON create a compilation error.

build	17-Oct-2018 12:30:27	  In file included from \main\Engine\Plugins\ACLPlugin\Source\ACLPlugin\Private\ACLStatsDumpCommandlet.cpp:39:
error	17-Oct-2018 12:30:27	  /main/Engine/Plugins/ACLPlugin/ThirdParty/acl/external/sjson-cpp/includes\sjson/writer.h(363,56):  error: expected ')'
build	17-Oct-2018 12:30:27	                  size_t length = snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", value, k_line_terminator);
build	17-Oct-2018 12:30:27	                                                                       ^
build	17-Oct-2018 12:30:27	  /main/Engine/Plugins/ACLPlugin/ThirdParty/acl/external/sjson-cpp/includes\sjson/writer.h(363,27):  note: to match this '('
build	17-Oct-2018 12:30:27	                  size_t length = snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", value, k_line_terminator);

If we look inside cinttypes for find where the inttypes.h is done. We can see the part that is supposed to do the include there...

// For 27.9.2/3 (see C99, Note 184)
#if _GLIBCXX_HAVE_INTTYPES_H
# ifndef __STDC_FORMAT_MACROS
#  define _UNDEF__STDC_FORMAT_MACROS
#  define __STDC_FORMAT_MACROS
# endif
# include <inttypes.h>
# ifdef _UNDEF__STDC_FORMAT_MACROS
#  undef __STDC_FORMAT_MACROS
#  undef _UNDEF__STDC_FORMAT_MACROS
# endif
#endif

_GLIBCXX_HAVE_INTTYPES_H is not defined. The inttypes.h header file exist in C. So in normal time this define defintion of _GLIBCXX_HAVE_INTTYPES_H will be done inside "C++config.h" and that will be add in include before everything by the compiler himself. For whatever reason Unreal don't include this, so result never define _GLIBCXX_HAVE_INTTYPES_H. So the result is cinttypes never include inttypes.h.

For doing a fix what I have done is directly define __STDC_FORMAT_MACROS and call the C version of the header <inttypes.h> and everything work fine.

Like this include/sjson/writer.h

#include <functional>
#include <cstdio>
#include <cstdint>
#include <cstring>

# ifndef __STDC_FORMAT_MACROS
#  define _UNDEF__STDC_FORMAT_MACROS
#  define __STDC_FORMAT_MACROS
# endif
#include <inttypes.h>
# ifdef _UNDEF__STDC_FORMAT_MACROS
#  undef __STDC_FORMAT_MACROS
#  undef _UNDEF__STDC_FORMAT_MACROS
# endif

namespace sjson
{
	// TODO: Cleanup the locking stuff, wrap it in #ifdef to strip when asserts are disabled

Personally I don't like this solution, but that fix the compilation.

I write there for having your opinion about this problem.

Note: I simply add the Issues there, but maybe this issue will be need to be place inside the UE4 ACL plugin or ACL directly. But the compilation error is inside sjson.

@nfrechette
Copy link
Owner

Hmm that is quite the interesting issue. The C99 standard says that __STDC_FORMAT_MACROS must be defined before the header is included in order for the macros to be defined but the C++11 standard removed that restriction and always defines them. It appears that the compiler is not quite C++11 compliant...

I'm not sure if it's possible for you to try and upgrade the compiler, travis does compile ACL and sjson-cpp with clang 5 but with the last stable release, not 5.0.0.

Can you try to add this to the plugin C# file instead of your fix:
PublicDefinitions.Add("__STDC_FORMAT_MACROS");

@nfrechette nfrechette self-assigned this Oct 25, 2018
@nfrechette nfrechette added the bug label Oct 25, 2018
@Meradrin
Copy link
Author

If I add PublicDefinitions.Add("__STDC_FORMAT_MACROS"); and return writer.h to the original state all is working correctly. I am a little bit lost on this one, because that make no sense with what I have read inside the STL include in centos files. So I have simply add this one.

ACLPlugin.Build.cs

            if (Target.Platform == UnrealTargetPlatform.Linux)
            {
                PublicDefinitions.Add("__STDC_FORMAT_MACROS");
            }

I will debug a little bit more for seeing what is going on when the compilation is done.

@Meradrin
Copy link
Author

Oky after debugging directly the LinuxToolChain.cs and trying to understand what is going on.

ParallelExecutor.ExecuteActions:   .. ThirdParty/Linux/LibCxx/include/c++/v1\\cinttypes
ParallelExecutor.ExecuteActions:   ... ThirdParty/Linux/LibCxx/include/c++/v1\\inttypes.h
ParallelExecutor.ExecuteActions:   .... D:\\UE-Toolchain\\v11_clang-5.0.0-centos7\\x86_64-unknown-linux-gnu\\lib\\clang\\5.0.0\\include\\inttypes.h
ParallelExecutor.ExecuteActions:   ..... D:/UE-Toolchain/v11_clang-5.0.0-centos7/x86_64-unknown-linux-gnu/usr/include\\inttypes.h

I see that the version cinttypes inside the v11_clang-5.0.0-centos7 is never call. It use only the old C version in the end and look like the one use by unreal (LibCxx) is not correctly setup for be STL standard correct.

cinttypes you can see that is no __STDC_FORMAT_MACROS defined. Maybe in normal time it is inside the __config file, I don't know.

So yeah I simply do this fix in the end.

            if (Target.Platform == UnrealTargetPlatform.Linux)
            {
                PrivateDefinitions.Add("__STDC_FORMAT_MACROS");
            }

I change PublicDefinitions for PrivateDefinitions no need to spread this define on everywhere __STDC_FORMAT_MACROS, that can maybe in really rare case create conflict with other module. The only place that need to be define it is inside ACLStatsDumpCommandlet.cpp

Thank for the help!

Maybe you can add this inside your official UE4 ACL Plugin.

@nfrechette
Copy link
Owner

Nice find! Thanks a lot for looking into this and reporting the issue. I will indeed add that same code along with a comment that describes why and points to this github issue) in the plugin to make sure others don't run into the problem (or you can submit it in a PR). I'll make sure to make a minor release for this next week since it's fairly important.
In the meantime, I'll close this issue

@nfrechette
Copy link
Owner

@all-contributors add @Meradrin as bug reports

@allcontributors
Copy link
Contributor

@nfrechette

I've put up a pull request to add @Meradrin! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants