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.

Iterar el grafo de dependencias en CMake para generar una lista de archivos de bibliotecas de enlaces utilizadas para CGO.

Quiero iterar sobre todas las bibliotecas de enlace de un objetivo objetivo para construir una lista de todos los binarios de bibliotecas (bibliotecas estáticas) a las que enlaza el objetivo, por ejemplo:

cmake
add_executable(exe main.cpp)
target_link_libraries(exe fmt::fmt otherExe)

Deseamos una lista de todos los archivos binarios de bibliotecas (usando $<TARGET_LINKER_FILE:tgt>) para los objetivos dependientes fmt::fmt y otherExe para generar el archivo CGO interface.go apropiado con CFLAGS y LDFLAGS.

El problema es que es difícil escribir un bucle en CMake para iterar sobre las dependencias de enlace del objetivo ya que las propiedades como LINK_LIBRARIES e INTERFACE_LINK_LIBRARIES son en general listas pero pueden contener expresiones generadoras, como en el caso del objetivo de biblioteca de interfaz fmt::fmt que proviene de Conan donde INTERFACE_LINK_LIBRARIES se resuelve como $<$<CONFIG:Release>:CONAN_LIB::fmt_fmt_RELEASE;>, que contiene un punto y coma “";"” que luego se trata como una lista con $<$<CONFIG:Release>:CONAN_LIB::fmt_fmt_RELEASE; y >.

Esto se debe a que Conan agrega lo siguiente:

cmake
set_property(TARGET fmt::fmt
PROPERTY INTERFACE_LINK_LIBRARIES
$<$<CONFIG:Release>:${fmt_LIBRARIES_TARGETS_RELEASE}
${fmt_OBJECTS_RELEASE}> APPEND)

¿Alguien tiene una solución para esto?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Una posible solución es utilizar las propiedades LINK_LIBRARIES e INTERFACE_LINK_LIBRARIES de cada objetivo dependiente de forma recursiva hasta que se hayan recopilado todas las bibliotecas de enlace. Aquí está la función de CMake get_target_link_libraries que hace esto:

    function(get_target_link_libraries target libs)
      get_target_property(deps ${target} LINK_LIBRARIES)
      get_target_property(intf_deps ${target} INTERFACE_LINK_LIBRARIES)
      set(all_libs ${deps} ${intf_deps})
      foreach(lib ${all_libs})
        if(TARGET ${lib})
          get_target_property(type ${lib} TYPE)
          if(${type} STREQUAL "STATIC_LIBRARY")
            get_target_property(lib_file ${lib} LINKER_LANGUAGE)
            if(${lib_file} STREQUAL "C")
              get_target_property(lib_file ${lib} TARGET_LINKER_FILE_C)
            else()
              get_target_property(lib_file ${lib} TARGET_LINKER_FILE)
            endif()
            list(APPEND ${libs} ${lib_file})
          else()
            get_target_link_libraries(${lib} ${libs})
          endif()
        endif()
      endforeach()
    endfunction()
    

    Puedes usar esta función en tu proyecto de CMake de la siguiente manera:

    add_executable(exe main.cpp)
    target_link_libraries(exe fmt::fmt otherExe)
    
    set(all_libs "")
    get_target_link_libraries(exe all_libs)
    
    message("Todas las bibliotecas de enlace: ${all_libs}")
    

    Esto mostrará una lista de todos los archivos binarios de bibliotecas enlazadas a exe. Puedes usar esta lista para generar el archivo interface.go de CGO correspondiente con CFLAGS y LDFLAGS apropiados.

Comments are closed.