我正在为CMake配置我的项目并且遇到链接问题 - 项目文件全部编译成功,然后它说它正在链接并报告未找到的各种符号。
这些符号主要由我自己的代码提供,而其中一些符号由BerkeleyDB提供,它正确定位并包含在内。
这是我的顶级CMakeLists.txt:
cmake_minimum_required(VERSION 2.6)
project( rpdb C )
# add local modules path for project
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/" )
# where to look for source files (headers and source)
include_directories( include src )
# define sub-directories of source that cmake knows about as well a where their output will be put
add_subdirectory( src bin )
# compiler-dependent flags:
if( CMAKE_COMPILER_IS_GNUCC )
# gcc
add_definitions( -ggdb -fsigned-char -freg-struct-return -Wall -W -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Winline -Werror )
else( CMAKE_COMPILER_IS_GNUCC )
# non-gcc (intended for clang)
add_definitions( -ggdb -fsigned-char -Wall -W -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Winline -Werror )
endif( CMAKE_COMPILER_IS_GNUCC )
# distribution configuration
set(CMAKE_C_FLAGS_DISTRIBUTION "-O3")
set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O3")
这是我的src级CMakeLists.txt:
# make sure we have libdb
find_package( BerkeleyDB REQUIRED )
include_directories( ${libdb_INCLUDE_DIRS} )
target_link_libraries( rpdb ${libdb_LIBRARIES} )
# define variable specifying included source files - all .c files below this directory
file( GLOB rpdb_src "**/*.c" )
# define shared library with sources
add_library( rpdb SHARED ${rpdb_src} )
输出(部分):
...
[100%] Building C object bin/CMakeFiles/rpdb.dir/RPDB_TransactionController/RPDB_TransactionController.c.o
Linking C shared library librpdb.dylib
Undefined symbols:
"_RPDB_ReplicationVerbositySettingsController_displayMessageProcessingInformation", referenced from:
_RPDB_SettingsController_internal_setVerbosity in RPDB_SettingsController.c.o
...
所有符号做实际上都存在。结果似乎发生在目标文件中的符号之外,而不是当前正在查看的符号。
“cmake ../”的输出(来自安装,顶级目录):
=> cmake ..
-- Found BerkeleyDB: /usr/local/lib/libdb.dylib
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/ahaig/Projects/RPDB/RPDB_C/install
任何帮助都非常感激。
答案 0 :(得分:2)
而不是GLOB
,请尝试GLOB_RECURSE
(CMake 2.8.3 docs, file command),您可以这样使用:file ( GLOB_RECURSE rpdb_src "*.c" )
一个例子:
function (add_test_files)
set ( src_files "" )
####################################################
# Find all C/C++ files recursively from current dir
####################################################
foreach ( ext IN ITEMS "cpp" "cxx" "cc" "c" )
file ( GLOB_RECURSE _files "*.${ext}" )
set ( src_files ${src_files} ${_files} )
endforeach ()
message ( STATUS "Found: ${src_files}" )
add_executable ( test ${src_files} )
endfunction ()
add_test_files ()
答案 1 :(得分:0)
使VERBOSE = 1
另外,请查看CMakeCache.txt
答案 2 :(得分:0)
我的问题归结为文件包含问题。我使用** / * .c通过glob包含文件,显然被视为* / * .c。也许我在这里误解了glob模式 - 我只是在Ruby的文件通配中只使用了它们。
无论如何,这是我提出的解决方案:
# function processes each sub-directory and then adds each source file in directory
# each function should cascade back upward in setting variables so that the bottom directory
# adds its source first, and then the level above it adds its source and passes both up, and so on...
function( recursively_include_source which_directory )
# get list of source from this directory
file( GLOB this_directory_src "${which_directory}/*.c" )
# get list of all files for this directory
file( GLOB this_directory_all_files "${which_directory}/*" )
if( this_directory_all_files AND this_directory_src )
# remove source from list of files to get list of directories
list( REMOVE_ITEM this_directory_all_files ${this_directory_src} )
set( this_directory_directories ${this_directory_all_files} )
# for each sub-directory, call self with sub-directory as arg
foreach( this_sub_directory ${this_directory_directories} )
recursively_include_source( ${this_sub_directory} )
endforeach( this_sub_directory ${this_directory_directories} )
endif( this_directory_all_files AND this_directory_src )
# add source files to ${rpdb_src} in PARENT_SCOPE
set( rpdb_src ${rpdb_src} ${this_directory_src} PARENT_SCOPE )
endfunction( recursively_include_source which_directory )
这包括当前目录中和下面的所有.c文件。
我这样称呼函数:
recursively_include_source( ${CMAKE_CURRENT_SOURCE_DIR} )
所以最终的src-dir CMakeLists.txt看起来像这样:
# make sure we have libdb
find_package( BerkeleyDB REQUIRED )
include_directories( ${DB_INCLUDE_DIRS} )
set(LIBS ${LIBS} ${DB_LIBRARIES})
recursively_include_source( ${CMAKE_CURRENT_SOURCE_DIR} )
# define shared library with sources
add_library( rpdb SHARED ${rpdb_src} )
target_link_libraries( rpdb ${LIBS} )
一切似乎都在起作用。