自定义FindXXX模块无法在CMake中运行?

时间:2015-11-13 22:08:41

标签: c compiler-errors linker cmake linker-errors

我已经编写了一个基本的FindUsb CMake模块来查找libusb,但是在库中使用它似乎没有正确链接。

我的项目结构如下:

MyProject
├── MyLibrary
│   ├── CMakeLists.txt
│   ├── cmake
│   │   └── Modules
│   │       └── FindLibUsb.cmake
│   ├── include
│   │   └── MyLibrary
│   │       └── library.h
│   └── src
│       └── library.c
│
└── MyProject
    ├── CMakeLists.txt
    └── src
        └── project.c

MyProject取决于MyLibraryMyLibrary的位置取决于libusb

以下是MyLibrary/CMakeLists.txt的内容:

cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules")

set(MyLibrary_SOURCES
    src/library.c
)

set(MyLibrary_INCLUDES
    include
)

# Add source to library
add_library(MyLibrary STATIC ${MyLibrary_SOURCES} ${MyLibrary_INCLUDES})

# Find libusb
find_package(LibUsb REQUIRED)

# Add dependencies
target_link_libraries(MyLibrary ${LIBUSB_LIBRARY})

# Add include directories to library
target_include_directories(MyLibrary PUBLIC ${MyLibrary_INCLUDES} ${LIBUSB_INCLUDE_DIR})

MyLibrary/cmake/Modules/FindLibUsb.cmake

# FindLibUsb
# ----------
# Tries to find libusb
#
# Variables:
#  LIBUSB_ROOT_DIR - Set this variable to the root installation of CMocka
#
# Read-Only variables:
#  LIBUSB_FOUND - system has libusb
#  LIBUSB_INCLUDE_DIRS - the libusb include directories
#  LIBUSB_INCLUDE_DIR - for backwards compatiblity, the same as LIBUSB_INCLUDE_DIRS
#  LIBUSB_LIBRARY - libusb library location
#  LIBUSB_DEFINITIONS - compiler switches required for using libusb
#

include(FindPackageHandleStandardArgs)

set(LIBUSB_ROOT_DIR ${LIBUSB_ROOT_DIR} CACHE PATH "Root installation directory of libusb")

find_path(LIBUSB_INCLUDE_DIRS
  NAMES libusb.h
  PATHS ${LIBUSB_ROOT_DIR}/include
  PATH_SUFFIXES libusb-1.0
)

find_library(LIBUSB_LIBRARY
  NAMES usb
  PATHS ${LIBUSB_ROOT_DIR}/lib
)

set(LIBUSB_INCLUDE_DIR ${LIBUSB_INCLUDE_DIRS})

find_package_handle_standard_args(LibUsb DEFAULT_MSG LIBUSB_LIBRARY LIBUSB_INCLUDE_DIR)

mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARY)

我在libusb.h内加MyLibrary/include/MyLibrary/library.h

#include <libusb.h>

void do_something(libusb_context **context);

MyLibrary/src/library.c内使用它:

#include "MyLibrary/library.h"

void do_something(libusb_context **context) {
    libusb_init(context);
    // Do something
    libusb_exit(*context);
}

然后我在MyLibrary MyProject中加入MyProject/CMakeLists.txt,如下所示:

cmake_minimum_required(VERSION 2.8.11 FATAL_ERROR)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})

project(MyProject)

add_subdirectory(../MyLibrary ${CMAKE_BINARY_DIR}/MyLibrary)

set(MyProject_SOURCES
    src/project.c
)

set(MyProject_INCLUDES
    include
)

# Set include directory
include_directories(${MyProject_INCLUDES})

# Add source to executable
add_executable(MyProject ${MyProject_SOURCES})

# Add dependencies
target_link_libraries(MyProject MyLibrary)

以下是MyProject/src/project.c的内容:

#include "MyLibrary/library.h"

int main(int argc, char *argv[]) {
    libusb_context *context;

    do_something(&context);
}

使用MyLibrary/buildcmake ..make编译项目时,项目编译成功,但是从MyProject/build编译时出现以下错误:

[ 25%] Building C object MyLibrary/CMakeFiles/MyLibrary.dir/src/library.c.o
[ 50%] Linking C static library ../lib/libMyLibrary.a
[ 50%] Built target MyLibrary
[ 75%] Building C object CMakeFiles/MyProject.dir/src/project.c.o
[100%] Linking C executable bin/MyProject
Undefined symbols for architecture x86_64:
  "_libusb_exit", referenced from:
      _do_something in libMyLibrary.a(library.c.o)
  "_libusb_init", referenced from:
      _do_something in libMyLibrary.a(library.c.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [bin/MyProject] Error 1
make[1]: *** [CMakeFiles/MyProject.dir/all] Error 2
make: *** [all] Error 2

看起来libusb的实际图书馆二进制文件没有被链接,当我在make VERBOSE=1make clean MyProject/build之后运行时,会确认这一点,具有以下输出:

/usr/local/Cellar/cmake/3.3.2/bin/cmake -H/Users/jack/Documents/Development/Languages/C/issue/MyProject -B/Users/jack/Documents/Development/Languages/C/issue/MyProject/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/Cellar/cmake/3.3.2/bin/cmake -E cmake_progress_start /Users/jack/Documents/Development/Languages/C/issue/MyProject/build/CMakeFiles /Users/jack/Documents/Development/Languages/C/issue/MyProject/build/CMakeFiles/progress.marks
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/Makefile2 all
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f MyLibrary/CMakeFiles/MyLibrary.dir/build.make MyLibrary/CMakeFiles/MyLibrary.dir/depend
cd /Users/jack/Documents/Development/Languages/C/issue/MyProject/build && /usr/local/Cellar/cmake/3.3.2/bin/cmake -E cmake_depends "Unix Makefiles" /Users/jack/Documents/Development/Languages/C/issue/MyProject /Users/jack/Documents/Development/Languages/C/issue/MyLibrary /Users/jack/Documents/Development/Languages/C/issue/MyProject/build /Users/jack/Documents/Development/Languages/C/issue/MyProject/build/MyLibrary /Users/jack/Documents/Development/Languages/C/issue/MyProject/build/MyLibrary/CMakeFiles/MyLibrary.dir/DependInfo.cmake --color=
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f MyLibrary/CMakeFiles/MyLibrary.dir/build.make MyLibrary/CMakeFiles/MyLibrary.dir/build
[ 25%] Building C object MyLibrary/CMakeFiles/MyLibrary.dir/src/library.c.o
cd /Users/jack/Documents/Development/Languages/C/issue/MyProject/build/MyLibrary && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc   -I/Users/jack/Documents/Development/Languages/C/issue/MyLibrary/include -I/usr/local/include/libusb-1.0    -o CMakeFiles/MyLibrary.dir/src/library.c.o   -c /Users/jack/Documents/Development/Languages/C/issue/MyLibrary/src/library.c
[ 50%] Linking C static library ../lib/libMyLibrary.a
cd /Users/jack/Documents/Development/Languages/C/issue/MyProject/build/MyLibrary && /usr/local/Cellar/cmake/3.3.2/bin/cmake -P CMakeFiles/MyLibrary.dir/cmake_clean_target.cmake
cd /Users/jack/Documents/Development/Languages/C/issue/MyProject/build/MyLibrary && /usr/local/Cellar/cmake/3.3.2/bin/cmake -E cmake_link_script CMakeFiles/MyLibrary.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar cq ../lib/libMyLibrary.a  CMakeFiles/MyLibrary.dir/src/library.c.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib ../lib/libMyLibrary.a
[ 50%] Built target MyLibrary
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/MyProject.dir/build.make CMakeFiles/MyProject.dir/depend
cd /Users/jack/Documents/Development/Languages/C/issue/MyProject/build && /usr/local/Cellar/cmake/3.3.2/bin/cmake -E cmake_depends "Unix Makefiles" /Users/jack/Documents/Development/Languages/C/issue/MyProject /Users/jack/Documents/Development/Languages/C/issue/MyProject /Users/jack/Documents/Development/Languages/C/issue/MyProject/build /Users/jack/Documents/Development/Languages/C/issue/MyProject/build /Users/jack/Documents/Development/Languages/C/issue/MyProject/build/CMakeFiles/MyProject.dir/DependInfo.cmake --color=
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/MyProject.dir/build.make CMakeFiles/MyProject.dir/build
[ 75%] Building C object CMakeFiles/MyProject.dir/src/project.c.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc   -I/Users/jack/Documents/Development/Languages/C/issue/MyProject/include -I/Users/jack/Documents/Development/Languages/C/issue/MyLibrary/include -I/usr/local/include/libusb-1.0    -o CMakeFiles/MyProject.dir/src/project.c.o   -c /Users/jack/Documents/Development/Languages/C/issue/MyProject/src/project.c
[100%] Linking C executable bin/MyProject
/usr/local/Cellar/cmake/3.3.2/bin/cmake -E cmake_link_script CMakeFiles/MyProject.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc   -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/MyProject.dir/src/project.c.o  -o bin/MyProject  lib/libMyLibrary.a 
Undefined symbols for architecture x86_64:
  "_libusb_exit", referenced from:
      _do_something in libMyLibrary.a(library.c.o)
  "_libusb_init", referenced from:
      _do_something in libMyLibrary.a(library.c.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [bin/MyProject] Error 1
make[1]: *** [CMakeFiles/MyProject.dir/all] Error 2
make: *** [all] Error 2

缺少对实际libusb库的任何引用。

打印LIBUSB_LIBRARY会提供有效且存在的路径/usr/local/lib/libusb.dylib

动态编译MyLibrary也无济于事。看起来MyLibrary根本没有与libusb相关联?在构建的libMyLibrary.alibMyLibrary.dylib

中没有对它的引用

1 个答案:

答案 0 :(得分:0)

我想以下一行

# Add dependencies
message(MyLibrary ${LIBUSB_LIBRARY})

应替换为

# Add dependencies
target_link_libraries(MyLibrary ${LIBUSB_LIBRARY})