Skip to content

Project build system errors. Problems, notes, requests. #1736

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

Open
f9x0 opened this issue Mar 8, 2025 · 22 comments
Open

Project build system errors. Problems, notes, requests. #1736

f9x0 opened this issue Mar 8, 2025 · 22 comments

Comments

@f9x0
Copy link

f9x0 commented Mar 8, 2025

Godot version

godot 4.4

godot-cpp version

godot-cpp 4.4

System information

windows 10 x64

Issue description

Hello. I'll note right away that I'm not a professional C++ developer. I have to use C++, I don't have enough performance of GDscript\C#(Godot).
My toolchain: clang + cmake + ninja and clang + scons.
I'll probably test MSVC\MinGW in the future.

Result godot-cpp 4.4:
scons -j4 platform=windows

register_types.windows.template_debug.x86_64.obj : error LNK2019: unresolved external symbol "protected: static void __cdecl godot::MyNode2D::_bind_methods(void)" (?_bind_methods@MyNode2D@godot@@KAXXZ) referenced in function "private: static void __cdecl godot::ClassDB::_register_class<class godot::MyNode2D,0>(bool,bool,bool)" (??$_register_class@VMyNode2D@godot@@$0A@@ClassDB@godot@@CAX_N00@Z)
register_types.windows.template_debug.x86_64.obj : error LNK2019: unresolved external symbol "public: __cdecl godot::MyNode2D::MyNode2D(void)" (??0MyNode2D@godot@@qeaa@XZ) referenced in function "private: static void * __cdecl godot::ClassDB::_create_instance_func(void *,unsigned char)" (??$_create_instance_func@VMyNode2D@godot@@@ClassDB@godot@@CAPEAXPEAXE@Z)
demo\bin\libgdexample.windows.template_debug.x86_64.dll : fatal error LNK1120: 2 unresolved externals

I encountered this error in cmake . Version godot-cpp 4.3
Solution.

target_compile_definitions(${PROJECT_NAME} PUBLIC
$<$CONFIG:Debug:
DEBUG_ENABLED
DEBUG_METHODS_ENABLED
>
TYPED_METHOD_BIND
)

I don't know how to fix this in godot-cpp 4.4 scons.

Why did I decide to try scons?
I was very tired of cmake breaking and thought it would be better.
Previously, I chose cmake because.
For me, scons took 20-30% longer to build.
4-5 sec vs 7-9 sec. Rebuild.
Now scons didn't build at all.
When I tried to google additional flags.
Scons decided to rebuild everything and I left it. I was tired like a blind kitten picking up library build flags.

Cmake. I compiled it in two ways. A separate library + my cmake for the project.
And including godot-cpp as an additional dependency.
I got different errors. Runtime conflicts. Incorrect std++ library, its name is broken.

windows.cmake
option( GODOTCPP_DEBUG_CRT "Compile with MSVC's debug CRT (/MDd)" OFF )
Is this really necessary? I built it in debug mode.
Which conflicted with the main runtime. A strange default setting or my stupidity.

Cmake cache clearly showed that the hot reload option was not set.
Had to set it manually.
Additionally.
set_target_properties(
${PROJECT_NAME}
PROPERTIES
COMPILE_DEFINITIONS HOT_RELOAD_ENABLED
)

My lines in cmake. So that this function would work as a separate cmake project.
Previously, I spent hours to understand how to run this. By github + commit + changes.
I want to see such things in a normal wiki!

godot-cpp 4.4 --target godot-cpp.template_debug
lld-link: error: /failifmismatch: mismatch detected for '_ITERATOR_DEBUG_LEVEL':

CMakeFiles/re.dir/src/register_types.cpp.obj has value 2
libgodot-cpp.windows.template_debug.x86_64.lib(array.cpp.obj) has value 0

Other minor inconsistencies. Which are poorly documented.
In godot-cpp 4.3 I had 2 failures.
HOT_RELOAD_ENABLED
TYPED_METHOD_BIND
And only when I created the library and used it manually.

godot-cpp 4.4 did not build anything.
I spent many hours and the best I got.
cmake -GNinja -Bbuild/debug -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug -DGODOTCPP_USE_HOT_RELOAD=ON -DGODOTCPP_DEBUG_CRT=ON

