Commit 1f158eff authored by Wez Furlong's avatar Wez Furlong Committed by Facebook Github Bot

fbcode_builder: getdeps: add CMakeBuilder

Summary:
the cmake builder knows how to use cmake to configure a build
for (preferably) and out-of-src build.  The `cmake.defines` section of
the manifest is used to pass `-Dkey=value` options to the cmake configure
command line.

We prefer to use `ninja` to execute the build so that we can use more
cores than 1 on Windows and just for consistency across platforms
with mac and linux.

Reviewed By: simpkins

Differential Revision: D14690998

fbshipit-source-id: 8102e8b4a47da515ca001772788ed0e5f2645ad7
parent 840ee5bb
......@@ -10,8 +10,9 @@ from __future__ import absolute_import, division, print_function, unicode_litera
import glob
import os
import shutil
from .envfuncs import Env, add_path_entry
from .envfuncs import Env, add_path_entry, path_search
from .runcmd import run_cmd
......@@ -142,3 +143,80 @@ class AutoconfBuilder(BuilderBase):
self._run_cmd(configure_cmd, env=env)
self._run_cmd(["make", "-j%s" % self.build_opts.num_jobs], env=env)
self._run_cmd(["make", "install"], env=env)
class CMakeBuilder(BuilderBase):
def __init__(
self, build_opts, ctx, manifest, src_dir, build_dir, inst_dir, defines
):
super(CMakeBuilder, self).__init__(
build_opts, ctx, manifest, src_dir, build_dir, inst_dir
)
self.defines = defines or {}
def _invalidate_cache(self):
for name in ["CMakeCache.txt", "CMakeFiles"]:
name = os.path.join(self.build_dir, name)
if os.path.isdir(name):
shutil.rmtree(name)
elif os.path.exists(name):
os.unlink(name)
def _needs_reconfigure(self):
for name in ["CMakeCache.txt", "build.ninja"]:
name = os.path.join(self.build_dir, name)
if not os.path.exists(name):
return True
return False
def _build(self, install_dirs, reconfigure):
reconfigure = reconfigure or self._needs_reconfigure()
defines = {
"CMAKE_INSTALL_PREFIX": self.inst_dir,
"BUILD_SHARED_LIBS": "OFF",
# Some of the deps (rsocket) default to UBSAN enabled if left
# unspecified. Some of the deps fail to compile in release mode
# due to warning->error promotion. RelWithDebInfo is the happy
# medium.
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
}
defines.update(self.defines)
define_args = ["-D%s=%s" % (k, v) for (k, v) in defines.items()]
# if self.build_opts.is_windows():
# define_args += ["-G", "Visual Studio 15 2017 Win64"]
define_args += ["-G", "Ninja"]
# CMAKE_PREFIX_PATH is only respected when passed through the
# environment, so we construct an appropriate path to pass down
env = self.env.copy()
for d in install_dirs:
add_path_entry(env, "CMAKE_PREFIX_PATH", d)
add_path_entry(env, "PKG_CONFIG_PATH", "%s/lib/pkgconfig" % d)
bindir = os.path.join(d, "bin")
add_path_entry(env, "PATH", bindir, append=False)
# Resolve the cmake that we installed
cmake = path_search(env, "cmake")
if reconfigure:
self._invalidate_cache()
self._run_cmd([cmake, self.src_dir] + define_args, env=env)
self._run_cmd(
[
cmake,
"--build",
self.build_dir,
"--target",
"install",
"--config",
"Release",
"-j",
str(self.build_opts.num_jobs),
],
env=env,
)
......@@ -10,7 +10,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera
import io
from .builder import AutoconfBuilder, MakeBuilder
from .builder import AutoconfBuilder, CMakeBuilder, MakeBuilder
from .expr import parse_expr
from .fetcher import (
ArchiveFetcher,
......@@ -312,4 +312,10 @@ class ManifestParser(object):
build_options, ctx, self, src_dir, build_dir, inst_dir, args
)
if builder == "cmake":
defines = self.get_section_as_dict("cmake.defines", ctx)
return CMakeBuilder(
build_options, ctx, self, src_dir, build_dir, inst_dir, defines
)
raise KeyError("project %s has no known builder" % (self.name))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment