-1

Имеется проект с подобной структурой:

include
  | foo
      | first_foo.h
      | second_foo.h
  | bar
      | first_bar.h
      | second_bar.h
src
  | foo
      | first_foo.cpp
      | second_foo.cpp
  | bar
      | first_bar.cpp
      | second_bar.cpp
      | main.cpp
СMakeList.txt

Сам CMakeList.txt выглядит следующим образом:

cmake_minimum_required(VERSION 3.0.0)
project(FooBar VERSION 0.1.0)

include_directories("./include")
include_directories("./include/foo")
include_directories("./include/bar")

aux_source_directory("./src/foo" FOO)
aux_source_directory("./src/bar" BAR)

add_executable(${PROJECT_NAME} ${FOO} ${BAR})

main.cpp:

#include "first_foo.h"
#include "second_foo.h"
#include "first_bar.h"
#include "second_bar.h"
using namespace tests;

int main()
{
    from_first_foo();
    from_second_foo();
    from_first_bar();
    from_second_bar();
    return 0;
}

Проблема в том, что при таких параметрах компилятор выдаёт ошибку:

undefined reference to 'tests::from_first_foo()'
undefined reference to 'tests::from_second_foo()'
undefined reference to 'tests::from_first_bar()'
undefined reference to 'tests::from_second_bar()'

То есть, я так понимаю, что он не может найти файлы реализации. Как сделать так, чтобы он их увидел? Заранее спасибо за ответ.

  • использование cmake версии 3.0.0 обязательное условие? – Andrej Levkovitch Apr 06 '20 at 14:13
  • лучше не использовать функции вроде aux_source_directory или file glob - это будет приводит к проблемам, например в случае переключения между ветками с разным содержимым и т.п. Лучше вручную прописывать source файлы - это самый надежный способ – Andrej Levkovitch Apr 06 '20 at 14:19
  • Версия CMake не принципиальна. Вручную же прописывать каждый файл, как мне кажется, уж слишком неэффективно по времени. Да, понятное дело, если проект маленький. А если он содержит в себе, например, 100 классов, где каждый реализован в отдельном файле (возьмем, что каждый класс в проекте достаточно объемный и раскидывание каждого в отдельный файл - вполне оправданная затея)? – Blooderino Apr 07 '20 at 15:22
  • даже в этом случае это оправданная затея. Во-первых вы запишите их всего один раз. Во-вторых, как ни парадоксально, чем больше проект, тем больше вы будете испытывать проблем с glob объявлениями. Это связано с тем, что чем больше проект, тем чаще вам нужно переключаться между ветками, над проектом и людей работает больше. Из-за этого и проблем будет возникать больше – Andrej Levkovitch Apr 07 '20 at 16:13
  • если версия не принципиальна, то порекомендую использовать 3.5 и выше и вручную прописать сырцы - если это не поможет, то проблема может быть только в коде – Andrej Levkovitch Apr 07 '20 at 16:15

1 Answers1

1

У проблемы одна из двух причин:

  • либо tests::from_first_foo() и т.д. действительно ни где не реализованы. О причинах и о том как устранить см. основной ответ: Ссылка на неразрешенный внешний символ (возможные причины).

  • либо виной всему aux_source_directory(). Его не рекомендуется использовать для поиска исходников как раз потому, что ни система сборки ни cmake не будут видеть вновь добавленные файлы в указанные каталоги, пока cmake'у явно не будет дана команда сгенерировать систему сборки заново.

Fat-Zer
  • 23,138