lld-link: warning: section name .debug_abbrev is longer than 8 characters and will use a non-standard string table
lld-link: warning: section name .debug_info is longer than 8 characters and will use a non-standard string table
lld-link: warning: section name .debug_line is longer than 8 characters and will use a non-standard string table
lld-link: warning: section name .debug_ranges is longer than 8 characters and will use a non-standard string table
lld-link: warning: section name .debug_str is longer than 8 characters and will use a non-standard string table

Sorry for the long message. I'm trying to convey that it might be hard for a newbie. Getting started quickly is important!
The second issue that has already been raised.
Building godot-cpp separately. I dream of building godot-cpp with 1 command and connecting it to my cmake with one line.
Like in SDL3\EnTT\flecs\SFML\DXTK\Love2D ect. I can just do it, I don't need additional knowledge inside their cmake. Rarely do I need to configure flags that the docs have.
Why is this important to me? I develop games. I have many projects. I figure out the details of C++ Godot or test ideas. Sometimes I connect other languages. When I am asked to build godot-cpp every time, I feel sad. 20-30 minutes (on average and depends on CPU load).
I also need a release version to check performance. Why? I am ready to guarantee the same env toolchain. For one version, for example, godot 4.4.
Probably it is even possible to create it at the level of github actions.
Why can rust-godot provide ready-made artifacts, but godot-cpp not? Or a normal way of organizing this function. Development is one thing, in the release I can assemble everything as it should be.
Documentation is really lacking.
I also don't know. Can I somehow get documentation for all godot-cpp? It would also be better to integrate this into clangd.
A little off topic. Maybe cmake should not try to make it closer to scons?
Maybe make different build options? scons. cmake all in one. cmake light version, assemble and get artifacts. I understand this is a lot of work. I am not qualified to help here, perhaps documentation of your difficulties.
But it seems to me that this is a basic need. To start quickly.
I spend more time on assembling and organizing the project than writing the functionality. And I want to spend less time on creating when, that's why I want Ninja + Cmake + other tool.

Steps to reproduce

build project scons windows clang + bind method.

Minimal reproduction project

"N/A"

@enetheru
Copy link
Collaborator

enetheru commented Mar 9, 2025

I'll comment on the cmake stuff since thats my forte

I was very tired of cmake breaking

Yeah so was I. 4.3 and below barely had a solution, so I've completely overhauled it for 4.4, they are worlds apart. I'm hoping that after some time with 4.4 I can backport, but we have to see how 4.4 goes for now and its still in progress and going through enough change that it'll take some attention to keep up. Not much more to go though so fingers crossed in the next week or so it will settle.

Whenever I look at 4.3 and below its just baffling, the CMakeLists.txt makes zero sense. Multiple side projects of people have completely re-written to work around its failings, like the RogueLite repo.

For 4.4 you just need to look at the options cmake -S <source_dir> -LH and it will show you what variables are available.

option( GODOTCPP_DEBUG_CRT "Compile with MSVC's debug CRT (/MDd)" OFF )
Is not necessary in most cases, in 4.4 if you include godot-cpp before other dependencies we set it to what godot-cpp requires, but unless you need symbols relating to windows you can ignore it.

I've tried to add lots of comments to the cmake files in the godot-cpp source.

godot-cpp 4.4 did not build anything.

Yeah sorry, I'm going to change that as its confusing people, hence why I said it will settle in a week or so. you need to specify a target atm, try this:
cmake -S <source dir> -B <build_dir> <options>
cmake --build <build_dir> --target godot-cpp.template_debug

Why can rust-godot provide ready-made artifacts, but godot-cpp not?

have a look at https://github.com/godotengine/godot-cpp-template

Documentation is really lacking.

We're aware, and working on it, could always use some more help ;)

Maybe cmake should not try to make it closer to scons?

Sorry this is a hard requirement, and I'm almost there.

Maybe make different build options? scons. cmake all in one. cmake light version, assemble and get artifacts.

Have a look at build profiles for a lighter version tailored to your needs.

I am not qualified to help here, perhaps documentation of your difficulties.

Only way to truly know that is to try.

I spend more time on assembling and organizing the project than writing the functionality. And I want to spend less time on creating when, that's why I want Ninja + Cmake + other tool.

