If you want an option to Xcode builds, the Buck build system can be a good solution. I’ll show you in this guide how to get started and why to use an alternative build system. You can use Buck as a project generator too, but it’s not the main idea. If you are looking only for a project generator, you can use other easier options.
For first, you need to understand the build system concept. Xcode isn’t a build system, it’s an IDE, that contains a build system. Build systems have the rules of compiling code and packaging it. Like an iOS build system, it calls swiftc to compile swift code, ibtool to compile xibs (…) and after it, creates the .app, the binary in the correct structure.
Now, clean your mind and forget Xcode for now…
Think about your project structure, the modules, files, resources… Go to the finder and start creating folders to organize your code.
Let’s setup Buck
What you’ll install:
- Command line tools;
- Java 8;
I recommend you use HomeBrew.
To install The command line tools:
Buck is written in Java, then you will need to install Java in your machine. Not, let’s install Java using AdoptOpenJDK:
brew tap AdoptOpenJDK/openjdk brew install --cask adoptopenjdk8
Let’s install buck now:
brew tap facebook/fb brew install buck
If you receive a error like
Error: /usr/local/Cellar/buck/2021.01.12.01 is not a directory Run
brew link buck
For the last step, run:
brew install watchman
You can see the complete guide here.
Before using Buck, I recommend you read this article. Will help you to understand how a .app or .ipa is generated.
The most benefit of Buck is modularization. Then, stop thinking in your app as a BIG code, start to think in a LOT of small parts of code. Each module needs to work “alone”, with dependencies of course, but you need to can use the module in another app without bringing all other modules.
Each module needs a BUCK file. It’s a file without an extension named BUCK. In this file, you will teach buck how to build the module.
To use buck, some default configs are needed. See the file
.buckconfig . This file contains the default configs and some paths needed.
To generate a .app, or using the correct term, a Bundle, you need a Binary. A Binary is an executable file with your code. And pay attention here, a saw your CODE. Assets, xibs, and storyboards aren’t code!
Go to VeryCoolApp/BUCK. You’ll see a code like this:
apple_binary( name = “VeryCoolAppBinary”, visibility = [“PUBLIC”], srcs = glob([‘**/*.swift’]), ... is_main_run_destination = True, )
apple_binary will generate a binary (oh a Sherlock Holmes here…). This binary by self doesn’t do anything, you will need to put it inside a Bundle.
apple_bundle( name = “VeryCoolApp”, visibility = [“PUBLIC”], extension = “app”, binary = “:VeryCoolAppBinary”, product_name = “VeryCoolApp”, info_plist = “Info.plist”, ... )
Finally, the Bundle is the app! A Bundle is in the resume a folder that contains all compiled sources.
All of the parameters you can find at buck documentation.
“Ok, but my app has assets and xibs and storyboards, where did I put it?”
As I saw before, the BUCK file is how we teach buck to build our files. Let’s see how to compile assets:
apple_asset_catalog( name = “VeryCoolAppAssets”, visibility = [“PUBLIC”], dirs = [“Media.xcassets”], )
After added the
apple_asset_catalog to your buck file, you need to use it as a dependency in your app:
apple_binary( name = “VeryCoolAppBinary”, visibility = [“PUBLIC”], srcs = glob([‘**/*.swift’]), deps = [“:VeryCoolAppAssets”], )
Ok, the next step is to compile de xibs and storyboards, the resources:
apple_resource( name = “VeryCoolAppResources”, visibility = [“PUBLIC”], files = glob([ “**/*.xib” ]), )
If you need to compile storyboards too, just add them to files . Now, let’s use it as a dependency:
apple_binary( name = “VeryCoolAppBinary”, visibility = [“PUBLIC”], srcs = glob([‘**/*.swift’]), deps = [“:VeryCoolAppResources”, “:VeryCoolAppAssets”], )
Congratulations!!! Now, a buck can build your app! Try to make:
buck build VeryCoolApp
Yeah, finally we will create a Module! An independent module. Please, go to VeryCoolLibrary/BUCK.
Here is more simple, it’s a
apple_library( name = “VeryCoolLibrary”, visibility = [“PUBLIC”], srcs = glob([‘*.swift’]), tests = [“:VeryCoolLibraryTests”], )
It’s an independent library. This library has a
tests module inside:
apple_test( name = “VeryCoolLibraryTests”, ... deps = [ “//VeryCoolLibrary:VeryCoolLibrary”, ], srcs = glob([ “Tests/Sources/*.swift”, ]), )
Now, to use the library is too easy, do you remember de
apple_binary( name = “VeryCoolAppBinary”, visibility = [“PUBLIC”], srcs = glob([‘**/*.swift’]), deps = [“:VeryCoolAppResources”, “:VeryCoolAppAssets”, “//VeryCoolLibrary:VeryCoolLibrary”], )
Congratulations!!! Now, a buck can test your library! Try to make:
buck test //VeryCoolLibrary -n “iPhone 12
The make file is only to help you with the commands.
To use, just create a new file named Makefile and add:
build: @-BUCK build //VeryCoolApp
make build for example.
Yes, Buck can create an Xcode project for you. Run:
BUCK project VeryCoolApp && open VeryCoolApp/VeryCoolApp.xcworkspace
You can find all code in this repository: