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

feat: switch to xmake #377

Merged
merged 1 commit into from
Apr 6, 2024
Merged

feat: switch to xmake #377

merged 1 commit into from
Apr 6, 2024

Conversation

localcc
Copy link
Contributor

@localcc localcc commented Feb 10, 2024

Xmake is a nicer build system, which doesn't require as much effort to
add new build configurations in that work with every generator. Xmake
also allows to interface with CMake projects which allows us to easily
use existing CMake external dependencies.

All internal dependencies were converted to use xmake.

Xmake also has a nice package manager which doesn't require any
configuration on the user's side, allowing us to use packages from that
if needed.

Setting up

Checkout the xmake branch for the unreal submodule

The project should now be compilable with xmake.

Example

To compile the full project in release mode using xmake you can use this to configure first:

xmake f -m "Game__Shipping__Win64"

After configuring run:

xmake

Vs project files

If you want to generate visual studio project files, run:

xmake project -k vsxmake2022

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 11, 2024

I get this error after following your steps, after checking out this branch + the xmake branch in the Unreal submodule:

CMake Error at CMakeLists.txt:10 (get_target_property):
  get_target_property() called with non-existent target "Zydis".


CMake Error at CMakeLists.txt:11 (get_target_property):
  get_target_property() called with non-existent target "Zycore".


CMake Error at CMakeLists.txt:12 (message):
  message called with incorrect number of arguments

The command I ran was: xmake f -v --vs_runtime="MD" -m "Game__Shipping__Win64"

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 11, 2024

When running xmake project -k vsxmake2022, I get:

error: failed to parse manifest at `Z:\repos\oss_ue4ss\awesome-mod\RE-UE4SS\build\.packages\c\cargo_patternsleuth_bind\latest\cache\source\Cargo.toml`

Caused by:
  can't find library `patternsleuth_bind`, rename file to `src/lib.rs` or specify lib.path

The install_package.lua file already had your fix in it as well so I didn't modify the file.

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 12, 2024

After the latest changes, xmake f --vs_runtime="MD" -m "Game__Shipping__Win64" appears to succeed but xmake gives me several errors.

error:  Assembling: build\.gens\proxy_files\windows\x64\Game__Shipping__Win64\dwmapi.asm
MASM : fatal error A1000:cannot open file : build\.gens\proxy_files\windows\x64\Game__Shipping__Win64\dwmapi.asm
Z:\repos\oss_ue4ss\awesome-mod\RE-UE4SS\deps\first\Unreal\include\Unreal/Core/Windows/WindowsPlatformCompilerSetup.hpp(253): fatal error C1189: #error:  "Bad VCC option: C++ exception handling must be enabled" //lint !e309 suppress as lint doesn't have this defined
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(6): error C2230: could not find module 'Outputdevice'
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(10): error C2653: 'OutputDevice': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(10): error C2270: 'has_optional_arg': modifiers not allowed on nonmember functions
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(15): error C2653: 'OutputDevice': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(15): error C2653: 'File': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(15): error C2760: syntax error: 'attribute specifier' was unexpected here; expected ')'
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(15): error C2059: syntax error: 'attribute specifier'
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(16): error C2143: syntax error: missing ';' before '{'
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(16): error C2447: '{': missing function header (old-style formal list?)
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(22): error C2653: 'OutputDevice': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(22): error C2065: 'Formatter': undeclared identifier
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(22): error C2760: syntax error: 'new_formatter' was unexpected here; expected ')'
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(22): error C2146: syntax error: missing ')' before identifier 'new_formatter'
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(27): error C2653: 'OutputDevice': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(27): error C2653: 'File': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(39): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(27): error C3646: 'StringType': unknown override specifier
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(30): error C2653: 'File': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(30): error C2146: syntax error: missing ';' before identifier 'when_as_string'
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(30): error C2065: 'when_as_string': undeclared identifier
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(30): error C3861: 'STR': identifier not found
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(31): error C2065: 'when_as_string': undeclared identifier
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(34): error C2653: 'OutputDevice': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(34): error C2653: 'File': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(34): error C2065: 'StringViewType': undeclared identifier
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(34): error C2760: syntax error: 'string_to_format' was unexpected here; expected ')'
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(34): error C2146: syntax error: missing ')' before identifier 'string_to_format'
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(34): error C2653: 'File': is not a class or namespace name
deps\first\DynamicOutput\src\OutputDevice.mod.cpp(37): error C2059: syntax error: '}'
c1xx: fatal error C1083: Cannot open source file: 'build\.gens\proxy_files\windows\x64\Game__Shipping__Win64\dllmain.cpp': No such file or directory

It also appears that --vs_runtime="MD", as is suggested in your example command line, is outdated because I'm getting: warning: --vs_runtime=MD is deprecated, please use --runtimes=MD

Running xmake project -k vsxmake2022 ends in success, and building the solution generates the same errors as above.

@localcc
Copy link
Contributor Author

localcc commented Feb 12, 2024

Which environment are you running this in? Is it the x64 development tools prompt, some other?

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 12, 2024

Which environment are you running this in? Is it the x64 development tools prompt, some other?

I ran it in PowerShell, without running any other script like the vcvarsall script first.

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 19, 2024

Testing again after the latest commit gives me the following warnings when running xmake f --vs_runtime="MD" -m "Game__Shipping__Win64" but no errors, though I can't promise I wasn't getting this warning before the latest change, I might've missed it, and I don't know the importance of it:

warning: the arch "x64" is NOT a valid target triple, will be IGNORED and may cause compilation errors, please check it again

