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)