Ninja: Las rutas subninja relativas no se resuelven

Creado en 21 jun. 2015  ·  8Comentarios  ·  Fuente: ninja-build/ninja

Intentaría un PR para esto, pero no estoy completamente seguro de que sea un error o si es intencionado.

Al incluir un subninja, obtengo

ninja: error: 'mod.c', necesario para 'mod.o', falta y no se conoce ninguna regla para hacerlo

aunque ejecutar ninja directamente en ese directorio funciona bien. Bajo la sospecha de que las rutas relativas pueden ser las culpables, copié la estructura del proyecto en un nuevo directorio, antepuse cada entrada/salida con la ruta absoluta y ejecuté ninja desde el directorio principal (que contiene el build.ninja que subninja 'd el módulo). Se construyó muy bien.

¿Sugiere esto que deberíamos generar nuestras configuraciones ninja con rutas absolutas? Esto tiene muchos problemas, además del hecho de que no todos los generadores que he visto hacen esto. Además, la documentación no hace ninguna distinción y, de lo contrario, Ninja funciona bien.

Quiero equivocarme por el lado de _es un error_, pero siento que un PR que realiza la canonicalización de la ruta de tiempo de ejecución podría introducir un impacto en el rendimiento (aunque estoy agitando mis manos aquí sin ningún punto de referencia para respaldar esa sospecha).

Comentario más útil

No estoy seguro de entender. Los subninjas, en el caso de uso que he descrito en particular, normalmente no conocen la estructura del ninja principal (al menos, no necesitan saberlo). Sin embargo, estoy seguro de que alguien podría encontrar un caso en el que lo hagan.

El problema al que me enfrento en este momento es que las dependencias (bibliotecas de terceros, etc.) que no usan mi generador (que es el 100% de ellos) actualmente deben construirse usando un programa previo, y deben reiniciarse cada vez que están actualizados o cambiados, etc. La mayoría de los generadores con los que trabajo tienen las opciones para generar una configuración ninja, pero todos están configurados solo para ese directorio (es decir, en relación con ese directorio).

Ser capaz de realizar reconstrucciones selectivas utilizando sus configuraciones y gráficos sería enorme. Actualmente, no puedo hacer esto debido al hecho de que subninja asume rutas relativas al directorio de compilación.

Todos 8 comentarios

Todas las rutas son relativas al directorio de compilación, no al archivo que contiene la línea subninja.

Sin embargo, eso no tiene sentido. Eso significa que los generadores tendrán que _todos_ implementar alguna forma de anteponer un prefijo a los archivos, lo que significa cambiar los comandos del directorio de trabajo que se ejecutan (lo que puede cambiar la intención original de la configuración de compilación dependiendo de cómo se ejecuten el generador/comandos).

Entonces, ¿cuáles son los casos de uso contrastantes para subninja frente a include ?

Un subninja con rutas relativas al archivo de compilación sería útil en el sentido de que las dependencias que están configuradas para ejecutarse dentro de su propio directorio pueden hacerlo sin tener que modificar sus rutas, pero aun así pueden contribuir al gráfico de dependencias de la configuración ninja principal.

La funcionalidad include no se modificaría y actuaría exactamente como actúan los subninjas, aparte de que los nombres de las reglas de hechos ahora estarían en un espacio de nombres combinado (según #921). Actualmente, subninja y include logran esencialmente lo mismo además de definir el alcance de las variables y los nombres de las reglas...

La idea es que el generador genere todos los archivos .ninja, para que puedan escribir rutas relativas al directorio de compilación. Es una idea interesante combinar archivos ninja generados por diferentes generadores (¿parece que eso es lo que quieres hacer?), pero eso no es algo que se admita en este momento.

Correcto, la diferencia entre subninja y include es que el primero agrega un alcance y el segundo no. El caso de uso para esto es que el ninja de nivel superior puede definir reglas de compilación comunes, como cc, que hacen referencia a variables como cflags , y cada subninja puede establecer cflags en lo que sea apropiado para ese objetivo, y allí puede haber acciones únicas allí. Para ver un ejemplo, puede ejecutar python misc/write_fake_manifests.py /tmp/foo` para escribir un montón de archivos .ninja en /tmp/foo que usan este patrón.

Eso tiene sentido, aunque todavía no veo mucho beneficio (aparte del alcance).

Es una idea interesante combinar archivos ninja generados por diferentes generadores (¿parece que eso es lo que quieres hacer?)

Exactamente. Ser capaz de incluir el propio Ninja como un submódulo para mi generador, y luego otro proyecto CMake (que está configurado para generar archivos de compilación Ninja), y luego generar los archivos de configuración Ninja para ambos e incluirlos como subninja s en El archivo build.ninja _my_ project para poder compilarlos como si fueran independientes, pero permitir que mi proyecto use sus resultados (y, por lo tanto, sus gráficos de dependencia) para compilar todo el proyecto a la vez .

Si eso tiene sentido. El caso de uso inmediato que veo con mi generador en particular es que está tomando prestados algunos conceptos de Tup (que el IIRC influyó en algunas decisiones de diseño dentro de Ninja) en el sentido de que puedo incluir N subproyectos, todos con sus propios build.ninja y luego toque sus gráficos para permitirme construir automáticamente un gráfico de dependencia mucho más grande.

Personalmente, creo que eso haría que subninja fuera mucho más útil, aunque podría ver que es un cambio potencialmente importante. Sin embargo, no veo una forma de evitar esto a menos que 1) modifique los archivos build.ninja las dependencias con un parche o 2) sacrifique la capacidad de aprovechar los gráficos de dependencia de las dependencias.

¿Pensamientos?

Qué tal si:

subninja path/to/build.ninja relative path/to

y un relative ausente por defecto es ./ . Eso haría que no se rompa, pero aún así daría la funcionalidad si un generador así lo desea.

O, siguiendo los pasos de otras construcciones Ninja, tal vez

subninja path/to/build.ninja
  relative = path/to

Suponga que tiene un proyecto en .../foo y tiene una barra de subdirectorios, y que Ninja tiene la lógica de ruta relativa que sugiere.

Si su sistema de compilación quiere escribir todas las salidas de compilación en /foo/obj, un subninja en /foo/bar que usa rutas relativas al directorio necesitaría saber escribir su salida en ../obj/bar, ya que esa es la ruta a el archivo de ese subdirectorio. Por lo tanto, lo que sea que esté generando sus archivos build.ninja ya debe conocer la jerarquía de ruta global, en cuyo caso hacer que todas las rutas sean relativas es efectivamente el mismo problema que anteponer una barra/ a las rutas en el directorio bar/.

Sin embargo, tal vez haya suficientes personas que escriban la salida de compilación en sus directorios de origen como para que lo anterior no importe. Principalmente escucho de personas que quieren una separación aún más fuerte, como las personas que enviaron parches a Ninja para que puedan construir Ninja con la salida de compilación en un directorio totalmente no relacionado.

No estoy seguro de entender. Los subninjas, en el caso de uso que he descrito en particular, normalmente no conocen la estructura del ninja principal (al menos, no necesitan saberlo). Sin embargo, estoy seguro de que alguien podría encontrar un caso en el que lo hagan.

El problema al que me enfrento en este momento es que las dependencias (bibliotecas de terceros, etc.) que no usan mi generador (que es el 100% de ellos) actualmente deben construirse usando un programa previo, y deben reiniciarse cada vez que están actualizados o cambiados, etc. La mayoría de los generadores con los que trabajo tienen las opciones para generar una configuración ninja, pero todos están configurados solo para ese directorio (es decir, en relación con ese directorio).

Ser capaz de realizar reconstrucciones selectivas utilizando sus configuraciones y gráficos sería enorme. Actualmente, no puedo hacer esto debido al hecho de que subninja asume rutas relativas al directorio de compilación.

Evan: La forma en que entendí esto es que crearías un árbol como este:

  subbuild1
  subbuild2

y dado que los generadores generalmente admiten colocar el directorio de compilación en lugares arbitrarios, la construcción del proyecto 1 en la subconstrucción 1 y el proyecto 2 en la subconstrucción 2 deberían funcionar. Luego hay un archivo ninja de nivel superior en builddir que Qix quiere manejar para construir los subproyectos.

Sin relación: esta característica relative también tiene que cambiar el cwd a su argumento si alguna regla depende de que el directorio actual sea igual a su directorio de compilación (por ejemplo, si una regla elimina los artefactos construidos o algo así).

¿Fue útil esta página
0 / 5 - 0 calificaciones