Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 31 additions & 28 deletions build_defs/cc.build_defs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ def cc_library(name:str, srcs:list=[], hdrs:list=[], private_hdrs:list=[], deps:
['cc:pc:' + lib for lib in pkg_config_libs] +
['cc:pcc:' + cflag for cflag in pkg_config_cflags] +
['cc:inc:' + join_path(pkg_name, include) for include in includes] +
['cc:def:' + define for define in defines] +
labels)

if not srcs and not _interfaces:
Expand Down Expand Up @@ -120,14 +119,14 @@ def cc_library(name:str, srcs:list=[], hdrs:list=[], private_hdrs:list=[], deps:
)
provides = {'cc_hdrs': hdrs_rule}

# TODO(pebers): handle includes and defines in _library_cmds as well.
pre_build = _library_transitive_labels(_c, compiler_flags, pkg_config_libs, pkg_config_cflags) if (deps or includes or defines or _interfaces) else None
# TODO(pebers): handle includes in _library_cmds as well.
pre_build = _library_apply_labels(_c, compiler_flags, pkg_config_libs, pkg_config_cflags, defines) if (deps or includes or _interfaces) else None
pkg = package_name()

if _interfaces:
# Generate the module interface file
xflags = _MODULE_FLAGS + ["--precompile", "-x", "c++-module", "-o", '"$OUT"']
cmds, tools = _library_cmds(_c, compiler_flags + xflags, pkg_config_libs, pkg_config_cflags, archive=False)
cmds, tools = _library_cmds(_c, compiler_flags + xflags, pkg_config_libs, pkg_config_cflags, defines, archive=False)
interface_rule = build_rule(
name = name,
tag = 'interface',
Expand All @@ -147,7 +146,7 @@ def cc_library(name:str, srcs:list=[], hdrs:list=[], private_hdrs:list=[], deps:
else:
all_deps = deps

cmds, tools = _library_cmds(_c, compiler_flags, pkg_config_libs, pkg_config_cflags)
cmds, tools = _library_cmds(_c, compiler_flags, pkg_config_libs, pkg_config_cflags, defines)
if not out:
out = f'{name}.a' if name.startswith('lib') else f'lib{name}.a'
if len(srcs) > 1:
Expand Down Expand Up @@ -296,11 +295,10 @@ def cc_object(name:str, src:str, hdrs:list=[], private_hdrs:list=[], out:str=Non
['cc:pc:' + lib for lib in pkg_config_libs] +
['cc:pcc:' + cflag for cflag in pkg_config_cflags] +
[f'cc:inc:{pkg}/{include}' for include in includes] +
['cc:def:' + define for define in defines] +
labels)
if alwayslink:
labels += ['cc:al:{pkg}/{name}.a']
cmds, tools = _library_cmds(_c, compiler_flags, pkg_config_libs, pkg_config_cflags, archive=False)
cmds, tools = _library_cmds(_c, compiler_flags, pkg_config_libs, pkg_config_cflags, defines, archive=False)

return build_rule(
name=name,
Expand All @@ -314,8 +312,8 @@ def cc_object(name:str, src:str, hdrs:list=[], private_hdrs:list=[], out:str=Non
test_only=test_only,
labels=labels,
tools=tools,
pre_build=_library_transitive_labels(_c, compiler_flags, pkg_config_libs, pkg_config_cflags, archive=False)
if (deps or includes or defines) else None,
pre_build=_library_apply_labels(_c, compiler_flags, pkg_config_libs, pkg_config_cflags, defines, archive=False)
if (deps or includes) else None,
needs_transitive_deps=True,
)

Expand Down Expand Up @@ -821,8 +819,8 @@ def _escape_linker_flag(flag:str):
return "-Wl," + flag.replace(" ", ",")


def _library_cmds(c:bool=False, compiler_flags:list=[], pkg_config_libs:list=[], pkg_config_cflags:list=[], extra_flags:list=[],
archive:bool=True):
def _library_cmds(c:bool=False, compiler_flags:list=[], pkg_config_libs:list=[], pkg_config_cflags:list=[], defines:list=[],
extra_flags:list=[], archive:bool=True):
"""Returns the commands needed for a cc_library rule."""
# Most compilers allow multiple action flags to be specified, with later flags overriding earlier ones. However,
# specifying more than one action is an error (-Wunused-command-line-argument) as of Clang 20, so if the compiler
Expand All @@ -831,8 +829,8 @@ def _library_cmds(c:bool=False, compiler_flags:list=[], pkg_config_libs:list=[],
common_flags = [] if any([cf in _ACTION_FLAGS for cf in compiler_flags]) else ["-c"]

common_flags += ["-I", "."]
dbg_flags = _build_flags(compiler_flags, pkg_config_libs, pkg_config_cflags, c=c, dbg=True)
opt_flags = _build_flags(compiler_flags, pkg_config_libs, pkg_config_cflags, c=c)
dbg_flags = _build_flags(compiler_flags, pkg_config_libs, pkg_config_cflags, defines, c=c, dbg=True)
opt_flags = _build_flags(compiler_flags, pkg_config_libs, pkg_config_cflags, defines, c=c)
cmd_template = '"$TOOLS_PLEASE_CC" cc "$TOOLS_CC" %s ${SRCS_SRCS}'
if archive:
cmd_template += ' && "$TOOLS_ARCAT" ar -r && "$TOOLS_AR" s "$OUT"'
Expand Down Expand Up @@ -891,28 +889,33 @@ def _module_file_flag(module_file:str):
)


def _library_transitive_labels(c:bool=False, compiler_flags:list=[], pkg_config_libs:list=[], pkg_config_cflags:list=[], archive:bool=True):
"""Applies commands from transitive labels to a cc_library rule."""
def apply_transitive_labels(name):
labels = get_labels(name, 'cc:')
def _library_apply_labels(c:bool=False, compiler_flags:list=[], pkg_config_libs:list=[], pkg_config_cflags:list=[],
defines:list=[], archive:bool=True):
"""Extracts options from the labels of dependencies - transitively, in some cases - and adds them to the command of
a cc_library target.
"""
def apply_labels(name):
flags = []
for l in labels:
if l.startswith("inc:"):
flags += ["-isystem", l[4:]]
elif l.startswith("def:"):
flags += ["-D", l[4:]]

pkg_config_libs += [l[3:] for l in labels if l.startswith('pc:') and l[3:] not in pkg_config_libs]
pkg_config_cflags += [l[4:] for l in labels if l.startswith('pcc:') and l[4:] not in pkg_config_cflags]
mods = [_module_file_flag(l[4:]) for l in labels if l.startswith('mod:')]
mods = []
# Only the headers for this library's direct dependencies should be collected - transitive dependencies aren't
# needed at compile time, and just pollute the build environment.
for l in get_labels(name, "cc:inc:", maxdepth=1):
flags += ["-isystem", l]
for l in get_labels(name, "cc:"):
if l.startswith("pc:") and l[3:] not in pkg_config_libs:
pkg_config_libs += [l[3:]]
elif l.startswith("pcc:") and l[4:] not in pkg_config_cflags:
pkg_config_cflags += [l[4:]]
elif l.startswith("mod:"):
mods += [_module_file_flag(l[4:])]
flags += mods
if mods:
flags += _MODULE_FLAGS
if flags: # Don't update if there aren't any relevant labels
cmds, _ = _library_cmds(c, compiler_flags, pkg_config_libs, pkg_config_cflags, flags, archive=archive)
cmds, _ = _library_cmds(c, compiler_flags, pkg_config_libs, pkg_config_cflags, defines, flags, archive=archive)
for k, v in cmds.items():
set_command(name, k, v)
return apply_transitive_labels
return apply_labels


def _binary_transitive_labels(c:bool=False, linker_flags:list=[], pkg_config_libs:list=[], strip:bool=None, shared:bool=False,
Expand Down
9 changes: 9 additions & 0 deletions test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,12 @@ plugin_e2e_test(
"file": "executable" if CONFIG.TARGET_OS == "darwin" else "statically linked",
},
)

plugin_e2e_test(
name = "transitive_deps_test",
repo = "transitive_deps_repo",
test_cmd = "plz run //:binary > out",
expected_output = {
"out": "one=1 one_plus_one=2",
},
)
19 changes: 0 additions & 19 deletions test/labels/BUILD

This file was deleted.

Empty file removed test/labels/another_lib.cpp
Empty file.
3 changes: 0 additions & 3 deletions test/labels/lib1/include/lib.hpp

This file was deleted.

9 changes: 0 additions & 9 deletions test/labels/lib_test.cpp

This file was deleted.

2 changes: 2 additions & 0 deletions test/transitive_deps_repo/.plzconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Plugin "cc"]
Target = //plugins:cc
9 changes: 9 additions & 0 deletions test/transitive_deps_repo/BUILD_FILE
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
subinclude("///cc//build_defs:c")

c_binary(
name = "binary",
srcs = ["binary.c"],
deps = [
"//one",
],
)
16 changes: 16 additions & 0 deletions test/transitive_deps_repo/binary.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <stdio.h>

#include "one.h"

#ifdef BUILDING_LIBONE
#error "BUILDING_LIBONE should not be defined"
#endif

#ifdef BUILDING_LIBTWO
#error "BUILDING_LIBTWO should not be defined"
#endif

int main() {
printf("one=%d one_plus_one=%d\n", one(), one_plus_one());
return 0;
}
16 changes: 16 additions & 0 deletions test/transitive_deps_repo/one/BUILD_FILE
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
subinclude("///cc//build_defs:c")

c_library(
name = "one",
srcs = ["one.c"],
hdrs = ["one.h"],
private_hdrs = ["one_private.h"],
defines = ["BUILDING_LIBONE"],
includes = ["."],
visibility = [
"//:binary",
],
deps = [
"//two",
],
)
19 changes: 19 additions & 0 deletions test/transitive_deps_repo/one/one.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "one.h"
#include "two.h"
#include "one_private.h"

#ifndef BUILDING_LIBONE
#error "BUILDING_LIBONE should be defined"
#endif

#ifdef BUILDING_LIBTWO
#error "BUILDING_LIBTWO should not be defined"
#endif

int one() {
return ONE_INT;
}

int one_plus_one() {
return two();
}
3 changes: 3 additions & 0 deletions test/transitive_deps_repo/one/one.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int one();

int one_plus_one();
9 changes: 9 additions & 0 deletions test/transitive_deps_repo/one/one_private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef BUILDING_LIBONE
#error "BUILDING_LIBONE should be defined"
#endif

#ifdef BUILDING_LIBTWO
#error "BUILDING_LIBTWO should not be defined"
#endif

#define ONE_INT 1
4 changes: 4 additions & 0 deletions test/transitive_deps_repo/plugins/BUILD_FILE
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
plugin_repo(
name = "cc",
revision = "e2e",
)
13 changes: 13 additions & 0 deletions test/transitive_deps_repo/two/BUILD_FILE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
subinclude("///cc//build_defs:c")

c_library(
name = "two",
srcs = ["two.c"],
hdrs = ["two.h"],
private_hdrs = ["two_private.h"],
defines = ["BUILDING_LIBTWO"],
includes = ["."],
visibility = [
"//one",
],
)
10 changes: 10 additions & 0 deletions test/transitive_deps_repo/two/two.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "two.h"
#include "two_private.h"

#ifndef BUILDING_LIBTWO
#error "BUILDING_LIBTWO should be defined"
#endif

int two() {
return TWO_INT;
}
1 change: 1 addition & 0 deletions test/transitive_deps_repo/two/two.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int two();
5 changes: 5 additions & 0 deletions test/transitive_deps_repo/two/two_private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#ifndef BUILDING_LIBTWO
#error "BUILDING_LIBTWO should be defined"
#endif

#define TWO_INT 2