es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo envuelvo `cc_binary`/`cc_library` en una regla personalizada (¡no en un macro!)?

Para evitar un bug y establecer opciones de compilador específicas de la plataforma, quiero envolver las reglas cc_binary (y cc_library) en una regla personalizada.

No quiero usar una macro, ya que tendría que estructurar mi código de esta manera:

deps = select(
{
“//platforms//os:linux”: deps + [“my-extra-dep”],
“//conditions:default”: deps,
}
)

En cambio, me gustaría estructurar mi código de esta manera:

// verifica si es @platforms//os:linux
if is_linux():
deps = deps + [“my-extra-dep”]
defines = defines + [“custom-define1”, …]

Esto último solo es posible en una regla, donde se pueden consultar los atributos de la plataforma.
En una macro, estaría limitado a hacer una selección de cada atributo individual.

Mi problema está en la plantilla de mi regla personalizada: ¿cuáles deberían ser los atributos para poder transmitir de forma transparente a las reglas nativas cc_binary/cc_library? ¿Estoy pasando por alto una forma fácil de hacer esto que no implique traducir toda la especificación de la interfaz de las reglas cc_* a Starlark?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para envolver cc_binary y cc_library en una regla personalizada, deberás definir los attrs (atributos) de tu regla personalizada. Aquí hay algunos posibles attrs que puedes considerar:

    • name: el nombre de la regla.
    • srcs: la lista de archivos fuente.
    • deps: la lista de dependencias.
    • data: la lista de archivos de datos.
    • copts: la lista de opciones del compilador de C++.
    • defines: la lista de definiciones del preprocesador.
    • linkopts: la lista de opciones del enlazador.
    • linkshared: un booleano que indica si se enlazará el binario con bibliotecas compartidas.
    • linkstatic: un booleano que indica si se enlazará el binario con bibliotecas estáticas.

    Para derivar de manera transparente hacia la regla nativa cc_binary/cc_library, puedes utilizar una llamada ctx.rule() para crear la regla nativa y luego configurar los attrs apropiados en base a las condiciones específicas de la plataforma. Aquí tienes un ejemplo de implementación:

    def _impl(ctx):
        native_rule = ctx.rule(
            implementation = "cc_binary",
            attrs = {
                "name": ctx.attr.name,
                "srcs": ctx.attr.srcs,
                "deps": ctx.attr.deps,
                "data": ctx.attr.data,
                "copts": ctx.attr.copts,
                "defines": ctx.attr.defines,
                "linkopts": ctx.attr.linkopts,
                "linkshared": ctx.attr.linkshared,
                "linkstatic": ctx.attr.linkstatic,
            },
        )
    
        if is_linux():
            native_rule.attr.deps += ["my-extra-dep"]
            native_rule.attr.defines += ["custom-define1"]
    
        return [native_rule]
    
    my_cc_binary = rule(
        implementation = _impl,
        attrs = {
            "name": attr.string(mandatory=True),
            "srcs": attr.label_list(allow_files=True),
            "deps": attr.label_list(),
            "data": attr.label_list(allow_files=True),
            "copts": attr.string_list(),
            "defines": attr.string_list(),
            "linkopts": attr.string_list(),
            "linkshared": attr.bool(default=False),
            "linkstatic": attr.bool(default=False),
        },
    )
    

    En este ejemplo, la native_rule se crea utilizando ctx.rule() con implementation configurado como "cc_binary" y el resto de los attrs se copian de los attrs de la regla personalizada. Luego, los atributos deps y defines se modifican en base a las condiciones específicas de la plataforma. Finalmente, la native_rule se devuelve como una lista de reglas.

    Ten en cuenta que deberás definir la función is_linux() en algún lugar de tu archivo BUILD o en un módulo separado.

Comments are closed.