godotengine / godot-cpp

C++ bindings for the Godot script API
MIT License
1.66k stars 502 forks source link

Compiling GDExtension on Mac M1 gives me an error related to ctime #1521

Open aljoscharei opened 1 month ago

aljoscharei commented 1 month ago

Godot version

v4.3.beta3.official [82cedc83c]

godot-cpp version

master, 4.3 as of https://github.com/godotengine/godot-cpp/pull/1513

System information

macOS Ventura 13.1 (22C65)

Issue description

I try to compile a GDextension written in c++ (code found here). The code requires FFmpeg found here and the C++ bindings for Godot v4.3 found here. FFmpeg and the Godot C++ binding compile without issue individually. However, if I try to compile the entire GDExtension I get an error. I have a Mac m1 running macOs ventura 13.1.

I tried different two version of the c/c++ standard library (xcode command-line tools 13.1 and 13.3) and tried changing the compiler from clang to gcc/g++. In all cases I get the similar errors. This is the ouput for clang -cc1 version 14.0.3 (clang-1403.0.22.14.1) default target arm64-apple-darwin22.2.0

These are the last line of the error log

In file included from godot-cpp/src/classes/wrapped.cpp:39:
In file included from godot-cpp/include/godot_cpp/core/class_db.hpp:38:
In file included from godot-cpp/include/godot_cpp/core/method_bind.hpp:46:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/iostream:38:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/istream:163:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/ostream:140:
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/locale:2383:24: error: member access into incomplete type 'tm'
        __get_year(__tm->tm_year, __b, __e, __err, __ct);
                       ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/wchar.h:131:19: note: forward declaration of 'tm'
            const struct tm * __restrict) __DARWIN_ALIAS(wcsftime);
                         ^
In file included from godot-cpp/src/classes/wrapped.cpp:39:
In file included from godot-cpp/include/godot_cpp/core/class_db.hpp:38:
In file included from godot-cpp/include/godot_cpp/core/method_bind.hpp:46:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/iostream:38:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/istream:163:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/ostream:140:
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/locale:2386:25: error: member access into incomplete type 'tm'
        __get_year4(__tm->tm_year, __b, __e, __err, __ct);
                        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/wchar.h:131:19: note: forward declaration of 'tm'
            const struct tm * __restrict) __DARWIN_ALIAS(wcsftime);
                         ^
scons: *** [godot-cpp/src/core/method_bind.macos.template_debug.universal.o] Error 1
52 errors generated.
scons: *** [godot-cpp/src/godot.macos.template_debug.universal.o] Error 1
52 errors generated.
52 errors generated.
scons: *** [godot-cpp/src/core/object.macos.template_debug.universal.o] Error 1
scons: *** [godot-cpp/src/classes/low_level.macos.template_debug.universal.o] Error 1
24 errors generated.
scons: *** [godot-cpp/src/classes/wrapped.macos.template_debug.universal.o] Error 1
52 errors generated.
scons: *** [godot-cpp/src/core/class_db.macos.template_debug.universal.o] Error 1
scons: building terminated because of errors.

Steps to reproduce

My SConstruct file with irrelevant parts deleted looks like this:

#!/usr/bin/env python
import os
import platform as os_platform

libname = 'gozen'
projectdir = 'test_room'

num_jobs = ARGUMENTS.get('jobs', 4)
platform = ARGUMENTS.get('platform', 'macos')

# The base directory for all relative paths
#base_dir = os.path.dirname(os.path.abspath(__file__))

env = SConscript('godot-cpp/SConstruct')
env.Append(CPPPATH=['src'])

env.Append(LIBS=['avcodec', 'avformat', 'avfilter', 'avdevice', 'avutil', 'swscale', 'swresample'])

# Disable the compiler error limit
if platform == 'macos':
    env.Append(CCFLAGS=['-ferror-limit=0', '-v'])

env.Append(CPPFLAGS=['-DDEBUG'])

if platform == 'macos':
    # macOS (including M1)
    arch = 'arm64' if os_platform.machine() == 'arm64' else 'x86_64'

    env.Append(CPPFLAGS=[
        '-IFFmpeg/include',
        '-IFFmpeg/libavcodec',
        '-IFFmpeg/libavformat',
        '-IFFmpeg/libavfilter',
        '-IFFmpeg/libavdevice',
        '-IFFmpeg/libavutil',
        '-IFFmpeg/libswscale',
        '-IFFmpeg/libswresample'
    ])

    env.Append(LIBS=['avcodec', 'avformat', 'avfilter', 'avdevice', 'avutil', 'swscale', 'swresample'])
    # env.Append(LINKFLAGS=['-L/usr/local/lib'])

    os.chdir('FFmpeg')
    os.system(f'./configure --prefix=ffmpeg_bin --enable-gpl --enable-shared --arch={arch} --target-os=darwin --cc=/usr/bin/clang --enable-version3 --pkg-config-flags=--static')
    os.system('make distclean')
    #os.system(f'./configure --enable-gpl --enable-shared --arch={arch} --target-os=darwin')
    os.system(f'./configure --prefix=ffmpeg_bin --enable-gpl --enable-shared --arch={arch} --target-os=darwin --cc=/usr/bin/clang --enable-version3 --pkg-config-flags=--static')

    os.system(f'make -j {num_jobs}')
    #os.system(f'make -j {num_jobs} install')

    os.chdir('..')

#env.Append(LIBPATH=['/usr/local/lib', '/opt/local/lib'])

src = Glob('src/*.cpp')
libpath = 'bin/{}/lib{}{}{}'.format(platform, libname, env['suffix'], env['SHLIBSUFFIX'])
sharedlib = env.SharedLibrary(libpath, src)
Default(sharedlib)

Minimal reproduction project

I use https://github.com/VoylinsGamedevJourney/GoZen_GDExtension/tree/master.

GoZen_GDExtension-master-modified_SConstruct.zip

However is use current versions of godot_cpp and FFmpeg. Using the godot_cpp 4.2.2gives me an error related to iOS when I try to compile godot_cpp as described here

Faless commented 1 month ago

Judging by the error:

 error: member access into incomplete type 'tm'
        __get_year(__tm->tm_year, __b, __e, __err, __ct);

and the inclusion stack, it seems that <iostream> includes <locale> which depends on <ctime> but does not include it.

This almost feels like a toolchain issue, which version of XCode are you using? I wonder if Xcode 15.4 fixes it....

You can try this change and see if it compiles:

diff --git a/include/godot_cpp/core/method_bind.hpp b/include/godot_cpp/core/method_bind.hpp
index eabd6ece..f9df7b6c 100644
--- a/include/godot_cpp/core/method_bind.hpp
+++ b/include/godot_cpp/core/method_bind.hpp
@@ -43,6 +43,7 @@
 #include <string>
 #include <vector>

+#include <ctime>
 #include <iostream>

 namespace godot {
aljoscharei commented 1 month ago

Thank you so much. Unfortunately after installing XCode 15.4 and applying the patch, no luck