I’ve been on a mission to get the libraries I have in CMake working in my UE4 project, where the UE4 project will be able to link in targets, by name, including all transitive dependencies (if we specify LibA and it requires LibB and LibC, we need to link all three of them). This is the current structure:
Root('RTG') CMakeLists.txt (the root file controlling the repo) Build Normal CMake build stuff Libs Client Client_Core ... Shared Shared_Network Shared_Physics ... Src Server Test_Client ... UE4 (not known to root CMakeLists.txt) rtg_client (UE4 proj root) Source Intermediate rtg_client.uproject
Most of my efforts to get UE4 to play nice with this structure have failed, but my current approach is;
- In rtg_client.build.cs (basic version here), I specify the CMake targets I want by name, and pass them to a Python script that generates a CMakeLists.txt file in /UE4/rtg_client/Intermediate containing those targets as dependencies of a target ‘DummyClient’
- The python script calls ‘cmake’ on that dir, which generates a .vcxproj for the DummyClient (we have to do this to flatten down the dependency tree - what if we specify LibA but it depends on LibB? The .vcxproj has all of this info)
- We parse the DummyClient.vcxproj file to get all of the library paths, library names, and include paths
- The above info is given to UE4 at the bottom of the .build.cs file via ‘PublicAdditionalLibraries’, ‘PublicLibraryPaths’, and ‘PublicIncludePaths’
- There is a pre-build step in the .uproject file that triggers this .bat file (or something very similar):
cd "Intermediate/_build" && cmake --build . --target DummyClient
So that any changes to the libraries by the root-level CMake projects (‘Server’ etc) are built for the rtg_client project to use and link.
Can anyone come up with a better solution? I don’t want to modify much of the Root/CMakeLists.txt file since it’s UE4-agnostic mostly. Maybe someone else here has gotten a UE4 project to play nicer with CMake? Is there some CMake parsing support built-in somewhere? I doubt it but you never know. I’m open to changing UBT (and the engine in general) to make this easier! Seriously; give me some pointers if you think it can be done better!
The big one problem; even with bIgnoreOutdatedImportLibraries set to false, UE4 does not re-link modified libraries! All of this work and UE4 just ignores the lib changes! This means that if I make changes to e.g. the ‘Shared’ libraries via the Server’s project file, and then run the client, the client won’t pick up those changes without first touching its source to trigger a relink (I think that’s what it would take).