管理CMake变量

时间:2014-07-24 16:47:51

标签: cmake

我对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)

1 个答案:

答案 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) 因为那个目录通常已经在默认的搜索路径中了,不过我觉得拥有它不会有什么坏处。

这应该让你朝着正确的方向前进,我为一次坐着打了太多。