c++ - CMake linking error (undefined reference to function)
问题描述
I'm working on C/C++ cross platform application. I'm using CMake for build process.
The project structure below is simplified, narrowing to the issue.
├── CMakeLists.txt
├── Common_libs
│ ├── CMakeLists.txt
│ └── File_Process_... (.cc/.h, 4 each)
└── MAIN
├── CMakeLists.txt
└── (Other subdirs and sources/headers)
./CMakeLists.txt:(Common_libs)
# CMakeLists.txt : CMake project, include source and define
# project specific logic here.
#
set(PKG_NAME File_Process)
add_library(${PKG_NAME} STATIC
include/File_Process_Interface.h
include/File_Process_Types.h
include/FP_Directory.h
include/FP_File.h
include/FP_FileLP.h
include/FP_Includes.h
include/Filestruct.h
../../MAIN/error.h
source/File_Process_Factory.cpp
source/FP_Directory.cpp
source/FP_File.cpp
source/FP_FileLP.cpp)
target_include_directories(${PKG_NAME} PUBLIC include)
target_include_directories(${PKG_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/Common/Resources/3RD_PARTYLibrary/include)
if (WIN32)
target_include_directories(${PKG_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/Common/Resources/Windows/Includes)
install(TARGETS ${PKG_NAME} ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/Common_libs/dist/${CMAKE_BUILD_TYPE}/Win/)
else()
SET(CMAKE_CXX_FLAGS "-std=c++11")
install(TARGETS ${PKG_NAME} ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/Common_libs/dist/${CMAKE_BUILD_TYPE}/Linux/)
endif(WIN32)
target_include_directories(${PKG_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
File_Process_Interface.h
namespace AppExecutable{
namespace Common {
class File_Process_Factory {
public:
enum File_ProcessObjectType {
FP_File, FP_Directory, FP_FileLP, Automatic_Detection
};
static IFile_Process* Create(File_ProcessObjectType type = FP_File, std::string source = "");
};
}
}
File_Process_Factory.cpp
namespace AppExecutable{
namespace Common {
IFile_Process* File_Process_Factory::Create(File_ProcessObjectType type, std::string source) {
switch (type) {
case File_Process_Factory::Automatic_Detection:
struct stat st;
if (stat(source.c_str(), &st) == -1) {
return NULL;
}
else {
if (S_ISDIR(st.st_mode)) {
return (IFile_Process*) (new Common::FP_Directory());
}
else {
if (source.rfind(".xyz") == (source.length() - 4)) {
return (IFile_Process*) (new Common::FP_FileLP());
}
else {
return (IFile_Process*) (new Common::FP_File());
}
}
}
//return (IFile_Process*)new Common::Automatic_Detection();
break;
case File_Process_Factory::FP_File:
return (IFile_Process*) (new Common::FP_File());
break;
case File_Process_Factory::FP_Directory:
return (IFile_Process*) (new Common::FP_Directory());
break;
case File_Process_Factory::FP_FileList:
return (IFile_Process*) (new Common::FP_FileLP());
break;
default:
throw ("Unknown File_ProcessObjectType");
}
}
./CMakeLists.txt:(MAIN)
cmake_minimum_required (VERSION 3.8)
project(AppExecutable C CXX)
cmake_policy(SET CMP0015 NEW)
if (WIN32)
include_directories(MAIN
MAIN/shared)
link_directories(../Common_libs/dist/${CMAKE_BUILD_TYPE}/Win/)
else()
include_directories(MAIN
MAIN/shared)
endif(WIN32)
file(GLOB SOURCES
*.cpp
shared/*.cpp
shared/*.c)
# Add source to this project's executable.
if (WIN32)
add_executable (AppExecutable ${SOURCES})
install(TARGETS AppExecutable DESTINATION ${CMAKE_SOURCE_DIR}/Application/Windows/)
target_link_libraries(AppExecutable File_Process)
else()
add_executable (AppExecutable ${SOURCES})
install(TARGETS AppExecutable DESTINATION ${CMAKE_SOURCE_DIR}/Application/Linux/)
target_link_libraries(AppExecutable File_Process)
endif(WIN32)
SET_TARGET_PROPERTIES(AppExecutable PROPERTIES DEBUG_POSTFIX "_debug")
Finally, when I do make, the following error is generated:
[ 33%] Built target Common_libs
[ 38%] Linking CXX executable AppExecutable
CMakeFiles/AppExecutable.dir/MAIN/FileEntry.cpp.o: In function `AppExecutable::Common::FileEntry::FileSimulation(int, char**)':
FileEntry.cpp:(.text+0xaa9): undefined reference to `AppExecutable::Common::File_Process_Factory::Create(AppExecutable::Common::File_Process_Factory::File_ProcessObjectType, std::string)'
collect2: error: ld returned 1 exit status
make[2]: *** [AppExecutable/AppExecutable] Error 1
make[1]: *** [AppExecutable/CMakeFiles/AppExecutable.dir/all] Error 2
make: *** [all] Error 2
link.txt
/opt/gcc54/bin/g++ -std=c++11 -O3 -DNDEBUG -static-libgcc -static-libstdc++ CMakeFiles/AppExecutable.dir/Output_App.cpp.o CMakeFiles/AppExecutable.dir/FileEntry.cpp.o CMakeFiles/AppExecutable.dir/AppExecutable.cpp.o CMakeFiles/AppExecutable.dir/ABCBaseClass.cpp.o CMakeFiles/AppExecutable.dir/ABCControl.cpp.o CMakeFiles/AppExecutable.dir/shared/CsvReader.c.o CMakeFiles/AppExecutable.dir/shared/OutputInterface.cpp.o CMakeFiles/AppExecutable.dir/shared/DataBlock.cpp.o CMakeFiles/AppExecutable.dir/shared/lElement.cpp.o CMakeFiles/AppExecutable.dir/shared/lParser.cpp.o CMakeFiles/AppExecutable.dir/shared/lParserCApi.cpp.o CMakeFiles/AppExecutable.dir/shared/ssupport.cpp.o CMakeFiles/AppExecutable.dir/shared/lVersionParser.c.o -o AppExecutable ../Common_libs/libFile_Process.a
I'm able to generate executable in Windows, I'm having issue on linux. I've been trying to fix this for some time. Why it is showing errors if it has already been built before the linkage?
解决方案
推荐阅读
- odoo - 类型错误:create() 在尝试创建新记录时恰好采用 2 个参数(给定 1 个)
- wordpress - 使用电话号码而不是用户名登录 WordPress
- reactjs - 如何知道我是否应该将 redux 用于我的应用程序或任何其他替代方案?
- apache-spark - Pyspark 枢轴保留其余列
- vba - VBA动态计数函数
- pyspark - pyspark 将大熊猫数据帧更改为 pyspark 数据帧并写入 s3 出错
- javascript - 如何在Java中保持PNG文件结构
- perl - 在 perl 中尝试::Tiny 和 $SIG{__DIE__}?
- c# - 将默认会话提供程序设置为环境变量
- javascript - 在 __webpack_require__ 中的 NextJS 中构建错误