lien entre bibliothèques via CMake et usage de INTERFACE dans la commande target_link_libraries()

comment se représenter les liens lors de l'usage du mot-clé INTERFACE

a marqué ce sujet comme résolu.

Salut à tous et à toutes, :)

je débute avec l’outil CMake et actuellement, j’ai un souci de compréhension des mots-clés INTERFACE, PUBLIC ET PRIVATE avec l’utilisation de la commande target_link_libraries().

Pour la mise en situation, j’ai un projet structuré de la minière suivante :

Test
  |--build
  |--Headers
      |-- calcul.h
      |-- printer.h
  |--Headers
      |-- calcul.cpp
      |-- printer.cpp
      |-- main.cpp
  |--CMakeLists.txt

Le contenu de main.cpp comme suit

#include "printer.h"
#include <iostream>

int main(){
    print_hello_world();
    print_add();
    return 0;
}

Celui de calcul.h

#ifndef __CALCUL_H__
#define __CALCUL_H__

int add(int , int);

#endif

Celui de calcul.cpp

#include "calcul.h"

int add(int a, int b){
    return a+b;
}

Celui de printer.h

#ifndef HELLO_WORLD_PRINTER_H
#define HELLO_WORLD_PRINTER_H

void print_hello_world();
void print_add();

#endif // HELLO_WORLD_PRINTER_H

Celui de printer.cpp

#include <iostream>
#include "calcul.h"

void print_hello_world() {
    std::cout << "Hello World!" << std::endl;
}

void print_add(){
    std::cout<<"8 + 3 = " << add(8,3)<< std::endl;
}

Et le script CMake est le suivant :

cmake_minimum_required(VERSION 3.9...3.30.0)

if(${CMAKE_VERSION} VERSION_LESS 3.12)
    cmake_policy(VERSION ${CMAKE_VERSION})
endif()

project(Cmake_test VERSION 0.1.0 DESCRIPTION "Test Bib" LANGUAGES CXX)

add_library( math_bib STATIC Sources/calcul.cpp )
target_include_directories(math_bib PRIVATE Headers)

add_library( print_bib  STATIC Sources/printer.cpp )
target_include_directories( print_bib PUBLIC Headers)

target_link_libraries(print_bib INTERFACE math_bib )

add_executable(my_exe Sources/main.cpp )
set_target_properties( my_exe
    PROPERTIES 
        CXX_STANDARD 17 
        CXX_STANDARD_REQUIRED ON )
target_include_directories(my_exe PRIVATE Headers)
target_link_libraries(my_exe PUBLIC print_bib
    #PUBLIC math_bib # mettre cette ligne si la commande target_link_libraries() avec pour cible print_bib n'est pas présente
)


Dans un projet de test, je cherche à lier la bibliothèque print_lib à l’exécutable my_exe. La bibliothèque print_lib dépend d’une autre bibliothèque (math_lib) et pour cela, je cherche également à lier la seconde bibliothèque (math_lib) à la première (print_lib). Le script CMake s’exécute sans avertissement et j’arrive à obtenir les bibliothèques ainsi que l’exécutable.
Je ne comprends pas pourquoi cela fonctionne. Mon raisonnement est le suivant : à la ligne 15, je "lie" la bibliothèque math_lib à la bibliothèque print_lib et j’utilise le mot-clé INTERFACE. Avec le mot-clé INTERFACE, la bibliothèque print_lib ne devrait pas pouvoir utiliser les fonctionnalités de la bibliothèque math_lib. Ces fonctionnalités devraient plutôt, grâce à la ligne 23, être utilisable par l’exécutable my_exe dans le code source main.cpp . Par conséquent, la bibliothèque print_lib ne devrait donc pas être utile à l’exécutable, qui lui ne devrait donc pas pouvoir être produit.

J’aimerais savoir, s’il vous plaît

  • ce qui est faux dans mon raisonnement et, par cela pourquoi tout fonctionne.
  • à quel moment est-ce que le lien est fait entre les bibliothèques à travers la commande target_link_libraries().

Merci d’avance pour vos retours.

Salut, Ce qui fait que ça fonctionne, c’est qu’en C++, tant que tu as accès à la déclaration dans le .h (grâce à la ligne 13 puisque tous tes headers sont dans le même dossier ce qui n’est effectivement pas représentatif d’une situation réelle de plusieurs bibliothèques), la phase de compilation (qui génère des .o/.obj et des .a/.lib) va se passer à merveille.

Enfin la phase du linker (qui rassemble tout ça dans un .exe) va chercher l’implémentation de add() n’importe où où c’est possible dans tout ce qu’on lui a demandé de rassembler (.o/.obj et .a/.lib).

D’où l’importance en C++ des namespace pour s’assurer qu’on confond pas n’importe quoi à cette étape…

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte