我对linux,cmake和软件/计算机领域的全新了解(我只是学习如何使用命令行,如果这可以让你了解我在哪里&#39我在某种程度上发现自己是一名软件实习生(我是EE专业)。我的任务是使用cmake和make构建一个软件包,但进展并不顺利。我正在努力理解与该软件包相关的顶级CMakeLists.txt文件中的每一行,感觉非常无能。我已经浏览了一些关于cmake的文档,虽然我对cmake如何使用CMakeLists.txt文件有所了解,但有些细节需要澄清。
1)正在使用许多变量,我想知道它们的值是什么。但是,并非CMakeLists.txt文件中的所有变量都显示在CMakeCache.txt文件中。例如,请考虑以下命令,如下所示
SET(bioreader_common_LIBS
${bioreader_common_LIBS}
QtCore
QtScript
QtScriptTools
QtNetwork
QtGui
QtTest
QtXml
QtDBus
QtSql
mongoclient.a
bsd
ssl
crypto
boost_system
boost_thread
boost_filesystem
boost_program_options
)
CMakeLists.txt文件中没有任何地方定义的变量bioreader_common_LIBS,它不包含在缓存中。显而易见的是,它的价值是"只是一个库列表。有没有办法(可能通过命令行)返回此变量的值?
2)在谷歌搜索cmake变量后,我遇到了一个wiki页面,详细介绍了有用的cmake变量(http://www.cmake.org/Wiki/CMake_Useful_Variables)。我一直试图找到很多这些变量的价值,但运气不佳。例如,其中一个有用的变量"是CMAKE_LIBRARY_PATH。虽然在CMakeLists.txt或CMakeCache.txt文件中没有引用此变量,但似乎它应该仍然存在并且具有值,但我无法找到它?
3)运行cmake和make后遇到的最大问题之一是无法链接某些库。例如,有一个必需的sql数据库驱动程序插件(mysql),我认为它存在于位于usr / lib / mysql / plugin中的12个.so文件。我意识到我需要修改CMakeLists.txt文件以包含这些库,或者可能在某处添加路径,但我不知道该怎么做。即使我知道 where 添加库我也不确定如何在CMakeLists.txt中命名库(我认为驱动程序的名称是" mysql"但显然技术上并不是你在CMakeLists.txt文件中所指的那样。
我所指的CMakeLists.txt文件如下所示。对不起,如果这个问题看起来很愚蠢,但我完全迷失了,感到非常沮丧。
cmake_minimum_required(VERSION 2.4)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
project (bioreader)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/;${CMAKE_MODULE_PATH}")
# Find Qt libraries
INCLUDE(FindQt4) # will find QMake moc includes and libraries for us
INCLUDE(${QT_USE_FILE})
FIND_PACKAGE(Qt4 REQUIRED)
LINK_DIRECTORIES(${QT_LIBRARY_DIR})
# Find MongoDB libraries
FIND_PACKAGE(MongoDB REQUIRED)
# Find Boost libraries
FIND_PACKAGE(Boost REQUIRED)
# Custom dependencies
INCLUDE(AddFileDependencies)
# Qt/Qtopia
include (${QT_USE_FILE})
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtCore/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtGui/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtNetwork/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtScript/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtScriptTools/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtTest/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtXml/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtDBus/)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtSql/)
# Optimized?
OPTION (OPTIMIZED "Compile in the optimized mode?" ON)
OPTION (ATOM "Optimize for Intel Atom 32-bit?" OFF)
OPTION (PROFILING "Add profiling information to executable?" OFF)
ADD_DEFINITIONS (-Wall -fno-strict-aliasing -Wno-strict-aliasing)
IF(OPTIMIZED)
ADD_DEFINITIONS (-O3)
IF (ATOM)
ADD_DEFINITIONS (-m32 -march=core2 -mtune=pentium -mfpmath=sse)
ENDIF (ATOM)
ELSE(OPTIMIZED)
ADD_DEFINITIONS (-g)
ENDIF(OPTIMIZED)
IF(PROFILING)
ADD_DEFINITIONS (-pg)
ENDIF(PROFILING)
# Ban exceptions? (used only for testing/refactoring)
OPTION (KILL_EXCEPTIONS "Disable support for exceptions?" OFF)
IF (KILL_EXCEPTIONS)
ADD_DEFINITIONS(-fno-exceptions)
ENDIF(KILL_EXCEPTIONS)
# Attempt to compile the code with ALL warnings enabled (ie. "pedantic
# mode")?
OPTION (PEDANTIC_MODE "Compile with all compiler warnings enabled?" ON)
IF (PEDANTIC_MODE)
ADD_DEFINITIONS (-pedantic -Wno-long-long -DUSING_PEDANTIC_MODE)
ENDIF (PEDANTIC_MODE)
# Linear algebra library
OPTION (LAPACK "Use LAPACK linear algebra library" ON)
IF(LAPACK)
MESSAGE(STATUS "Building using LAPACK.")
ADD_DEFINITIONS (-DUSING_LAPACK)
ELSE(LAPACK)
MESSAGE(STATUS "Building WITHOUT using LAPACK.")
ENDIF(LAPACK)
# Package subdirectories. These statements load the CMakeLists.txt files
# from the subordinate directories.
##
add_subdirectory (src/IO)
add_subdirectory (src/Instrument)
add_subdirectory (src/Protocol)
add_subdirectory (src/Script)
add_subdirectory (src/Physical)
add_subdirectory (rc/data)
add_subdirectory (rc/jslib)
add_subdirectory (rc/gfx)
add_subdirectory (rc/svninfo)
# Set up generic includes
include_directories (${bioreader_SOURCE_DIR})
include_directories (${bioreader_SOURCE_DIR}/src)
link_directories (${bioreader_BINARY_DIR})
link_directories (/usr/lib)
##
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
SET (bioreader_common_LIBS
Instrument
rcjslibCore
rcjslibBioScript
rcjslibRobot
rcgfx
rcsvninfo
rcdata
Physical
PhysicalController
PhysicalUnit
Protocol
IO
IOqextserialport
)
SET(bioreader_common_LIBS
${bioreader_common_LIBS}
QtCore
QtScript
QtScriptTools
QtNetwork
QtGui
QtTest
QtXml
QtDBus
QtSql
mongoclient.a
bsd
ssl
crypto
boost_system
boost_thread
boost_filesystem
boost_program_options
)
IF(LAPACK)
SET (bioreader_common_LIBS
${bioreader_common_LIBS}
lapack
blas
gfortran)
ENDIF(LAPACK)
SET (bioreader_reader_LIBS
InstrumentBuilderReader
InstrumentBuilderUnitTest
ProtocolTest
InstrumentTest
PhysicalControllerTest
PhysicalUnitTest
InstrumentBioTest
InstrumentBio
Script
PhysicalPump
PhysicalElevator
PhysicalMotor
PhysicalRobot
${bioreader_common_LIBS}
)
##
## BIOSCALE_QUICKAPP APPNAME SOURCES src1.cpp src2.cpp LIBS
##
MACRO(BIOSCALE_QUICKAPP APPNAME)
SET(__MODE "SOURCES") # default
FOREACH(ARG ${ARGN})
IF( ${ARG} STREQUAL "SOURCES" )
SET(__MODE "SOURCES")
ELSEIF( ${ARG} STREQUAL "LIBS" )
SET(__MODE "LIBS")
ELSE( ${ARG} STREQUAL "SOURCES" )
##
## source
##
IF( ${__MODE} STREQUAL "SOURCES")
SET(${APPNAME}_SRCS ${${APPNAME}_SRCS} ${ARG}) # append to var
ENDIF( ${__MODE} STREQUAL "SOURCES")
##
## libs
##
IF( ${__MODE} STREQUAL "LIBS")
SET(${APPNAME}_LIBS ${${APPNAME}_LIBS} ${ARG}) # append to var
ENDIF( ${__MODE} STREQUAL "LIBS")
ENDIF( ${ARG} STREQUAL "SOURCES" )
ENDFOREACH(ARG)
QT4_AUTOMOC(${${APPNAME}_SRCS})
add_executable(${APPNAME} ${${APPNAME}_SRCS})
target_link_libraries(${APPNAME} ${${APPNAME}_LIBS})
ENDMACRO(BIOSCALE_QUICKAPP)
## Configuration for all targets
SET (bioreader_SRCS src/universal.cpp)
# Executable target for unit tests
BIOSCALE_QUICKAPP (unittest
SOURCES ${bioreader_SRCS}
LIBS ${bioreader_reader_LIBS})
# Executable target for reader
BIOSCALE_QUICKAPP (reader
SOURCES ${bioreader_SRCS}
LIBS ${bioreader_reader_LIBS})
IF(PROFILING)
SET_TARGET_PROPERTIES(reader PROPERTIES LINK_FLAGS -pg)
ENDIF(PROFILING)
答案 0 :(得分:0)
这是一个很重要的帖子,我可能无法一次性回答所有这些问题。但是,我将从顶部开始并尝试回答我遇到的问题。似乎任何理解都会让你比你更远。谁知道,也许我甚至会回答真正的问题。
Q1)“CMakeLists.txt文件中没有任何地方是变量bioreader_common_LIBS已定义”
A1) SET(bioreader_common_LIBS $ {bioreader_common_LIBS} QtCore QtScript ....) 正在定义bioreader_common_LIBS。 set set正在做的是,“将bioreader_common_LIBS设置为它当前定义的任何内容(注意使用变量值的syntx $ {..}。)加上随后的内容,例如Qt libs。你可以看到如何在文件中使用相同类型的行,即附加到bioreader_common_LIBS的当前值
Q2)bioreader_common_LIBS已定义且未包含在缓存中。 A2)要将其添加到缓存中,设置调用看起来像.. set(bioreader_common_LIBS $ {bioreader_common_LIBS} lib1 lib2 CACHE STRING“”)
Q3 A3)'有用的CMake变量'在适当的时候由CMake设置,并且在你的CMakeLists.txt中不一定存在,除非你将它们设置为你需要的东西。您想要查看任何变量的值,请尝试,例如 消息(“var_name:$ {var_name}”) 查看var_name的值。配置项目时将打印这些消息。
Q4)剩下的...... A4)要记住的一件事是,每个子目录都有一个CMakeLists.txt文件,用于控制配置/构建库中的文件。
要查找您的库,请在您的CMakeLists中按照Boost示例进行操作。使用带有正确包名的find_package(MySQL REQUIRED)调用。您可以在CMake_install_directory / Modules中找到CMake提供的模块。如果没有,那么你需要写它。当成功时,查找模块提供了几个有用的变量。它们通常在文件中描述,但大致你会得到(使用MySQL作为示例)MySQL_FOUND - 告诉CMake是否找到它,MySQL_INCLUDE_DIR - 标题的路径,MySQL_LIBRARIES和/或MySQL_LIBRARY - 库的名称,MySQL_LIB_DIR - 库目录。
现在,您可以在CMake文件include_directories中看到,您可以添加 include_directories($ {} MySQL_INCLUDE_DIR) 到你的项目将它添加到编译器args的-I。您可以使用 link_directories($ {} MySQL_LIB_DIR) 添加该目录以进行链接。现在,要链接您的图书馆,请致电 target_link_libraries(my_lib $ {MySQL_LIBRARIES})
有一点需要注意,您当前的CMake文件有一些不良习惯,即它明确地将库命名为linke。不建议这样做,因为它会严格限制你对图书馆提供商的突发奇想。名称可以更改,因此您最好始终使用从查找模块中提供的变量。此外,我不相信你需要添加 link_directories(/ usr / lib) 因为那个目录通常已经在默认的搜索路径中了,不过我觉得拥有它不会有什么坏处。
这应该让你朝着正确的方向前进,我为一次坐着打了太多。