2015-11-13 273 views
0

我已经编写了一个基本的FindUsb CMake模块来查找libusb,但是它在使用库时似乎没有正确链接。自定义FindXXX模块不能在CMake中工作?

我的项目结构如下:

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.hMyLibrary/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); 
} 

然后我包括MyLibraryMyProjectMyProject/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); 
} 

当使用cmake ..make编译从MyLibrary/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=1(一make 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中没有提及它。

+0

owi535替代是不一样的在MyLibrary。尝试改变它。 –

+0

另一个复制/粘贴错误!现在修复它。仍然有问题。 –

+0

在'MyProject/build'的CMakeCache.txt文件中'LIBUSB_LIBRARY'的值是什么? –

回答

0

我想下面的行

# Add dependencies 
message(MyLibrary ${LIBUSB_LIBRARY}) 

# Add dependencies 
target_link_libraries(MyLibrary ${LIBUSB_LIBRARY}) 
+0

这是一个复制/粘贴错误,我更新了原始帖子(该错误仍然发生在target_link_libraries中)。 –