c++ cmake in main.cpp was not declared in this scope
13:57 07 Apr 2024

problem: in a cmake project, I included header file in the main.cpp successfully, but when I tried to use the implemented class, it had compile error:

\cpp_projects\folder_test\main.cpp: In function 'int main()':
\cpp_projects\folder_test\main.cpp:6:5: error: 'firstImpl' was not declared in this scope

I tried to adjust cmakelists.txt, google this situation, and even asked chatgpt, but no useful way could be applied.

could anyone help and tell me what I missed in cmakelists.txt? Or, did I use the interface in a wrong way? Why it seemed like no link between the interface and its implmentation?

the cmake project structure and every file content as below:

project_root/
│
├── interface/
│   ├── first.h
│   └── CMakeLists.txt
│
├── implement/
│   ├── firstImpl.cpp
│   └── CMakeLists.txt
│
├── main.cpp
└── CMakeLists.txt

first.h

class Ifirst {

  virtual void test() = 0;
};

CMakeLists.txt

add_library(Ifirst INTERFACE)
target_sources(Ifirst first.h)

firstImpl.cpp

#include "interface/first.h"
#include 

class firstImpl final : public Ifirst {
private:
public:
  void test() override {
    std::cout << "hi, i am in test function\n";
  }
};

CMakeLists.txt

add_library(firstImpl firstImpl.cpp)
target_link_libraries(firstImpl INTERFACE Ifirst)

main.cpp

#include 
#include "interface/first.h"

int main() {
    std::cout << "Hello, from test_folder!\n";
    firstImpl op;
    //Ifirst if_v = &op;

    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.28)
project(test_folder VERSION 0.1.0 LANGUAGES C CXX)

add_library(compiler_flags INTERFACE)
target_compile_features(compiler_flags INTERFACE cxx_std_20)

include(CTest)
enable_testing()


add_executable(test_folder main.cpp)

target_include_directories(test_folder PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interface)

target_link_libraries(test_folder PUBLIC firstImpl INTERFACE Ifirst)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

after adjustment

project_root/
│
├── interface/
│   ├── first.h
|   ├── firstImpl.h
│   └── CMakeLists.txt
│
├── main.cpp
└── CMakeLists.txt

first.h

class Ifirst {
private:
public:
  virtual void test() = 0;
};

firstImpl.h

#include "first.h"
#include 

class firstImpl final : public Ifirst {
private:
public:
  void test() override {
    std::cout << "hi, i am in test function\n";
  }
};

CMakeLists.txt

add_library(first_h INTERFACE first.h)
#target_include_directories(first_h INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
#target_sources(first_h INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/first.h)

add_library(firstImpl_h INTERFACE firstImpl.h)
#target_include_directories(firstImpl_h INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
#target_sources(firstImpl_h INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/firstImpl.h)

main.cpp

#include 
#include "interface/firstImpl.h"

int main() {
    std::cout << "Hello, from test_folder!\n";
    firstImpl op;

    //Ifirst& if_v = op;
    //if_v.test();
    Ifirst* if_v = &op;
    if_v->test();

    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.28)
project(test_folder VERSION 0.1.0 LANGUAGES C CXX)

add_library(compiler_flags INTERFACE)
target_compile_features(compiler_flags INTERFACE cxx_std_20)

include(CTest)
enable_testing()

add_subdirectory(interface)

add_executable(test_folder main.cpp)

target_include_directories(test_folder PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interface)

target_link_libraries(test_folder INTERFACE firstImpl)
c++ cmake interface polymorphism