无法将库链接到目标?

时间:2016-07-18 20:51:05

标签: c windows build linker cmake

我有the following CMakeLists.txt,尝试使用MinGW-w64在Windows上构建我的软件:

#
# Initial CMake and project setup
#

# Required CMake version (ExternalProject)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
INCLUDE(ExternalProject)
SET(PROJECT_NAME Khronos)
PROJECT(${PROJECT_NAME})

# Set software version
SET(APPLICATION_VERSION_MAJOR "0")
SET(APPLICATION_VERSION_MINOR "4")
SET(APPLICATION_VERSION_PATCH "0")
SET(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")

SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
SET_DIRECTORY_PROPERTIES(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/library-build)

#
# Setup compiler flags
#

if (NOT CMAKE_BUILD_TYPE)
    message(STATUS "No build type selected, default to Release")
    set(CMAKE_BUILD_TYPE Release FORCE)
endif()

set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -std=gnu11 -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -std=gnu11 -O3")

if (GCC_VERSION VERSION_GREATER "4.8")
elsif (GCC_VERSION VERSION_GREATER "4.1.2")
    SET (GCC_COMMON_WARNING_FLAGS "-pedantic -Wall -Wextra -Wconversion -Wfloat-equal -Wformat=2 -Winit-self -Winline -Winvalid-pch -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wstack-protector -Wstrict-null-sentinel -Wswitch-default -Wswitch-enum")
    SET (GCC_COMMON_WARNING_FLAGS "${GCC_COMMON_WARNING_FLAGS} -Wno-unused-parameter")
    SET (GCC_CXX_WARNING_FLAGS "-Wctor-dtor-privacy")
else ()
    SET(GCC_COMMON_WARNING_FLAGS "-pedantic -Wall -Wextra -Wconversion -Wfloat-equal -Wformat=2 -Winit-self -Winline -Winvalid-pch -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wstack-protector -Wstrict-null-sentinel -Wswitch-default -Wswitch-enum")
    SET(GCC_COMMON_WARNING_FLAGS "${GCC_COMMON_WARNING_FLAGS} -Wno-unused-parameter")
    SET(GCC_CXX_WARNING_FLAGS "-Wctor-dtor-privacy")
endif ()

#
# Find Doxygen for documentation
#

# add a target to generate API documentation with Doxygen
FIND_PACKAGE(Doxygen)
if (DOXYGEN_FOUND)
    ADD_CUSTOM_TARGET(DOC
        ${DOXYGEN_EXECUTABLE} ${CMAKE_SOURCE_DIR}/Doxyfile
        WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src
        COMMENT "Generating API documentation with Doxygen" VERBATIM
        )
endif ()

#
# Find/install dependencies
#

IF(WIN32)
    INCLUDE(${CMAKE_MODULE_PATH}/Win32-ExternalProjects.txt)
ELSE(UNIX)
    INCLUDE(${CMAKE_MODULE_PATH}/Unix-ExternalProjects.txt)
ENDIF()

#
# Final project settings
#

INCLUDE_DIRECTORIES(include)
ADD_SUBDIRECTORY(src)

ADD_EXECUTABLE(${PROJECT_NAME}
        $<TARGET_OBJECTS:audio>
        $<TARGET_OBJECTS:util>
        $<TARGET_OBJECTS:main>
        )

TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIBS})

if (DEPENDENCIES)
    MESSAGE (STATUS "Any missing dependencies will be downloaded upon running \"make\"")
    ADD_DEPENDENCIES(${PROJECT_NAME} ${DEPENDENCIES})
endif ()

我能够编译所有内容,但是我无法将可执行文件链接到库中:

