cmake undefined reference de fonction

La structure du projet ci-dessous est un exemple simplifié. J'ai essayé de la faire bouillir pour le montant minimal de fichiers à reproduire mon problème.

.
├── CMakeLists.txt
├── subdir1
│   ├── CMakeLists.txt
│   └── subsubdir1
│       ├── CMakeLists.txt
│       ├── Example.cpp
│       └── Example.h
└── subdir2
    ├── CMakeLists.txt
    ├── main.cpp
    └── subsubdir1
        ├── CMakeLists.txt
        ├── ExampleCreator.cpp
        └── ExampleCreator.h

./CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(test)

macro(add_sources)
    file (RELATIVE_PATH _relPath "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
    foreach (_src ${ARGN})
        if (_relPath)
            list (APPEND SRCS "${_relPath}/${_src}")
        else()
            list (APPEND SRCS "${_src}")
        endif()
    endforeach()
    if (_relPath)
        # propagate SRCS to parent directory
        set (SRCS ${SRCS} PARENT_SCOPE)
    endif()
endmacro()

add_subdirectory(subdir1)
add_subdirectory(subdir2)

add_executable(test ${SRCS})

subdir1/CMakeLists.txt

add_subdirectory(subsubdir1)

subdir1/subsubdir1/CMakeLists.txt

add_sources(Example.cpp)

subdir1/subsubdir1/Exemple.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

class Example
{
public:
    Example();
    virtual ~Example();
};

#endif

subdir1/subsubdir1/Example.cpp

#include <stdio.h>
#include "Example.h"

Example::Example()
{
    printf("Inside Example constructor\n");
}

Example::~Example()
{
}

subdir2/CMakeLists.txt

add_subdirectory(subsubdir1)
add_sources(main.cpp)

subdir2/main.cpp

#include "subsubdir1/ExampleCreator.h"

int main(int argc, char** argv)
{
    ExampleCreator creator;
    return 0;
}

subdir2/subsubdir1/CMakeLists.txt

add_sources(ExampleCreator.cpp)

subdir2/subsubdir1/ExampleCreator.h

#ifndef EXAMPLE_CREATOR_H
#define EXAMPLE_CREATOR_H

class ExampleCreator
{
public:
    ExampleCreator();
    virtual ~ExampleCreator();
};

#endif

subdir2/subsubdir1/ExampleCreator.cpp

#include "ExampleCreator.h"
#include "../../subdir1/subsubdir1/Example.h"

ExampleCreator::ExampleCreator()
{
    Example* ex1 = new Example();
}

ExampleCreator::~ExampleCreator()
{
}

J'espère que c'est vraiment un simple manque de compréhension de la façon de CMake gère les dépendances. Cette compile sans erreur, mais échoue lors de la liaison. Le make de sortie ci-dessous montre que Example.cpp n'est même pas de la compilation et je ne comprends pas pourquoi.

user>:~/src/test/build$ make
Scanning dependencies of target test
[ 50%] Building CXX object CMakeFiles/test.dir/subdir2/subsubdir1/ExampleCreator.cpp.o
[100%] Building CXX object CMakeFiles/test.dir/subdir2/main.cpp.o
Linking CXX executable test
CMakeFiles/test.dir/subdir2/subsubdir1/ExampleCreator.cpp.o: In function `ExampleCreator::ExampleCreator()':
ExampleCreator.cpp:(.text+0x2b): undefined reference to `Example::Example()'
collect2: ld returned 1 exit status
make[2]: *** [test] Error 1
make[1]: *** [CMakeFiles/test.dir/all] Error 2
make: *** [all] Error 2

Toutes les sources sont ajoutées à la SRCS variable dans la racine CMakeLists.txt fichier à partir de ce que je peux dire. Alors, pourquoi n'est-ce pas Example.cpp arriver compilé? ou sont-elles liées?

OriginalL'auteur E-rich | 2012-10-24