The errors regarding dwmapi.asm and "bad VCC option" when running xmake are gone, and the project appears to build successfully.

I also figured out my OutputDevice errors.
It turns out I had some WIP files in the OutputDevice/src directory and I guess either this new build system by default or you by choice are automatically compiling every file instead of explicitly listing each file that's supposed to be compiled.

This is a potential problem because we might have some unused files (and I do remember at least one file but unfortunately the name escapes me) that really should not be compiled.
It's a good idea to go through and match the old CMakeLists source files with the file tree and either explicitly prevent non-matching files from being compiled or just delete them from the repo completely.

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 19, 2024

It looks to me like ASMHelper and DynamicOutput are being dynamically linked.

@localcc
Copy link
Contributor Author

localcc commented Feb 19, 2024

I think unused files are better just deleted from the repo rather than not being selected in the build system, will check regarding the asmhelper/dynamicoutput linking incorrectly

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 19, 2024

The latest commit appears to be properly linking statically.
There's a problem with the Game_Debug target (and possibly others that aren't Game_Shipping, haven't tested other than these two):

error: GUI.cpp
UE4SS\src\GUI\GUI.cpp(454): error C3861: 'ProfilerSetThreadName': identifier not found

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 19, 2024

The ProfilerSetThreadName problem is apparent for all non-shipping targets according to intellisense.

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 20, 2024

How will this change work with IDEs that depend on CMake, like CLion ?
Would you somehow tell xmake to generate a CMake project and then open that particular directory in the IDE ?

@localcc
Copy link
Contributor Author

localcc commented Feb 20, 2024

You could be using generated cmake files, but usually the way I see most used for clion/clion nova is using the compiler commands generator (compile_commands)

@Buckminsterfullerene02
Copy link
Member

With fc251ba, I could not figure out a way to make cmake fallback to http if ssh fails like the others. Tried a bunch of things. So I hope it's not much of an issue if I just change this one clone from ssh to http

@Buckminsterfullerene02
Copy link
Member

How will this change work with IDEs that depend on CMake, like CLion ? Would you somehow tell xmake to generate a CMake project and then open that particular directory in the IDE ?

