Hi,
I have been tasked with porting our C++ codebase from Windows/Linux to MacOS.
Our setup uses Premake to generate platform specific project files. On Windows it creates a Visual Studio solution and project files, on Linux it creates makefiles, and on MacOS it generates an Xcode workspace and project files.
Our project hierarchy looks something like this:
Solution/Workspace S
-
Project A (shared library)
-
Project B (shared library)
-
Project C (shared library)
-
Projects D to R (About a dozen or so - all shared libraries)
-
Project V (application)
-
Project W (application)
-
Project X (application)
-
Project Y (application)
-
Project Z (application)
Projects B and C depend on A.
Projects D to R are dependent on some or all of the projects A, B, and C.
Each application is dependent on projects A, B, and C, and some of the intermediate projects D to R. (The exact dependencies vary according to the application.) Additionally, some applications can load shared libraries dynamically according to their state/settings. I.e., not all shared library dependencies are known at build time.
Initially all building typically happens on the command line. Once our build script has run Premake to generate the project files, it proceeds to build everything. Further builds can happen within Visual Studio/Xcode as part of the normal workflow. However, building must happen on the command line for DevOps CI/Release builds.
On Windows, for example, MSBuild lets me build the entire solution for a given configuration (Debug/Release/etc) in a single command. This builds projects A, B, C in order, followed by the intermediate projects (D to R), followed by the applications (V to Z). Each project is built once.
Same deal for Linux. Make builds each project in turn according to the dependencies with a single command. Each project is build once.
On MacOS, however, xcodebuild doesn't let me just build the entire workspace for a given configuration.
I can specify a workspace, but then I have to also specify a scheme. Or I can just specify a specific project.
However, when I build a specific project, Xcodebuild always builds all dependencies.
So my build script at the moment explicitly builds projects D to R, followed by applications V to Z.
This, however, leads to the ridiculous situation of Xcode building projects in the following order:
-
D, C, B, A
-
E, C, A
-
F, C, B, A
-
G, B, A
-
etc...
-
V, F, G, H, C, B, A
-
W, G, I, C, B, A
-
X, K, C, B, A
-
etc...
With the obvious effect of our MacOS builds taking 20+ times longer than their Windows/Linux counterparts.
So, my main questions are:
- Is it possible to just build every project in the workspace once?
- Or if that can't be done, is it possible to not build project dependencies? I.e., can I just build the single project I specify?
- If neither of those are possible, how can I optimise my builds so that they don't take half a day to complete?
I should point out, removing the project dependencies isn't an option. If project A is genuinely out of date, it should be built if I build one of the applications. Xcode should be smart enough to realise that it doesn't need to build everything every time.