cmake 对`demo::app::ApplicationDemo::entry()'的未定义引用

yeotifhr  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(104)

我正试图将代码嵌套在特定的namespace下,以便于组织。下面是一个MVP,我不能在我的代码中发现这个问题。不知道如何定义此嵌套或将其导出到CMakeLists.txt和Linking。只有在namespaces内部 Package 类时才会发生这种情况。

demo.h:

#pragma once
#include "../../third-party/fmt/include/fmt/core.h"
#include "../../third-party/fmt/include/fmt/color.h"

namespace demo {
    namespace app {
        class ApplicationDemo{
        public:
            void entry();
        };
    }
}

demo.cpp:

#include "demo.h"

namespace demo
{
    namespace app {
        void ApplicationDemo::entry(){
             std::string m_ascii = R"(
    ____                   
    |    \  ___  _____  ___ 
    |  |  || -_||     || . |
    |____/ |___||_|_|_||___|                    
)";
            fmt::print(fmt::emphasis::bold | fg(fmt::color::orange_red), m_ascii);
        }
    }
}

main.cpp:

#include <iostream>
#include "demoapp/demo.h"

int main(int argc, char const *argv[])
{
    demo::app::ApplicationDemo m_demo;

    m_demo.entry();
    std::cin.get();
    return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)

set(CMAKE_CXX_STANDARD 17)
project(demo)

set(CMAKE_CXX_FLAGS
        "${CMAKE_CXX_FLAGS} \
        -Wall \
        -fdiagnostics-color=always \
        -mavx")

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

include_directories(./)

add_subdirectory(third-party/fmt EXCLUDE_FROM_ALL)
target_compile_options(fmt PRIVATE -w)

add_subdirectory(src/demoapp)

set(third_parties fmt)

set(SOURCES src/main.cpp)
add_executable(demo src/main.cpp)
target_link_libraries(demo ${third_parties})

构建输出:

[main] Building folder: experiment 
[build] Starting build
[proc] Executing command: chcp
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build c:/GitHub/experiment/build --config Debug --target all -j 10 --
[build] [ 20%] Building CXX object third-party/fmt/CMakeFiles/fmt.dir/src/format.cc.obj
[build] [ 40%] Building CXX object third-party/fmt/CMakeFiles/fmt.dir/src/os.cc.obj
[build] [ 60%] Linking CXX static library ..\..\lib\libfmtd.a
[build] [ 60%] Built target fmt
[build] [ 80%] Building CXX object CMakeFiles/demo.dir/src/main.cpp.obj
[build] [100%] Linking CXX executable bin\demo.exe
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\demo.dir/objects.a(main.cpp.obj): in function `main':
[build] C:/GitHub/experiment/src/main.cpp:8:(.text+0x1c): undefined reference to `demo::app::ApplicationDemo::entry()'
[build] collect2.exe: error: ld returned 1 exit status
[build] mingw32-make[2]: *** [CMakeFiles\demo.dir\build.make:100: bin/demo.exe] Error 1
[build] mingw32-make[1]: *** [CMakeFiles\Makefile2:98: CMakeFiles/demo.dir/all] Error 2
[build] mingw32-make: *** [Makefile:135: all] Error 2
[proc] The command: "C:\Program Files\CMake\bin\cmake.EXE" --build c:/GitHub/experiment/build --config Debug --target all -j 10 -- exited with code: 2
[driver] Build completed: 00:00:04.365
[build] Build finished with exit code 2

编辑:我把事情这样,

/src/demoapp/
CMakeLists.txt,
demo.cpp
demo.h

/src/main.cpp

demoapp的CMakeLists.txt:

add_library(demoapp
demo.cpp)

target_link_libraries(demoapp fmt)

if(WIN32)
    target_link_libraries(demoapp)
else()
    target_link_libraries(demoapp stdc++fs)
endif()

然后,我将这行add_subdirectory(src/demoapp)添加到父根CMakeLists.txt。但是,当我这样做的时候,这是我想要的目标。很抱歉,我没有在前面指定,当我收到与上面相同的错误时。但是,如果我按照你教我的方法做,效果会很好。
我很感激任何有价值的信息。先谢了。

sdnqo3pr

sdnqo3pr1#

您忘记将demo.cpp添加到可执行文件中。它没有作为项目的一部分进行汇编和链接。

add_executable(demo
    src/main.cpp
    src/demo.cpp
    src/demo.h)
  • 注意:将demo.h添加到可执行文件中并不是绝对必要的,但对于IDE很有用,因为它使项目的头文件成为项目的一部分。例如,QtCreator依赖于此。*

void ApplicationDemo::entry()位于demo.cpp中,如果您不将demo.cpp添加到可执行文件中,则程序的其余部分将无法使用其中的定义,并且您将获得链接器错误。
此外,如果你想链接到一个库,有必要写:

target_link_libraries(demo demoapp)

仅仅在demoapp所在的位置添加一个缓存是不够的;它还没有告诉CMake库与demo可执行文件链接。

相关问题