Tbh I gave up using CLion/CLion Nova for UE4SS, CLion is way too slow analysing and debugging (and thinks that UE4SSProgram.cpp has 10k errors) and Nova is brand new so is still fairly buggy (but doesn't have the same issue as CLion). Not to mention the pain in the arse that is trying to switch between configurations.

In the end I switched to using Rider which has VS Solution support so you can just run the vsxmake2022 command and then open the .sln with Rider with all the configs there. I don't know if you rely on specific features of CLion/CLion Nova but just for general IDE stuff n things, Rider is surprisingly poggers.

@Buckminsterfullerene02
Copy link
Member

Are more instructions required for C++ mod building?

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 22, 2024

How will this change work with IDEs that depend on CMake, like CLion ? Would you somehow tell xmake to generate a CMake project and then open that particular directory in the IDE ?

Tbh I gave up using CLion/CLion Nova for UE4SS, CLion is way too slow analysing and debugging (and thinks that UE4SSProgram.cpp has 10k errors) and Nova is brand new so is still fairly buggy (but doesn't have the same issue as CLion). Not to mention the pain in the arse that is trying to switch between configurations.

In the end I switched to using Rider which has VS Solution support so you can just run the vsxmake2022 command and then open the .sln with Rider with all the configs there. I don't know if you rely on specific features of CLion/CLion Nova but just for general IDE stuff n things, Rider is surprisingly poggers.

I've been testing CLion Nova for a while now and it's faster but yeah it's awfully glitchy right now, hopefully it will get better.

I have CLion set up very specifically so I don't really want to change to another IDE even if it's from JetBrains because some plugins aren't compatible or settings are named differently (so I can't find them) or missing or whatever.

I'll try figure something out after this is merged, I don't want to be holding it up just because of CLion.

@Buckminsterfullerene02
Copy link
Member

Buckminsterfullerene02 commented Feb 22, 2024

Merge checklist:

  • Update readme
  • Adding xmake to Build requirements.
  • Completely rewriting Build instructions.
  • Rewriting Updating dependencies, and possibly renaming it to Updating git submodules since that's a more accurate description. It really just needs to mention that you can cd into Unreal/patternsleuth and use git commands like pull origin main/master to update to the latest. Alternatively, this section could be removed if it's deemed that devs should already know how to deal with submodules.
  • Update relevant docs pages
  • Update changelog
  • Remove unused files (VS_Solution/ and cmake/?)

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 23, 2024

I updated the merge checklist to clarify some things regarding updating the readme file.

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 25, 2024

The latest commit appears to be properly linking statically. There's a problem with the Game_Debug target (and possibly others that aren't Game_Shipping, haven't tested other than these two):

error: GUI.cpp
UE4SS\src\GUI\GUI.cpp(454): error C3861: 'ProfilerSetThreadName': identifier not found

This problem appears to be fixed.

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 25, 2024

Could the default VS startup project be changed from proxy_generator to UE4SS ?

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
@UE4SS UE4SS self-requested a review February 28, 2024 22:16
@UE4SS
Copy link
Collaborator

UE4SS commented Feb 28, 2024

My approval is pending a final test of the build instructions, which I will do soon.

  • Main build instructions
  • Mod build instructions

@UE4SS
Copy link
Collaborator

UE4SS commented Feb 28, 2024

The regular build instructions appear to work fine, but the mod instructions are not working for me.

When following the mod build instructions, I get this error when executing xmake f -m "Game__Shipping__Win64" --runtimes="MD":

error: cannot execv(Z:\repos\oss_ue4ss\cxx_mods\RE-UE4SS\Output\Game__Shipping__Win64\proxy_generator\proxy_generator.exe C:\Windows\System32\dwmapi.dll Z:\repos\oss_ue4ss\cxx_mods\RE-UE4SS\build\.gens\proxy_files\windows\x64\Game__Shipping__Win64), No such file or directory

When building through VS instead, I get these errors:

1>EXEC : error : Unreal.lib(NameTypes.cpp.obj) : error LNK2005: "public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const __cdecl RC::Unreal::FName::ToString(void)const " (?ToString@FName@Unreal@RC@@QEBA?BV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(FMemory.cpp.obj) : error LNK2005: "public: static void * __cdecl RC::Unreal::FMemory::Realloc(void *,unsigned __int64,unsigned int)" (?Realloc@FMemory@Unreal@RC@@SAPEAXPEAX_KI@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(FMemory.cpp.obj) : error LNK2005: "public: static void __cdecl RC::Unreal::FMemory::Free(void *)" (?Free@FMemory@Unreal@RC@@SAXPEAX@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObject.cpp.obj) : error LNK2005: "public: bool __cdecl RC::Unreal::UObjectBase::IsA(class RC::Unreal::UClass *)const " (?IsA@UObjectBase@Unreal@RC@@QEBA_NPEAVUClass@23@@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObject.cpp.obj) : error LNK2005: "public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > __cdecl RC::Unreal::UObject::GetFullName(class RC::Unreal::UObject *)const " (?GetFullName@UObject@Unreal@RC@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@PEAV123@@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObjectGlobals.cpp.obj) : error LNK2005: "class RC::Unreal::UObject * __cdecl RC::Unreal::UObjectGlobals::FindObject(class RC::Unreal::UClass *,class RC::Unreal::UObject *,wchar_t const *,bool,struct RC::Unreal::ObjectSearcher *)" (?FindObject@UObjectGlobals@Unreal@RC@@YAPEAVUObject@23@PEAVUClass@23@PEAV423@PEB_W_NPEAUObjectSearcher@23@@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObjectGlobals.cpp.obj) : error LNK2005: "class RC::Unreal::UObject * __cdecl RC::Unreal::UObjectGlobals::FindFirstOf(wchar_t const *)" (?FindFirstOf@UObjectGlobals@Unreal@RC@@YAPEAVUObject@23@PEB_W@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObjectGlobals.cpp.obj) : error LNK2005: "void __cdecl RC::Unreal::UObjectGlobals::FindAllOf(wchar_t const *,class std::vector<class RC::Unreal::UObject *,class std::allocator<class RC::Unreal::UObject *> > &)" (?FindAllOf@UObjectGlobals@Unreal@RC@@YAXPEB_WAEAV?$vector@PEAVUObject@Unreal@RC@@V?$allocator@PEAVUObject@Unreal@RC@@@std@@@std@@@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(AActor.cpp.obj) : error LNK2005: "public: struct RC::Unreal::FVector __cdecl RC::Unreal::AActor::K2_GetActorLocation(void)" (?K2_GetActorLocation@AActor@Unreal@RC@@QEAA?AUFVector@23@XZ) already defined in UE4SS.lib(UE4SS.dll)
1>   Creating library Output\Game__Shipping__Win64\MyAwesomeMod\MyAwesomeMod.lib and object Output\Game__Shipping__Win64\MyAwesomeMod\MyAwesomeMod.exp
1>patternsleuth_bind.lib(patternsleuth-748df43b2dbb523b.patternsleuth.4766f465fabaff7a-cgu.11.rcgu.o) : error LNK2019: unresolved external symbol __imp_GetModuleInformation referenced in function _ZN13patternsleuth7process8internal7windows10read_image17h1a4eb304d96ae647E
1>Output\Game__Shipping__Win64\MyAwesomeMod\MyAwesomeMod.dll : fatal error LNK1120: 1 unresolved externals
1>
1>C:\Users\<user>\xmake\scripts\vsxmake\vsproj\Xmake.targets(99,5): error MSB3073: The command "..." exited with code -1.
1>Done building project "MyAwesomeMod.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

stdout Outdated Show resolved Hide resolved
target_helpers.lua Outdated Show resolved Hide resolved
@Buckminsterfullerene02
Copy link
Member

Buckminsterfullerene02 commented Feb 29, 2024

The regular build instructions appear to work fine, but the mod instructions are not working for me.

When following the mod build instructions, I get this error when executing xmake f -m "Game__Shipping__Win64" --runtimes="MD":

error: cannot execv(Z:\repos\oss_ue4ss\cxx_mods\RE-UE4SS\Output\Game__Shipping__Win64\proxy_generator\proxy_generator.exe C:\Windows\System32\dwmapi.dll Z:\repos\oss_ue4ss\cxx_mods\RE-UE4SS\build\.gens\proxy_files\windows\x64\Game__Shipping__Win64), No such file or directory

When building through VS instead, I get these errors:

1>EXEC : error : Unreal.lib(NameTypes.cpp.obj) : error LNK2005: "public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const __cdecl RC::Unreal::FName::ToString(void)const " (?ToString@FName@Unreal@RC@@QEBA?BV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(FMemory.cpp.obj) : error LNK2005: "public: static void * __cdecl RC::Unreal::FMemory::Realloc(void *,unsigned __int64,unsigned int)" (?Realloc@FMemory@Unreal@RC@@SAPEAXPEAX_KI@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(FMemory.cpp.obj) : error LNK2005: "public: static void __cdecl RC::Unreal::FMemory::Free(void *)" (?Free@FMemory@Unreal@RC@@SAXPEAX@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObject.cpp.obj) : error LNK2005: "public: bool __cdecl RC::Unreal::UObjectBase::IsA(class RC::Unreal::UClass *)const " (?IsA@UObjectBase@Unreal@RC@@QEBA_NPEAVUClass@23@@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObject.cpp.obj) : error LNK2005: "public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > __cdecl RC::Unreal::UObject::GetFullName(class RC::Unreal::UObject *)const " (?GetFullName@UObject@Unreal@RC@@QEBA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@PEAV123@@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObjectGlobals.cpp.obj) : error LNK2005: "class RC::Unreal::UObject * __cdecl RC::Unreal::UObjectGlobals::FindObject(class RC::Unreal::UClass *,class RC::Unreal::UObject *,wchar_t const *,bool,struct RC::Unreal::ObjectSearcher *)" (?FindObject@UObjectGlobals@Unreal@RC@@YAPEAVUObject@23@PEAVUClass@23@PEAV423@PEB_W_NPEAUObjectSearcher@23@@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObjectGlobals.cpp.obj) : error LNK2005: "class RC::Unreal::UObject * __cdecl RC::Unreal::UObjectGlobals::FindFirstOf(wchar_t const *)" (?FindFirstOf@UObjectGlobals@Unreal@RC@@YAPEAVUObject@23@PEB_W@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(UObjectGlobals.cpp.obj) : error LNK2005: "void __cdecl RC::Unreal::UObjectGlobals::FindAllOf(wchar_t const *,class std::vector<class RC::Unreal::UObject *,class std::allocator<class RC::Unreal::UObject *> > &)" (?FindAllOf@UObjectGlobals@Unreal@RC@@YAXPEB_WAEAV?$vector@PEAVUObject@Unreal@RC@@V?$allocator@PEAVUObject@Unreal@RC@@@std@@@std@@@Z) already defined in UE4SS.lib(UE4SS.dll)
1>Unreal.lib(AActor.cpp.obj) : error LNK2005: "public: struct RC::Unreal::FVector __cdecl RC::Unreal::AActor::K2_GetActorLocation(void)" (?K2_GetActorLocation@AActor@Unreal@RC@@QEAA?AUFVector@23@XZ) already defined in UE4SS.lib(UE4SS.dll)
1>   Creating library Output\Game__Shipping__Win64\MyAwesomeMod\MyAwesomeMod.lib and object Output\Game__Shipping__Win64\MyAwesomeMod\MyAwesomeMod.exp
1>patternsleuth_bind.lib(patternsleuth-748df43b2dbb523b.patternsleuth.4766f465fabaff7a-cgu.11.rcgu.o) : error LNK2019: unresolved external symbol __imp_GetModuleInformation referenced in function _ZN13patternsleuth7process8internal7windows10read_image17h1a4eb304d96ae647E
1>Output\Game__Shipping__Win64\MyAwesomeMod\MyAwesomeMod.dll : fatal error LNK1120: 1 unresolved externals
1>
1>C:\Users\<user>\xmake\scripts\vsxmake\vsproj\Xmake.targets(99,5): error MSB3073: The command "..." exited with code -1.
1>Done building project "MyAwesomeMod.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

For the record, I could not reproduce this, I could build MyAwesomeMod no problemo. My guess is that since xmake UEPsuedo branch isn't merged yet, you are still using the old UEPsuedo version. I basically just copied my RE-UE4SS clone that's on the xmake branch in both repos, to MyMods directory.

@Buckminsterfullerene02
Copy link
Member

Buckminsterfullerene02 commented Mar 16, 2024

Just because I noticed non-internal devs are looking at this now, I'll pop in here that with latest commit I am having the Unreal linker errors same as before when you put some Unreal code in the mod. I.e. this: #377 (comment)
I am using the xmake.lua file that I updated in the last c++ docs commit. Might be something wrong with that. But localcc hasn't had a chance to look at it yet.

Just fyi: I just double checked to make sure I was compiling a bunch of Unreal code and I am and I'm not having any linker problems.

I deleted everything and recloned again on latest commit on this and on uepsuedo, I'm still having no luck. What xmake.lua file are you using for your mod?

I uploaded my test mod files. See if you can build it?
TestingMyAwesomeMod.zip

@UE4SS
Copy link
Collaborator

UE4SS commented Mar 16, 2024

Just because I noticed non-internal devs are looking at this now, I'll pop in here that with latest commit I am having the Unreal linker errors same as before when you put some Unreal code in the mod. I.e. this: #377 (comment)
I am using the xmake.lua file that I updated in the last c++ docs commit. Might be something wrong with that. But localcc hasn't had a chance to look at it yet.

Just fyi: I just double checked to make sure I was compiling a bunch of Unreal code and I am and I'm not having any linker problems.

I deleted everything and recloned again on latest commit on this and on uepsuedo, I'm still having no luck. What xmake.lua file are you using for your mod?

I uploaded my test mod files. See if you can build it? TestingMyAwesomeMod.zip

Turns out that I didn't update my xmake file completely.
This is my file:

local projectName = "MyAwesomeMod"

target(projectName)
	set_kind("shared")
	set_languages("cxx20")
	set_exceptions("cxx")
	
	add_includedirs(".")

	add_files("main.cpp")

	add_deps("UE4SS")

    on_load(function (target)
        import("build_configs", { rootdir = get_config("scriptsRoot") })
        build_configs:set_output_dir(target)
    end)

    on_config(function (target)
        import("build_configs", { rootdir = get_config("scriptsRoot") })
        build_configs:config(target)
    end)

    after_clean(function (target)
        import("build_configs", { rootdir = get_config("scriptsRoot") })
        build_configs:clean_output_dir(target)
    end)

Everything below add_deps is old stuff that I forgot to update.
After updating to match what it says in the mod creation guide, I also get linker errors.
So something is definitely wrong, either with the mod guide or in the core xmake files.
Something for @localcc to look at.

@UE4SS
Copy link
Collaborator

UE4SS commented Mar 16, 2024

I'm starting to have doubts about switching to xmake.

At least everyone knows roughly how to use cmake but if we switch to xmake we're kind of screwed until someone decides to learn it if something needs to be changed for whatever reason, and with cmake there's tons of information available whenever someone gets stuck and needs help while with xmake I haven't had much luck searching for help.
Also, the switch to xmake has proved to be difficult.
And then there's this: #427 (comment)

These things combined makes me doubt that changing to xmake is going to be easier in the long run than staying with cmake.

@Buckminsterfullerene02
Copy link
Member

Buckminsterfullerene02 commented Mar 16, 2024

I'm starting to have doubts about switching to xmake.

At least everyone knows roughly how to use cmake but if we switch to xmake we're kind of screwed until someone decides to learn it if something needs to be changed for whatever reason, and with cmake there's tons of information available whenever someone gets stuck and needs help while with xmake I haven't had much luck searching for help. Also, the switch to xmake has proved to be difficult. And then there's this: #427 (comment)

These things combined makes me doubt that changing to xmake is going to be easier in the long run than staying with cmake.

At least if you were still in the discord you'd know that every man and his dog has had some form of trouble or another with cmake build as it currently is. The rust integration with cmake (corrosion) is fragile at best. No one wants to maintain it. cmake is uncapable of falling back from ssh to http if ssh clone fails (which it does on the regular). I'm aware this PR has been rocky but I'm fairly confident that once xmake starts working it will just work. I mean, it was working fine, until I suggested localcc move the buildscripts into the existing tools folder just to keep the root repo clean and consistent. And the progress is only slow because people who want to work on it don't because they're busy or whatever, while everyone else is too hesitant to really look at xmake because it's new and are skeptical of its abilities.

That being said, narknon has always expressed the same concerns as you about xmake and the fact no one really knows about it. I do think you've got a fair point there. On the other hand, cmake's documentation is terrible and it has a serious problem with new versions releasing new features and then documentation either just not being updated properly, or is updated but its not obvious which versions support those. When I was first learning cmake it took me multiple painful months to realise about fetch content. It's just not documented obviously anywhere (unless you know to look for it), despite arguably being one of the most useful features cmake has to offer (imo). Meanwhile xmake is fresh and its docs are really easy to follow.

That's my two cents on it. I think it just needs to be given a chance (once everything works again).

after_load(function (target)
import("build_configs", { rootdir = get_config("scriptsRoot") })
import("target_helpers", { rootdir = get_config("scriptsRoot") })
build_configs:set_output_dir(target)
Copy link
Contributor

@bitonality bitonality Mar 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does our set_output_dir(target) helper accomplish something that the built-in target:set_targetdir/target:set_objectdir/target:set_dependir cannot?

@bitonality
Copy link
Contributor

I'm starting to have doubts about switching to xmake.
At least everyone knows roughly how to use cmake but if we switch to xmake we're kind of screwed until someone decides to learn it if something needs to be changed for whatever reason, and with cmake there's tons of information available whenever someone gets stuck and needs help while with xmake I haven't had much luck searching for help. Also, the switch to xmake has proved to be difficult. And then there's this: #427 (comment)
These things combined makes me doubt that changing to xmake is going to be easier in the long run than staying with cmake.

At least if you were still in the discord you'd know that every man and his dog has had some form of trouble or another with cmake build as it currently is. The rust integration with cmake (corrosion) is fragile at best. No one wants to maintain it. cmake is uncapable of falling back from ssh to http if ssh clone fails (which it does on the regular). I'm aware this PR has been rocky but I'm fairly confident that once xmake starts working it will just work. I mean, it was working fine, until I suggested localcc move the buildscripts into the existing tools folder just to keep the root repo clean and consistent. And the progress is only slow because people who want to work on it don't because they're busy or whatever, while everyone else is too hesitant to really look at xmake because it's new and are skeptical of its abilities.

That being said, narknon has always expressed the same concerns as you about xmake and the fact no one really knows about it. I do think you've got a fair point there. On the other hand, cmake's documentation is terrible and it has a serious problem with new versions releasing new features and then documentation either just not being updated properly, or is updated but its not obvious which versions support those. When I was first learning cmake it took me multiple painful months to realise about fetch content. It's just not documented obviously anywhere (unless you know to look for it), despite arguably being one of the most useful features cmake has to offer (imo). Meanwhile xmake is fresh and its docs are really easy to follow.

That's my two cents on it. I think it just needs to be given a chance (once everything works again).

Build engineer perspective to try and contextualize some of the kinks in the mod compilation context.

In my opinion, the templated xmake.lua that is in the c++ mod doc really ought to be a checked in file instead of a copy-paste from the docs.

  • If mod compilation fails locally, people can diff their old xmake.lua against the most current checked in version to determine if the issue is with their mod's build pipeline or with the UE4SS build pipeline.
  • Allows for easier linting/validation to ensure that a legal xmake.lua is being provided to modders.
  • Ensures that we are shipping a valid and easy way for modders to start making mods without having to learn the inner workings of the build pipe.

I also think a custom task that bootstraps the initial mod creation process would also decrease the amount of compilation failures due to issues with manually following the steps in the doc.

Proposing something like the following (syntax/options can be whatever we want):
xmake ue4ssmod new -d "C:\FolderForMyMod\"

  • Copy and paste the checked in template xmake.lua to the "C:\FolderForMyMod"
  • Add C:\FolderForMyMod\ as a buildable target
  • Generate VS files, etc. whatever else we want to provide to a new modder

This would enable the modder to bootstrap a buildable mod without having to create/touch an xmake.lua. This would also decouple the dev from the currently documented structure of

  • .../UE4SS repo
  • SIKE you actually need a .../ContainerDir/UE4SS repo
  • and you'll need a .../ContainerDir/MyModDir
  • Don't forget your .../ContainerDir/MyModDir/xmake.lua
  • And don't you dare forget the .../ContainerDir/xmake.lua

I have plenty of other ideas (and I'm sure we could get feedback on the onboard process from maintainers/modders) if we want to roll a UE4SS xmake task that can act as the entry point for modders in the development environment. It would certainly reduce the barrier to entry at the cost of up-front transparency to onboarding modders.

@UE4SS
Copy link
Collaborator

UE4SS commented Mar 17, 2024

Build engineer perspective to try and contextualize some of the kinks in the mod compilation context.

In my opinion, the templated xmake.lua that is in the c++ mod doc really ought to be a checked in file instead of a copy-paste from the docs.

* If mod compilation fails locally, people can diff their old xmake.lua against the most current checked in version to determine if the issue is with their mod's build pipeline or with the UE4SS build pipeline.

* Allows for easier linting/validation to ensure that a legal xmake.lua is being provided to modders.

* Ensures that we are shipping a valid and easy way for modders to start making mods without having to learn the inner workings of the build pipe.

I also think a custom task that bootstraps the initial mod creation process would also decrease the amount of compilation failures due to issues with manually following the steps in the doc.

Proposing something like the following (syntax/options can be whatever we want): xmake ue4ssmod new -d "C:\FolderForMyMod\"

* Copy and paste the checked in template `xmake.lua` to the "C:\FolderForMyMod"

* Add `C:\FolderForMyMod\` as a buildable target

* Generate VS files, etc. whatever else we want to provide to a new modder

This would enable the modder to bootstrap a buildable mod without having to create/touch an xmake.lua. This would also decouple the dev from the currently documented structure of

* `.../UE4SS repo`

* SIKE you actually need a `.../ContainerDir/UE4SS repo`

* and you'll need a `.../ContainerDir/MyModDir`

* Don't forget your `.../ContainerDir/MyModDir/xmake.lua`

* And don't you dare forget the `.../ContainerDir/xmake.lua`

I have plenty of other ideas (and I'm sure we could get feedback on the onboard process from maintainers/modders) if we want to roll a UE4SS xmake task that can act as the entry point for modders in the development environment. It would certainly reduce the barrier to entry at the cost of up-front transparency to onboarding modders.

We have the mod template repo already so we have to ask ourselves, is it easier to tell people to execute a command or is it easier to tell people to use the template repo ?
The command would probably just use the template repo to make updates easier to handle.
I believe the template repo is supposed to solve all the things you listed.
One thing I realized though is that I don't know how xmake works with dependencies.
I know with cmake it was problematic to put UE4SS outside the source directory, but I'm wondering if it's possible to have UE4SS at for example C:\UE4SS and all mods can somehow find the source from C:\UE4SSMods\<ModName>.
I solve this problem with links currently.

@Buckminsterfullerene02
Copy link
Member

Buckminsterfullerene02 commented Mar 17, 2024

In my opinion, the templated xmake.lua that is in the c++ mod doc really ought to be a checked in file instead of a copy-paste from the docs.

If mod compilation fails locally, people can diff their old xmake.lua against the most current checked in version to determine if the issue is with their mod's build pipeline or with the UE4SS build pipeline.
Allows for easier linting/validation to ensure that a legal xmake.lua is being provided to modders.
Ensures that we are shipping a valid and easy way for modders to start making mods without having to learn the inner workings of the build pipe.

Seems a bit overkill tbh when I doubt the mod xmake.lua will be changing at all once this is done. It will be the repo's main xmake.lua and buildscripts that will be changing.

Proposing something like the following (syntax/options can be whatever we want):
xmake ue4ssmod new -d "C:\FolderForMyMod" (...)
This would enable the modder to bootstrap a buildable mod without having to create/touch an xmake.lua. This would also decouple the dev from the currently documented structure of (...)

Template already does all this. Though currently it is using bats which probably isn't the best way to do it. The best way would probably be an xmake lua script. So feel free to take a look at what is already in those bats and port them to lua script. Note what the new_mod_setup bat is doing with git - on clone, it makes sure that you are checking out the latest version release tagged commit so that you're building your mods off the right API versions (which in 99% of the cases is latest release).

Currently in the docs we are describing the setup process and then at the end saying "oh by the way, there is a template you can use to do this for the rest of your mods". My reasoning for this order (rather than automated process first then manual setup) is so that modders understand exactly what the automated setup process is doing, which I'd say is pretty important when setting up your dev environment. Obviously if the process was super complex I wouldn't suggest users to do it manually. But for the most part it's just cloning the repo, copy and paste, change some names, and run a couple of commands.

@Buckminsterfullerene02
Copy link
Member

Buckminsterfullerene02 commented Mar 17, 2024

Just because I noticed non-internal devs are looking at this now, I'll pop in here that with latest commit I am having the Unreal linker errors same as before when you put some Unreal code in the mod. I.e. this: #377 (comment)
I am using the xmake.lua file that I updated in the last c++ docs commit. Might be something wrong with that. But localcc hasn't had a chance to look at it yet.

Just fyi: I just double checked to make sure I was compiling a bunch of Unreal code and I am and I'm not having any linker problems.

I deleted everything and recloned again on latest commit on this and on uepsuedo, I'm still having no luck. What xmake.lua file are you using for your mod?
I uploaded my test mod files. See if you can build it? TestingMyAwesomeMod.zip

Turns out that I didn't update my xmake file completely. This is my file:

local projectName = "MyAwesomeMod"

target(projectName)
	set_kind("shared")
	set_languages("cxx20")
	set_exceptions("cxx")
	
	add_includedirs(".")

	add_files("main.cpp")

	add_deps("UE4SS")

    on_load(function (target)
        import("build_configs", { rootdir = get_config("scriptsRoot") })
        build_configs:set_output_dir(target)
    end)

    on_config(function (target)
        import("build_configs", { rootdir = get_config("scriptsRoot") })
        build_configs:config(target)
    end)

    after_clean(function (target)
        import("build_configs", { rootdir = get_config("scriptsRoot") })
        build_configs:clean_output_dir(target)
    end)

Everything below add_deps is old stuff that I forgot to update. After updating to match what it says in the mod creation guide, I also get linker errors. So something is definitely wrong, either with the mod guide or in the core xmake files. Something for @localcc to look at.

I'm pretty sure I just fucked up on the mod's xmake.lua file. It builds fine for me with yours (and doesn't fail to find the build_scripts either, which is what I thought was wrong with yours). The fix that makes it actually find the build scripts is changing on_load to after_load. Nevermind, I set it back, wiped everything and recloned (didn't need to change branches or anything as they were set the same as before) and now it both finds build_configs fine and it builds with some unreal stuff in to link. What?? I don't understand how this is the exact same file but didn't work before...

I'll update the c++ docs with the correct file... I guess? I.e. reversing the xmake.lua in the docs commit since apparently the old one worked fine.

@localcc
Copy link
Contributor Author

localcc commented Mar 24, 2024

Could everyone re-check the compilation following the docs once again so the PR can get unblocked?

@UE4SS
Copy link
Collaborator

UE4SS commented Mar 24, 2024

Builds successfully following the updated creating-a-c++-mod.md file.

Has anyone actually tested the CI scripts ?
I don't see xmake being installed in the scripts.

@UE4SS
Copy link
Collaborator

UE4SS commented Mar 24, 2024

I built UE4SS standalone (without mods) and it still works.

Worth noting is that the output directory for UE4SS.dll has changed.
Old path : ue4ss\build_ninja_msvc\Output\Game__Shipping__Win64\UE4SS\bin
New path:ue4ss\Output\Game__Shipping__Win64\UE4SS

  1. The Output directory used to be in the build directory, now it's in the root directory.
  2. The bin directory no longer exists.

I don't think this will matter for our CI scripts, because build.py scans every directory until it finds the files its looking for.

@UE4SS
Copy link
Collaborator

UE4SS commented Mar 24, 2024

I ran the experimental release action on this branch and it doesn't recognize the xmake command: https://github.com/UE4SS-RE/RE-UE4SS/actions/runs/8409906618/job/23027788012
We should at least take care of that.

I know our pre-existing CI won't be able to compile as is even if it finds xmake because it doesn't checkout the xmake branch for the Unreal submodule, so either someone has to fork it and set all the CI up in their fork or we can make sure xmake is installed in our current CI and fix any potential problems after the merge.

@bitonality
Copy link
Contributor

I built UE4SS standalone (without mods) and it still works.

Worth noting is that the output directory for UE4SS.dll has changed. Old path : ue4ss\build_ninja_msvc\Output\Game__Shipping__Win64\UE4SS\bin New path:ue4ss\Output\Game__Shipping__Win64\UE4SS

1. The `Output` directory used to be in the build directory, now it's in the root directory.

2. The `bin` directory no longer exists.

I don't think this will matter for our CI scripts, because build.py scans every directory until it finds the files its looking for.

Output Structure

Project compilation will involve the following categories of outputs:

  • Dependencies: *.cpp.obj.d/*.lib.d
  • Generations: dwmapi.asm/dwmapi.def
  • Objs: *.c.obj/*.cpp.obj
  • Packages: patternsleuth/polyhook/etc
  • Output: *.lib/*.dll/*.pdb/etc

We should probably decide if we want to

  1. Replicate the intermediate and output directory structure we had with CMake
  2. Use the xmake default /build/... to store intermediates and outputs
  3. Use the current branch's impl of having /build/ for deps and intermediates and /Output/ for binary output.

@narknon
Copy link
Collaborator

narknon commented Mar 24, 2024

We should follow either GNU standards or mimic UE for output structure.

@localcc
Copy link
Contributor Author

localcc commented Mar 26, 2024

I much rather prefer the ue structure so we should try mimicking that.

@localcc
Copy link
Contributor Author

localcc commented Apr 5, 2024

Anything else that needs to be addressed? Would be best to have this merged asap so me, and maybe some other maintainers can get unblocked and get going.

UE4SS
UE4SS previously approved these changes Apr 5, 2024
Copy link
Collaborator

@UE4SS UE4SS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This builds as of the latest commit, both standalone and as part of a mod.
I don't have any further requests.

@UE4SS UE4SS dismissed their stale review April 5, 2024 21:35

Forgot about github actions.

@localcc
Copy link
Contributor Author

localcc commented Apr 5, 2024

@Buckminsterfullerene02 @bitonality I would like to request a build from either of you also, to verify it runs on different machines.

@UE4SS
Copy link
Collaborator

UE4SS commented Apr 5, 2024

On second thought, this needs to be addressed: #377 (comment)

Copy link
Collaborator

@UE4SS UE4SS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with the current state of this PR.
I will look at any CI problems (if they occur) after the merge.

@Okaetsu
Copy link
Contributor

Okaetsu commented Apr 5, 2024

Builds fine for me.

Copy link
Member

@Buckminsterfullerene02 Buckminsterfullerene02 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builds fine!

Someone who has the perms needs to merge xmake branch in UEPsuedo first, then do a git squash and force push before this PR can be merged.

Xmake is a nicer build system, which doesn't require as much effort to
add new build configurations in that work with every generator. Xmake
also allows to interface with CMake projects which allows us to easily
use existing CMake external dependencies.

All internal dependencies were converted to use xmake.

Xmake also has a nice package manager which doesn't require any
configuration on the user's side, allowing us to use packages from that
if needed.
@localcc localcc merged commit 4ea0fb4 into main Apr 6, 2024
@localcc localcc deleted the xmake branch April 6, 2024 08:23
@UE4SS
Copy link
Collaborator

UE4SS commented Apr 13, 2024

I have CLion set up very specifically so I don't really want to change to another IDE even if it's from JetBrains because some plugins aren't compatible or settings are named differently (so I can't find them) or missing or whatever.

I'll try figure something out after this is merged, I don't want to be holding it up just because of CLion.

In case anyone stumbles across this and wonders if I got CLion to work.
The answer is yes, with the compile_commands xmake option: xmake project -k compile_commands

Another problem was that I'm on Linux and we don't yet support Linux so I've had to figure out some way to use xmake to generate Windows files.
I was unable to figure out how to make wine work so I've resorted using a Windows VM that's always on and that has the UE4SS source as a shared drive.
I ssh into my VM and execute gen.bat, which contains the following:

@echo off
net use Z: \\192.168.0.182\stuff_shared /u:<username> *
Z:
cd Z:\repos\oss_ue4ss\cxx_mods
:: Note profilerFlavor being None.
:: It's set to Tracy by default if left out for debug builds and my VM doesn't like that.
xmake f --profilerFlavor=None -m "Game__Debug__Win64" -y
xmake project -k compile_commands
:: This file is stored in the cxx_mods directory.
:: Because reasons, I need to execute it multiple times.
:: If I don't, the search & replace only partially completes.
py fix_compile_commands.py
py fix_compile_commands.py
py fix_compile_commands.py
py fix_compile_commands.py
py fix_compile_commands.py
:: I store this bat file at C:\Users\<username>
:: As a result, re-entering the C drive will automatically put me right where I have my bat script.
:: That means I can re-execute this bat without needing to cd to it.
C:

This is the file I use to convert my compile_commands.json from Windows to Linux.
This is needed because obviously Windows binaries like cl.exe won't be found by CLion on Linux.

# This python script fixes all the paths in compile_commands.json generated by the 'xmake project -k compile_commands' command.
# The purpose of this is to allow compile_commands.json to be generated on a Windows machine (i.e. VM) via SSH, but a build server should also be possible.
# This script is necessary because:
# 1. I want to use the CLion IDE on my Linux machine.
# 2. Our project (UE4SS) doesn't support Linux builds yet so any attempt to use xmake will fail.
# 3. We no longer use cmake and, I've failed to figure out how to use xmake successfully via wine.

# Absolute path to compile_commands.json.
# This can be either on the client or the server, it depends on where you execute this script.
# This file needs to exist on the machine that you execute this script on.
# I prefer to execute this on the server alongside all my other toolchain scripts.
compile_commands_file = r"Z:\repos\oss_ue4ss\cxx_mods\compile_commands.json"

# Absolute path that compile_commands.json uses for its 'directory' field on the server.
server_project_root = r"Z:/repos/oss_ue4ss/cxx_mods"

# Absolute path to the actual project on the client.
client_project_root = r"/stuff/repos/oss_ue4ss/cxx_mods"

# Absolute path to cl.exe and ml64.exe on the server.
server_cl_exe = r"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.37.32822/bin/HostX64/x64/cl.exe"
server_ml64_exe = r"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.37.32822/bin/HostX64/x64/ml64.exe"

# Absolute path to clang-cl on the client.
client_clang_cl = r"/stuff/repos/llvm/llvm-project/build_clang_cxx_cxxabi_unwind_18rc3/bin/clang-cl"

with open(compile_commands_file, mode="r") as file:
    data = file.read()
    data = data.replace(server_project_root, client_project_root)
    data = data.replace(r"\\", "/")
    data = data.replace(server_cl_exe, client_clang_cl)
    data = data.replace(server_ml64_exe, client_clang_cl)

with open(compile_commands_file, mode="w") as file:
    file.write(data)

My workflow is this:

  1. SSH into VM, and just leave it connected for convenience.
  2. Execute 'gen.bat' in the VM.
  3. Open CLion and open compile_commands.json.
  4. Make whatever code change I want.
  5. Execute gen.bat whenever appropriate, for example if you added a new source file.
  6. Execute build.bat in the VM.

My build.bat file is very simple:

Z:
cd Z:\repos\oss_ue4ss\cxx_mods
xmake
C:

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

Successfully merging this pull request may close these issues.

7 participants