我已经编写了一个基本的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
取决于MyLibrary
和MyLibrary
的位置取决于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/build
和cmake ..
从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=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.a
或libMyLibrary.dylib
。
答案 0 :(得分:0)
我想以下一行
# Add dependencies
message(MyLibrary ${LIBUSB_LIBRARY})
应替换为
# Add dependencies
target_link_libraries(MyLibrary ${LIBUSB_LIBRARY})