summaryrefslogtreecommitdiff
path: root/doc/consume-cmake-libraries.org
blob: 4aa75b6d3fcb90ae52e7dce862956121c181b0ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
* Consume CMake Libraries

To support libraries built with CMake to be consumed by JustBuild, the rule
~["CC/foreign/cmake", "library"]~ can be used. This rule will run CMake and
collect the library's artifacts, public headers, and pkg-config files (if
available), to produce a proper JustBuild library target.

In this example, we show how to consume the ~gtest~ library built with CMake
using JustBuild.

** Example: Build the ~gtest~ Library with CMake

First make sure that ~just~, ~just-mr~, and ~just-import-git~ are available in
your ~PATH~. Then, define a new workspace by creating a ~ROOT~ marker.

#+BEGIN_SRC sh
$ touch ROOT
#+END_SRC

To define a repository for the
[[https://github.com/google/googletest/tree/v1.13.0][gtest]] library, create the
following ~repos.template.json~ file.

#+SRCNAME: repos.template.json
#+BEGIN_SRC js
{ "main": "tests"
, "repositories":
  { "imports": {"repository": {"type": "file", "path": "imports"}}
  , "gtest":
    { "repository":
      { "type": "git"
      , "branch": "v1.13.0"
      , "commit": "b796f7d44681514f58a683a3a71ff17c94edb0c1"
      , "repository": "https://github.com/google/googletest"
      }
    , "target_root": "imports"
    , "target_file_name": "gtest.TARGETS"
    , "bindings": {"rules": "rules-cc"}
    }
  , "tests":
    { "repository": {"type": "file", "path": "."}
    , "bindings": {"rules": "rules-cc", "gtest": "gtest"}
    }
  }
}
#+END_SRC

Now the missing ~rules-cc~ repository can be imported via:

#+BEGIN_SRC sh
$ just-import-git -C repos.template.json --as rules-cc -b master https://github.com/just-buildsystem/rules-cc > repos.json
$
#+END_SRC

Create the file ~imports/gtest.TARGETS~ with the following content.

#+SRCNAME: imports/gtest.TARGETS
#+BEGIN_SRC js
{ "gtest_main":
  { "type": ["@", "rules", "CC/foreign/cmake", "library"]
  , "name": ["gtest_main"]
  , "version": ["1", "13", "0"]
  , "project": [["TREE", null, "."]]
  , "defines": ["BUILD_SHARED_LIBS=ON"]
  , "out_hdr_dirs": ["gtest"]
  , "out_libs": ["libgtest_main.so.1.13.0", "libgtest.so.1.13.0"]
  , "pkg-config": ["gtest_main.pc", "gtest.pc"]
  }
}
#+END_SRC

The library ~gtest_main~ uses the rule ~["CC/foreign/cmake", "library"]~. It
sets ~defines~ to build shared libraries and collects the public header
directory ~gtest~, as well as the two libraries ~libgtest_main.so.1.13.0~ and
~libgtest.so.1.13.0~ (in this particular link order). Furthermore, to
automatically infer public compile and link flags (e.g., a link dependency to
the system's ~pthread~ library), the pkg-config files ~gtest_main.pc~ and
~gtest.pc~ are read, with the former (entry point) depending on the latter.

Now, create the actual ~test~ target, which consumes the ~gtest_main~ library,
by creating the following ~TARGETS~ file.

#+SRCNAME: TARGETS
#+BEGIN_SRC js
{ "test":
  { "type": ["@", "rules", "CC/test", "test"]
  , "name": ["test"]
  , "srcs": ["test.cpp"]
  , "private-deps": [["@", "gtest", "", "gtest_main"]]
  }
}
#+END_SRC

The last file missing yet is the actual test source file ~test.cpp~.

#+SRCNAME: test.cpp
#+BEGIN_SRC cpp
#include <gtest/gtest.h>

TEST(CastTest, double) {
  EXPECT_EQ (42.0, double(42));
}
#+END_SRC

Finally, build the ~test~ target to run the test.

#+BEGIN_SRC sh
$ just-mr build test -Pstdout
INFO: Requested target is [["@","tests","","test"],{}]
INFO: Analysed target [["@","tests","","test"],{}]
INFO: Export targets found: 0 cached, 0 uncached, 0 not eligible for caching
INFO: Target tainted ["test"].
INFO: Discovered 7 actions, 2 trees, 3 blobs
INFO: Building [["@","tests","","test"],{}].
INFO: Processed 7 actions, 0 cache hits.
INFO: Artifacts built, logical paths are:
        result [7ef22e9a431ad0272713b71fdc8794016c8ef12f:5:f]
        stderr [8b137891791fe96927ad78e64b0aad7bded08bdc:1:f]
        stdout [fc46e9e95a8a393e3c94875d66b0de956305f6a6:728:f]
        time-start [93887fee067665917f67e2cb757dd30bf22b23a0:11:f]
        time-stop [93887fee067665917f67e2cb757dd30bf22b23a0:11:f]
      (1 runfiles omitted.)
Running main() from src/gtest_main.cc
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from CastTest
[ RUN      ] CastTest.double
[       OK ] CastTest.double (0 ms)
[----------] 1 test from CastTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

INFO: Target tainted ["test"].
$
#+END_SRC