Ошибка связывания CMake (неопределенная ссылка на функцию) - PullRequest
0 голосов
/ 14 июля 2020

Я работаю над кроссплатформенным приложением на C / C ++. Я использую CMake для процесса сборки.

Структура проекта ниже упрощена, сужая до проблемы.

├── 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")

Наконец, когда я делаю это, создается следующая ошибка:

[ 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

Я могу сгенерировать исполняемый файл в Windows, у меня проблема с linux. Я уже некоторое время пытаюсь это исправить. Почему он показывает ошибки, если он уже был построен до привязки?

...