cmake未定义函数的引用 [英] cmake undefined reference to function

查看:1631
本文介绍了cmake未定义函数的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的项目结构是一个简化的例子。我尝试将其归档到最小的文件大小以重现我的问题。

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



./ CMakeLists.txt



  cmake_minimum_required(VERSION 2.8) 
project(test)

宏(add_sources)
文件(RELATIVE_PATH _relPath$ {CMAKE_SOURCE_DIR}$ {CMAKE_CURRENT_SOURCE_DIR})
foreach(_src $ { ARGN})
if(_relPath)
list(APPEND SRCS$ {_ relPath} / $ {_ src})
else()
list }
endif()
endforeach()
if(_relPath)
#将SRCS传播到父目录
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 / Example.h



  #ifndef EXAMPLE_H 
#define EXAMPLE_H

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

#endif



subdir1 / subsubdir1 / Example.cpp



  #include< stdio.h> 
#includeExample.h

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

示例::〜Example()
{
}



subdir2 / CMakeLists.txt



  add_subdirectory(subsubdir1)
add_sources cpp)



subdir2 / main.cpp



  #includesubsubdir1 / 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

ExampleCreator
{
public:
ExampleCreator();
virtual〜ExampleCreator();
};

#endif



subdir2 / subsubdir1 / ExampleCreator.cpp



  #includeExampleCreator.h
#include../../subdir1/subsubdir1/Example.h

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

ExampleCreator ::〜ExampleCreator()
{
}

我希望这是一个非常简单的理解,如何CMake处理依赖关系。此编译没有错误,但在链接期间失败。下面的 make 输出显示 Example.cpp 甚至不编译,我不明白为什么。 p>

  user>:〜/ src / test / build $ make 
扫描目标测试的依赖关系
[50% ]构建CXX对象CMakeFiles / test.dir / subdir2 / subsubdir1 / ExampleCreator.cpp.o
[100%]构建CXX对象CMakeFiles / test.dir / subdir2 / main.cpp.o
链接CXX可执行文件test
CMakeFiles / test.dir / subdir2 / subsubdir1 / ExampleCreator.cpp.o:在函数`ExampleCreator :: ExampleCreator()'中:
ExampleCreator.cpp :(。text + 0x2b):undefined `example :: Example()'
collect2:ld返回1退出状态
make [2]:*** [test]错误1
make [1]:*** [CMakeFiles /test.dir/all]错误2
make:*** [all]错误2

所有的源都附加到根据 CMakeLists.txt 文件中的 SRCS 变量。那么,为什么 Example.cpp 得不到编译?或链接? c code> subdir1 不会生成二进制文件。添加以下内容:

 项目(示例)
add_library(Example Example.cpp)

而不是您的 add_sources 。之后,您需要告诉使用它来链接它的项目:

  TARGET_LINK_LIBRARIES(subdir2示例)

如果您的名称不同,请记录这些命令的功能。


The project structure below is a simplified example. I tried to boil it down to the minimal amount of files to reproduce my issue.

.
├── 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/Example.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()
{
}

I'm hoping this is a really simple lack of understanding of how CMake handles dependencies. This compiles without error, but fails during linking. The make output below shows that Example.cpp isn't even compiling and I don't understand why.

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

All the sources are appended to the SRCS variable in the root CMakeLists.txt file from what I can tell. So, why isn't Example.cpp getting compiled? or linked?

解决方案

The directory subdir1 doesn't generate a binary. Add this:

project(Example)
add_library(Example Example.cpp)

instead of your add_sources. After this, you need to tell the project that uses it to link against it:

TARGET_LINK_LIBRARIES(subdir2 Example)

If your names differ, document yourself on the functionalities of these commands.

这篇关于cmake未定义函数的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