Six months ago I had the same problem, so I put in the time to earn trust and provide changes such that I can hopefully help others avoid it. And it wasn't straight forward or easy, but the things i have learned were worth the time spent. At some point I will get back to my personal project and the CMake things will slow down, hopefully soon.

@f9x0
Copy link
Author

f9x0 commented Mar 9, 2025

Thanks for your answers!
I don't know if this will help or not.
When I use FetchContent and don't specify CMAKE_MSVC_RUNTIME_LIBRARY
CMAKE_MSVC_RUNTIME_LIBRARY:STRING=MultiThreaded$<IF:$BOOL:OFF,DebugDLL,$<$<NOT:$BOOL:ON>:DLL>>
There may be other errors.
It would be very nice to add to readme.
How to minimally build godot-cpp + cmake.
Maybe I have a lot of problems because of cmake + ninja.
Maybe I just configured something wrong.

@enetheru
Copy link
Collaborator

enetheru commented Mar 9, 2025

It just needs to be the same value for all targets that are linked together. And since godot-cpp sets it as a cache value, either Godot-cpp needs to be the first target specified, or you need to set the value in the cache before any targets are defined.

@enetheru
Copy link
Collaborator

enetheru commented Mar 9, 2025

It would be very nice to add to readme.

I've been holding off on adding anything to readme until things are basically done and arent going to change, you can read what it might look like in the docs/cmake.rst

I have examples in there. I've tested with Ninja, Ninja-Multi Visual Studio, XCode MinGWMakefiles

@enetheru
Copy link
Collaborator

#1733 has been merged which reverts to a single godot-cpp target with template_debug as default that builds out of the gate which satisfies the getting started quickly, and reduces the need to look into the build system.

Can you report back if you find it simpler to deal with?

@f9x0
Copy link
Author

f9x0 commented Mar 19, 2025

#1733 has been merged which reverts to a single godot-cpp target with template_debug as default that builds out of the gate which satisfies the getting started quickly, and reduces the need to look into the build system.

Can you report back if you find it simpler to deal with?

My cmake:

cmake_minimum_required(VERSION 3.19)
project(re)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)

FetchContent_Declare(
    GDExtension
    GIT_REPOSITORY https://github.com/godotengine/godot-cpp.git
    GIT_TAG 4.4
)

FetchContent_MakeAvailable(GDExtension)

file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
    "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
)

add_library(${PROJECT_NAME} SHARED ${SOURCES})

target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src")
target_link_libraries(${PROJECT_NAME} PRIVATE godot::cpp)

# without build
target_compile_definitions(${PROJECT_NAME} PUBLIC
    $<$<CONFIG:Debug>:
        DEBUG_ENABLED
        DEBUG_METHODS_ENABLED
    >       
    TYPED_METHOD_BIND
)

output:
C:\Windows\system32\cmd.exe /C "cd . && C:\dev_tool\LLVM\bin\clang++.exe -nostartfiles -nostdlib -O0 -g -Xclang -gcodeview -Xclang -flto-visibility-public-std -D_MT -Xclang --dependent-lib=libcmt -Wl,--no-undefined -static -static-libgcc -static-libstdc++ -lstdc++ -fuse-ld=lld-link -shared -o re.dll -Xlinker /MANIFEST:EMBED -Xlinker /implib:re.lib -Xlinker /pdb:re.pdb -Xlinker /version:0.0 CMakeFiles/re.dir/src/enemy_skeleton.cpp.obj CMakeFiles/re.dir/src/enemy_undead.cpp.obj CMakeFiles/re.dir/src/my_node2d/my_node2d.cpp.obj CMakeFiles/re.dir/src/register_types.cpp.obj bin/libgodot-cpp.windows.template_debug.x86_64.lib -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames && cd ."
clang++: warning: argument unused during compilation: '-static-libgcc' [-Wunused-command-line-argument]
clang++: warning: argument unused during compilation: '-static-libstdc++' [-Wunused-command-line-argument]
lld-link: warning: ignoring unknown argument '--no-undefined'
lld-link: error: could not open 'stdc++.lib': no such file or directory
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

Maybe problem "-nostartfiles -nostdlib"
Maybe the problem is in my cmake?
commands:
cmake -GNinja -Bbuild\debug
cmake --build build\debug

