diff options
Diffstat (limited to 'third_party/bazel/rules_haskell/docs/haskell.rst')
-rw-r--r-- | third_party/bazel/rules_haskell/docs/haskell.rst | 364 |
1 files changed, 0 insertions, 364 deletions
diff --git a/third_party/bazel/rules_haskell/docs/haskell.rst b/third_party/bazel/rules_haskell/docs/haskell.rst deleted file mode 100644 index 353561111a21..000000000000 --- a/third_party/bazel/rules_haskell/docs/haskell.rst +++ /dev/null @@ -1,364 +0,0 @@ -.. _guide: - -Introduction to Bazel: Building a Haskell project -================================================= - -In this tutorial, you'll learn the basics of building Haskell -applications with Bazel. You will set up your workspace and build -a simple Haskell project that illustrates key Bazel concepts, such as -targets and ``BUILD.bazel`` files. After completing this tutorial, take -a look at :ref:`Common Haskell build use cases <use-cases>` for -information on more advanced concepts such as writing and running -Haskell tests. - -What you'll learn ------------------ - -In this tutorial you'll learn how to: - -* build a target, -* visualize the project's dependencies, -* split the project into multiple targets and packages, -* control target visibility across packages, -* reference targets through labels. - -Before you begin ----------------- - -To prepare for the tutorial, first `install Bazel`_ if you don't have -it installed already. Then, retrieve the ``rules_haskell`` GitHub -repository:: - - git clone https://github.com/tweag/rules_haskell/ - -The sample project for this tutorial is in the ``tutorial`` -directory and is structured as follows:: - - rules_haskell - └── tutorial - ├── WORKSPACE - ├── main - │ ├── BUILD.bazel - │ └── Main.hs - └── lib - ├── BUILD.bazel - └── Bool.hs - -The first thing to do is to:: - - $ cd tutorial - -Build with Bazel ----------------- - -Set up the workspace -^^^^^^^^^^^^^^^^^^^^ - -Before you can build a project, you need to set up its workspace. -A workspace is a directory that holds your project's source files and -Bazel's build outputs. It also contains files that Bazel recognizes as -special: - -* the ``WORKSPACE`` file, which identifies the directory and its - contents as a Bazel workspace and lives at the root of the project's - directory structure, - -* one or more ``BUILD.bazel`` files, which tell Bazel how to build different - parts of the project. (A directory within the workspace that - contains a ``BUILD.bazel`` file is a *package*. You will learn about - packages later in this tutorial.) - -To designate a directory as a Bazel workspace, create an empty file -named ``WORKSPACE`` in that directory. - -When Bazel builds the project, all inputs and dependencies must be in -the same workspace. Files residing in different workspaces are -independent of one another unless linked, which is beyond the scope of -this tutorial. - -Understand the BUILD file -^^^^^^^^^^^^^^^^^^^^^^^^^ - -It is recommended to use a ``.bazel`` extension for each ``BUILD`` file to -avoid clashing with files or folders already using that name. - -A ``BUILD.bazel`` file contains several different types of instructions for -Bazel. The most important type is the *build rule*, which tells Bazel -how to build the desired outputs, such as executable binaries or -libraries. Each instance of a build rule in the ``BUILD.bazel`` file is -called a *target* and points to a specific set of source files and -dependencies. A target can also point to other targets. - -Take a look at the ``BUILD.bazel`` file in the ``tutorial/lib`` directory:: - - haskell_library( - name = "booleans", - srcs = ["Bool.hs"], - ) - -In our example, the ``booleans`` target instantiates the -`haskell_library`_ rule. The rule tells Bazel to build a reusable -(statically or dynamically linked) library from the ``Bool.hs`` source -file with no dependencies. - -The attributes in the target explicitly state its dependencies and -options. While the ``name`` attribute is mandatory, many are optional. -For example, in the ``booleans`` target, ``name`` is self-explanatory, -and ``srcs`` specifies the source file(s) from which Bazel builds the -target. - -Build the project -^^^^^^^^^^^^^^^^^ - -Let's build your sample project. Run the following command:: - - $ bazel build //lib:booleans - -Notice the target label - the ``//lib:`` part is the location of our -``BUILD.bazel`` file relative to the root of the workspace, and ``booleans`` -is what we named that target in the ``BUILD.bazel`` file. (You will learn -about target labels in more detail at the end of this tutorial.) - -Bazel produces output similar to the following:: - - INFO: Found 1 target... - Target //lib:booleans up-to-date: - bazel-bin/lib/libZSbooleans/libZSbooleans.conf - bazel-bin/lib/libZSbooleans/package.cache - INFO: Elapsed time: 2.288s, Critical Path: 0.68s - -Congratulations, you just built your first Bazel target! Bazel places -build outputs in the ``bazel-bin`` directory at the root of the -workspace. Browse through its contents to get an idea for Bazel's -output structure. - -Review the dependency graph -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -A successful build has all of its dependencies explicitly stated in -the ``BUILD.bazel`` file. Bazel uses those statements to create the -project's dependency graph, which enables accurate incremental builds. - -Let's visualize our sample project's dependencies. First, generate -a text representation of the dependency graph (run the command at the -workspace root):: - - bazel query --nohost_deps --noimplicit_deps \ - 'deps(//lib:booleans)' --output graph - -The above command tells Bazel to look for all dependencies for the -target ``//lib:booleans`` (excluding host and implicit dependencies) -and format the output as a graph. - -Then, paste the text into GraphViz_. - -On Ubuntu, you can view the graph locally by installing GraphViz and the xdot -Dot Viewer:: - - sudo apt update && sudo apt install graphviz xdot - -Then you can generate and view the graph by piping the text output above -straight to xdot:: - - xdot <(bazel query --nohost_deps --noimplicit_deps \ - 'deps(//lib:booleans)' --output graph) - -As you can see, the first stage of the sample project has a single -target that builds a single source file with no additional -dependencies: - -.. digraph:: booleans - - node [shape=box]; - "//lib:booleans" - "//lib:booleans" -> "//lib:Bool.hs" - "//lib:Bool.hs" - -Now that you have set up your workspace, built your project, and -examined its dependencies, let's add some complexity. - -Refine your Bazel build ------------------------ - -While a single target is sufficient for small projects, you may want -to split larger projects into multiple targets and packages to allow -for fast incremental builds (that is, only rebuild what's changed) and -to speed up your builds by building multiple parts of a project at -once. - -Specify multiple build targets -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Let's split our sample project build into two targets. Take a look at -the ``BUILD.bazel`` files in the ``tutorial/lib`` and ``tutorial/main`` -directories. The contents of both files could have been kept in -a single ``BUILD.bazel`` as follows:: - - haskell_library( - name = "booleans", - srcs = ["Bool.hs"], - ) - - haskell_toolchain_library(name = "base") - - haskell_binary( - name = "demorgan", - srcs = ["Main.hs"], - compiler_flags = ["-threaded"], - deps = [":base", ":booleans"], - ) - -With this single ``BUILD.bazel`` file, Bazel first builds the ``booleans`` -library (using the `haskell_library`_ rule), then the ``demorgan`` -binary (which as an example uses the ``booleans`` library to check one -of the De Morgan laws). The ``deps`` attribute in the ``demorgan`` -target tells Bazel that the ``:booleans`` library is required to build -the ``demorgan`` binary. The binary also requires the ``base`` -built-in library that ships with GHC, to perform I/O among other -things. Libraries like ``base``, ``bytestring`` and others that ship -with GHC are special in that they are prebuilt outside of Bazel. To -import them as regular targets, we use the `haskell_toolchain_library`_ rule. - -Let's build this new version of our project:: - - $ bazel build //main:demorgan - -Bazel produces output similar to the following:: - - INFO: Found 1 target... - Target //main:demorgan up-to-date: - bazel-bin/main/demorgan - INFO: Elapsed time: 2.728s, Critical Path: 1.23s - -Now test your freshly built binary:: - - $ bazel-bin/main/demorgan - -Or alternatively:: - - $ bazel run //main:demorgan - -If you now modify ``Bool.hs`` and rebuild the project, Bazel will -usually only recompile that file. - -Looking at the dependency graph: - -.. digraph:: demorgan - - node [shape=box]; - "//main:demorgan" - "//main:demorgan" -> "//main:base\n//main:Main.hs" - "//main:demorgan" -> "//lib:booleans" - "//lib:booleans" - "//lib:booleans" -> "//lib:Bool.hs" - "//lib:Bool.hs" - "//main:base\n//main:Main.hs" - -You have now built the project with two targets. The ``demorgan`` -target builds one source file and depends on one other target -(``//lib:booleans``), which builds one additional source file. - -Use multiple packages -^^^^^^^^^^^^^^^^^^^^^ - -Let’s now split the project into multiple packages. - -Notice that we actually have two sub-directories, and each contains -a ``BUILD.bazel`` file. Therefore, to Bazel, the workspace contains two -packages, ``lib`` and ``main``. - -Take a look at the ``lib/BUILD.bazel`` file:: - - haskell_library( - name = "booleans", - srcs = ["Bool.hs"], - visibility = ["//main:__pkg__"], - ) - -And at the ``main/BUILD.bazel`` file:: - - haskell_toolchain_library(name = "base") - - haskell_binary( - name = "demorgan", - srcs = ["Main.hs"], - compiler_flags = ["-threaded"], - deps = [":base", "//lib:booleans"], - ) - -As you can see, the ``demorgan`` target in the ``main`` package -depends on the ``booleans`` target in the ``lib`` package (hence the -target label ``//lib:booleans``) - Bazel knows this through the -``deps`` attribute. - -Notice that for the build to succeed, we make the ``//lib:booleans`` -target in ``lib/BUILD.bazel`` explicitly visible to targets in -``main/BUILD.bazel`` using the ``visibility`` attribute. This is because by -default targets are only visible to other targets in the same -``BUILD.bazel`` file. (Bazel uses target visibility to prevent issues such -as libraries containing implementation details leaking into public -APIs.) - -You have built the project as two packages with three targets and -understand the dependencies between them. - -Use labels to reference targets -------------------------------- - -In ``BUILD.bazel`` files and at the command line, Bazel uses *labels* to -reference targets - for example, ``//main:demorgan`` or -``//lib:booleans``. Their syntax is:: - - //path/to/package:target-name - -If the target is a rule target, then ``path/to/package`` is the path -to the directory containing the ``BUILD.bazel`` file, and ``target-name`` is -what you named the target in the ``BUILD.bazel`` file (the ``name`` -attribute). If the target is a file target, then ``path/to/package`` -is the path to the root of the package, and ``target-name`` is the -name of the target file, including its full path. - -When referencing targets within the same package, you can skip the -package path and just use ``//:target-name``. When referencing targets -within the same ``BUILD.bazel`` file, you can even skip the ``//`` workspace -root identifier and just use ``:target-name``. - -Further reading ---------------- - -Congratulations! You now know the basics of building a Haskell project -with Bazel. Next, read up on the most common :ref:`Common Haskell -build use cases <use-cases>`. Then, check out the following: - -* `External Dependencies`_ to learn more about working with local and - remote repositories. - -* The `Build Encyclopedia`_ to learn more about Bazel. - -* The `C++ build tutorial`_ to get started with building C++ - applications with Bazel. - -* The `Java build tutorial`_ to get started with building Java - applications with Bazel. - -* The `Android application tutorial`_ to get started with building - mobile applications for Android with Bazel. - -* The `iOS application tutorial`_ to get started with building mobile - applications for iOS with Bazel. - -Happy building! - -.. note:: This tutorial is adapted from the Bazel `C++ build tutorial`_. - -.. _install Bazel: https://docs.bazel.build/versions/master/install.html -.. _haskell_binary: http://api.haskell.build/haskell/haskell.html#haskell_binary -.. _haskell_toolchain_library: http://api.haskell.build/haskell/haskell.html#haskell_toolchain_library -.. _haskell_library: http://api.haskell.build/haskell/haskell.html#haskell_library -.. _graphviz: https://www.graphviz.org/ -.. _external dependencies: https://docs.bazel.build/versions/master/external.html -.. _build encyclopedia: https://docs.bazel.build/versions/master/be/overview.html -.. _C++ build tutorial: https://docs.bazel.build/versions/master/tutorial/cpp.html -.. _Java build tutorial: https://docs.bazel.build/versions/master/tutorial/java.html -.. _Android application tutorial: https://docs.bazel.build/versions/master/tutorial/android-app.html -.. _iOS application tutorial: https://docs.bazel.build/versions/master/tutorial/ios-app.html |