"C:\Program Files (x86)\CMake\bin\cmake.exe" -HC:\Users\syb0rg\Downloads\Khronos -BC:\Users\syb0rg\Downloads\Khronos\build --check-build-system CMakeFiles\Makefile.cmake 0
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_progress_start C:\Users\syb0rg\Downloads\Khronos\build\CMakeFiles C:\Users\syb0rg\Downloads\Khronos\build\CMakeFiles\progress.marks
make -f CMakeFiles\Makefile2 all
make[1]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f CMakeFiles\sphinxbase.dir\build.make CMakeFiles/sphinxbase.dir/depend
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build\CMakeFiles\sphinxbase.dir\DependInfo.cmake --color=
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f CMakeFiles\sphinxbase.dir\build.make CMakeFiles/sphinxbase.dir/build
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
make[2]: Nothing to be done for `CMakeFiles/sphinxbase.dir/build'.
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
[ 17%] Built target sphinxbase
make -f CMakeFiles\LibSndFile.dir\build.make CMakeFiles/LibSndFile.dir/depend
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build\CMakeFiles\LibSndFile.dir\DependInfo.cmake --color=
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f CMakeFiles\LibSndFile.dir\build.make CMakeFiles/LibSndFile.dir/build
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
make[2]: Nothing to be done for `CMakeFiles/LibSndFile.dir/build'.
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
[ 35%] Built target LibSndFile
make -f CMakeFiles\pocketsphinx.dir\build.make CMakeFiles/pocketsphinx.dir/depend
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build\CMakeFiles\pocketsphinx.dir\DependInfo.cmake --color=
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f CMakeFiles\pocketsphinx.dir\build.make CMakeFiles/pocketsphinx.dir/build
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
make[2]: Nothing to be done for `CMakeFiles/pocketsphinx.dir/build'.
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
[ 53%] Built target pocketsphinx
make -f CMakeFiles\PortAudio.dir\build.make CMakeFiles/PortAudio.dir/depend
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build\CMakeFiles\PortAudio.dir\DependInfo.cmake --color=
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f CMakeFiles\PortAudio.dir\build.make CMakeFiles/PortAudio.dir/build
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
make[2]: Nothing to be done for `CMakeFiles/PortAudio.dir/build'.
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
[ 71%] Built target PortAudio
make -f src\audio\CMakeFiles\audio.dir\build.make src/audio/CMakeFiles/audio.dir/depend
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos\src\audio C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build\src\audio C:\Users\syb0rg\Downloads\Khronos\build\src\audio\CMakeFiles\audio.dir\DependInfo.cmake --color=
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f src\audio\CMakeFiles\audio.dir\build.make src/audio/CMakeFiles/audio.dir/build
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
make[2]: Nothing to be done for `src/audio/CMakeFiles/audio.dir/build'.
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
[ 73%] Built target audio
make -f src\util\CMakeFiles\util.dir\build.make src/util/CMakeFiles/util.dir/depend
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos\src\util C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build\src\util C:\Users\syb0rg\Downloads\Khronos\build\src\util\CMakeFiles\util.dir\DependInfo.cmake --color=
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f src\util\CMakeFiles\util.dir\build.make src/util/CMakeFiles/util.dir/build
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
make[2]: Nothing to be done for `src/util/CMakeFiles/util.dir/build'.
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
[ 75%] Built target util
make -f src\CMakeFiles\main.dir\build.make src/CMakeFiles/main.dir/depend
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos\src C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build\src C:\Users\syb0rg\Downloads\Khronos\build\src\CMakeFiles\main.dir\DependInfo.cmake --color=
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f src\CMakeFiles\main.dir\build.make src/CMakeFiles/main.dir/build
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
make[2]: Nothing to be done for `src/CMakeFiles/main.dir/build'.
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
[ 80%] Built target main
make -f CMakeFiles\tritium.dir\build.make CMakeFiles/tritium.dir/depend
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build\CMakeFiles\tritium.dir\DependInfo.cmake --color=
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f CMakeFiles\tritium.dir\build.make CMakeFiles/tritium.dir/build
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
make[2]: Nothing to be done for `CMakeFiles/tritium.dir/build'.
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
[ 97%] Built target tritium
make -f CMakeFiles\Khronos.dir\build.make CMakeFiles/Khronos.dir/depend
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build C:\Users\syb0rg\Downloads\Khronos\build\CMakeFiles\Khronos.dir\DependInfo.cmake --color=
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make -f CMakeFiles\Khronos.dir\build.make CMakeFiles/Khronos.dir/build
make[2]: Entering directory `C:/Users/syb0rg/Downloads/Khronos/build'
[100%] Linking C executable Khronos.exe
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\Khronos.dir\link.txt --verbose=1
"C:\Program Files (x86)\CMake\bin\cmake.exe" -E remove -f CMakeFiles\Khronos.dir/objects.a
C:\PROGRA~1\MINGW-~1\X86_64~1.0-P\mingw64\bin\ar.exe cr CMakeFiles\Khronos.dir/objects.a @CMakeFiles\Khronos.dir\objects1.rsp
C:\PROGRA~1\MINGW-~1\X86_64~1.0-P\mingw64\bin\gcc.exe     -Wl,--whole-archive CMakeFiles\Khronos.dir/objects.a -Wl,--no-whole-archive  -o Khronos.exe -Wl,--out-implib,libKhronos.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\Khronos.dir\linklibs.rsp
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0xd2): undefined reference to `ps_start_utt'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x109): undefined reference to `ps_process_raw'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x115): undefined reference to `ps_get_in_speech'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x161): undefined reference to `ps_end_utt'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x172): undefined reference to `ps_get_hyp'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x185): undefined reference to `ps_start_utt'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x1ce): undefined reference to `ps_end_utt'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x1e8): undefined reference to `ps_get_hyp'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x24b): undefined reference to `getPathFromDescriptor'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x61c): undefined reference to `err_set_logfp'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x626): undefined reference to `err_set_debug_level'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x678): undefined reference to `ps_args'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x6d7): undefined reference to `cmd_ln_init'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x71f): undefined reference to `ps_init'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x7fb): undefined reference to `ps_free'
CMakeFiles\Khronos.dir/objects.a(main.c.obj):main.c:(.text+0x807): undefined reference to `cmd_ln_free_r'
collect2.exe: error: ld returned 1 exit status
make[2]: *** [Khronos.exe] Error 1
make[2]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make[1]: *** [CMakeFiles/Khronos.dir/all] Error 2
make[1]: Leaving directory `C:/Users/syb0rg/Downloads/Khronos/build'
make: *** [all] Error 2

这里是来自${LIBS}的{​​{1}}输出(以更易读的形式):

message()

作为参考,C:/Users/syb0rg/Downloads/Khronos/lib/sphinxbase/bin/Debug/Win32/sphinxbase.dll C:/Users/syb0rg/Downloads/Khronos/lib/pocketsphinx/bin/Debug/Win32/pocketsphinx.dll C:/Users/syb0rg/Downloads/Khronos/lib/PortAudio/libportaudio_x86.dll C:/Users/syb0rg/Downloads/Khronos/lib/LibSndFile/libsndfile.dll C:/Users/syb0rg/Downloads/Khronos/lib/tritium/libtritium.a 设置在此处:

${LIBS}

所有这些库都存在于指定位置。有什么建议吗?

2 个答案:

答案 0 :(得分:4)

undefined reference to明确表示你向链接器提供带有此(导出!)函数的必需对象文件/库。主要有两个原因:

  1. 您未将此库传递给链接器命令行或未将正确的搜索路径(-L...)传递给它 - 检查结果命令行的两次,make VERBOSE=1将显示更详细的输出。
  2. 路径正确,但文件/功能本身无效 - 您可以针对不同的CPU架构编译库(例如,在定位x86_64时尝试使用x86库)。还要检查标记为可导出的功能(在大多数情况下,这是使用MSVC编译器时的问题,但您也可以使用GCC / MinGW隐藏功能)。并且不要忘记检查文件是不是零长度:)

答案 1 :(得分:-2)

你可以试试这个:

set(CMAKE_BUILD_TYPE CACHE Release FORCE)

参考:https://cmake.org/cmake/help/v2.8.8/cmake.html#variable:CMAKE_CFG_INTDIR

搜索:initial-cache