Standalone build of godot-cpp goes fine.
Building godot-cpp library and embedding it into my cmake.
Worked well, there are 2 nuances.
I added this to my cmake.
set (CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<IF:$BOOL:OFF,DebugDLL,$<$<NOT:$BOOL:ON>:DLL>>")
To have the same runtimes.

And I still have warnings.
lld-link: warning: section name .debug_abbrev is longer than 8 characters and will use a non-standard string table
lld-link: warning: section name .debug_info is longer than 8 characters and will use a non-standard string table
lld-link: warning: section name .debug_line is longer than 8 characters and will use a non-standard string table
lld-link: warning: section name .debug_ranges is longer than 8 characters and will use a non-standard string table
lld-link: warning: section name .debug_str is longer than 8 characters and will use a non-standard string table

@enetheru
Copy link
Collaborator

hmm, appears to be mixing clang and msvc flags, what compiler combination are you using? i'm going to assume msvc with clang? how do you have it setup?

This is mixing up concepts, debug_template isnt related to debug with symbols. if GODOTCPP_TARGET isnt specified this will already build the template_debug build enabling these flags, and TYPED_METHOD_BIND is only enabled for MSVC by default and not clang. I'm assuming you have some special need for it?

target_compile_definitions(${PROJECT_NAME} PUBLIC
    $<$<CONFIG:Debug>:
        DEBUG_ENABLED
        DEBUG_METHODS_ENABLED
    >       
    TYPED_METHOD_BIND
)

@enetheru
Copy link
Collaborator

make sure this is before adding godot-cpp
set (CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<IF:$BOOL:OFF,DebugDLL,$<$<NOT:$BOOL:ON>:DLL>>")

CMake copies CMAKE_MSVC_RUNTIME_LIBRARY to targets as they are defined, so if its after then it will not guarantee they are the same. As a compromise with how the scons thing was setup we set that variable as a cache one so it can be overridden by users and add a warning to the output.

There are also a bunch of things at the top of the godot-cpp/cmake/windows.cmake that explain whats going on there.

@enetheru
Copy link
Collaborator

I see C:\dev_tool\LLVM\bin\clang++.exe is that clang downloaded from their website? if so it defaults to visual studio compatible interface so flags end up being in the forward slash form. We try to detect, and adjust flags to match, but i'm not sure i did the best job for all circumstances.

Also cmake downloaded for windows defaults to visual studio build files. how did you install both cmake and clang?

@f9x0
Copy link
Author

f9x0 commented Mar 19, 2025

hmm, appears to be mixing clang and msvc flags, what compiler combination are you using? i'm going to assume msvc with clang? how do you have it setup?

This is mixing up concepts, debug_template isnt related to debug with symbols. if GODOTCPP_TARGET isnt specified this will already build the template_debug build enabling these flags, and TYPED_METHOD_BIND is only enabled for MSVC by default and not clang. I'm assuming you have some special need for it?

target_compile_definitions(${PROJECT_NAME} PUBLIC
$<$CONFIG:Debug:
DEBUG_ENABLED
DEBUG_METHODS_ENABLED
>
TYPED_METHOD_BIND
)

#1250
I looked it up here.
Without it, my method binds don't work.

Yes, I use clang from their official site.
Cmake is also from the official site.
Probably clang itself finds the msvc toolchain and works with it. I don't know how it works under the hood. I don't have mingw installed.
I don't use env msvc. Godot-cpp 4.3 worked, except for TYPED_METHOD_BIND.

The usual build builds and works.
Maybe I'll install mingw and try to build with it.

@enetheru
Copy link
Collaborator

ahh so you dont have msvc installed right?

@f9x0
Copy link
Author

f9x0 commented Mar 19, 2025

ahh so you dont have msvc installed right?

installed.
I checked msvc and mingw.
They work fine, but not clang.

@f9x0
Copy link
Author

f9x0 commented Mar 21, 2025

I have studied my problem and found a solution.
clang (GNU-like) does not work correctly in windows.
clang-cl (MSVC-like) works correctly.
Maybe it is worth noting this in the CMake docs?
It is a bit strange that mingw works correctly, but clang GNU does not.
As far as I understand, there are some discrepancies and subtleties of different levels in these versions. But now godot-cpp works and I am happy about it.
The last thing that worries me is whether it is possible to create documentation for all C++ godot-cpp classes. To implement in clangd.
And I think this topic can be closed.

@enetheru
Copy link
Collaborator

clang (GNU-like) does not work correctly in windows.

I also had problems with that specific combination, because clang can emulate either gnu or msvc frontend, for both the compiler and the linker interfaces independently it makes for really weird scenarios that I would have to put enormous effort into resolving the differences.

Look up the llvm-mingw project I've had good experiences with it.
I also use the Msys2 clang64 with minimal issues( SCons doesnt play as nice )

@enetheru
Copy link
Collaborator

The last thing that worries me is whether it is possible to create documentation for all C++ godot-cpp classes. To implement in clangd.

What does this mean in more detail please?

@f9x0
Copy link
Author

f9x0 commented Mar 21, 2025

Последнее, что меня беспокоит, это возможно ли создать документацию для всех классов C++ godot-cpp. Реализовать в clangd.

Что это значит, расскажите подробнее, пожалуйста?

godot-cpp generates classes without documentation. That's why my LSP only returns function signatures. Is it possible to generate classes with documentation?

@enetheru
Copy link
Collaborator

godot-cpp generates classes without documentation. That's why my LSP only returns function signatures. Is it possible to generate classes with documentation?

I know you can dump the extension api from godot.exe , and there is an option --dump-extension-api-with-docs I dont know if that then passed to the generator does what you want..

@f9x0
Copy link
Author

f9x0 commented Mar 22, 2025

I found another problem.
If you take godot-cpp 4.4(6388e26
), build a project with it. When closing the release build of godot 4.4 and newer (game). Will be:

[new session]
Invalid parameter passed to C runtime function.
clientcore\windows\dwm\dwmapi\attribute.cpp(185)\dwmapi.dll!00007FFE645F3647: (caller: 00007FF62A695139) ReturnHr(1) tid(15f8) 80070057 The parameter is incorrect.
clientcore\windows\dwm\dwmapi\attribute.cpp(185)\dwmapi.dll!00007FFE645F3647: (caller: 00007FF62A686805) ReturnHr(2) tid(15f8) 80070057 The parameter is incorrect.
Critical error detected c0000374

I tested msvc \ clang-cl. Cmake \ Ninja. Windows 10.
Scons everything works as it should!
My code:

#include "test_class.hpp"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/utility_functions.hpp>

using namespace godot;

void TestClass::_bind_methods() {
	// this method error
	ClassDB::bind_method(D_METHOD("test_method_run"),&TestClass::test_method_run);

};

void TestClass::test_method_run(){
	UtilityFunctions::print("Test3");
}

void TestClass::_process(double delta) {
	test_method_run();
}

The problem is method registration. Without this, everything will work without an error.
At first I thought it might be a godot 4.4 problem. Later I compiled godot-cpp 4.3, scons 4.4 and everything works as it should.

@enetheru
Copy link
Collaborator

I think I can reproduce, does it still cause a problem in a Release build? If not it might be related to /RTC being on which might be detecting a stack smashing bug.
I have a PR which turns it off, and I can get a working Debug extension, but I dont know how much of a solution that is
#1751

@enetheru
Copy link
Collaborator

enetheru commented Apr 2, 2025

@f9x0 can you test with latest master and see if this is still the case?

@f9x0
Copy link
Author

f9x0 commented May 2, 2025

@f9x0можете ли вы протестировать последнюю версию мастера и посмотреть, так ли это?
I will test and give you an answer!

@f9x0
Copy link
Author

f9x0 commented May 4, 2025

@f9x0 can you test with latest master and see if this is still the case?

Silent crash start game.
Release Only.

[new session]
Invalid parameter passed to C runtime function.
clientcore\windows\dwm\dwmapi\attribute.cpp(185)\dwmapi.dll!00007FF9640236A7: (caller: 00007FF79ABA5139) ReturnHr(1) tid(1d1c) 80070057 The parameter is incorrect.
clientcore\windows\dwm\dwmapi\attribute.cpp(185)\dwmapi.dll!00007FF9640236A7: (caller: 00007FF79AB96805) ReturnHr(2) tid(1d1c) 80070057 The parameter is incorrect.

When I have time, I'll double check it.
Godot 4.4.1

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

No branches or pull requests

2 participants