在Windows上链接外部库CMakeLists.txt

时间:2018-01-10 12:05:07

标签: c++ boost cmake sfml

我正在尝试实现一个CMakeLists.txt来在Linux和Windows下编译我的项目。我使用两个库:SFML和boost。但是,我希望我的项目可以在Linux或Windows下构建,而无需安装用户的库。

我解释一下。库SFML和boost被编译并放在我的文件夹项目中,我希望无论在哪台计算机上下载我的项目,我都可以构建它。

这是我的问题,我无法从我的文件夹项目中的libraries文件夹,SFML和boost库中外部链接。

这是我的CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)

project(r-type_client CXX)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")

include_directories(./boost/include
        ./SFML/include
        ./include
        )

if(UNIX)

set(BOOST_LIBRARY
-L./boost/linux
-lboost_regex
)

set(SFML_LIBRARY
-L./SFML/linux
-lsfml-graphics
-lsfml-window
-lsfml-system
)

add_executable(r-type_client
       srcs/Main.cpp
       )

target_link_libraries(r-type_client
          ${BOOST_LIBRARY}
          ${SFML_LIBRARY}
          )

elseif(WIN32)

add_library(bar SHARED IMPORTED)
set_property(TARGET bar PROPERTY IMPORTED_LOCATION        
C:/Users/Hugo/Downloads/Old/client/SFML/windows/sfml-graphics.dll)
set_property(TARGET bar PROPERTY IMPORTED_IMPLIB         
C:/Users/Hugo/Downloads/Old/client/SFML/windows/sfml-graphics.lib)
add_library(bor SHARED IMPORTED)
set_property(TARGET bor PROPERTY IMPORTED_LOCATION 
C:/Users/Hugo/Downloads/Old/client/SFML/windows/sfml-window.dll)
set_property(TARGET bor PROPERTY IMPORTED_IMPLIB 
C:/Users/Hugo/Downloads/Old/client/SFML/windows/sfml-window.lib)
add_library(bur SHARED IMPORTED)
set_property(TARGET bur PROPERTY IMPORTED_LOCATION 
C:/Users/Hugo/Downloads/Old/client/SFML/windows/sfml-system.dll)
set_property(TARGET bur PROPERTY IMPORTED_IMPLIB 
C:/Users/Hugo/Downloads/Old/client/SFML/windows/sfml-system.lib)
add_executable(r-type_client srcs/Main.cpp)
target_link_libraries(r-type_client bar bor bur)

endif(UNIX)

1 个答案:

答案 0 :(得分:2)

正如我在评论中提到的那样,您应该使用find_package()正确地找到所有内容,以正确的方式设置您的CMake项目。

CMake是一种工具,允许人们无论主机系统如何即时创建编译所需的文件。通过硬编码路径和(不需要的)每个平台分支,你基本上否定了CMake的整个目的。

要在CMake中包含第三方库,您通常需要使用find_package(),其中包括正确定位库和设置变量的必要逻辑(它基本上是您所做的)到目前为止手工完成。)

让我们为SFML做这件事,因为它对于Boost来说基本相同(我并没有真正让Boost准备好测试所有内容,因为变量名称可能因项目而异)。

首先,您告诉CMake您的项目想要使用SFML:

find_package(SFML)

根据实际的"包",你可以扩展它。在SFML的情况下,我们甚至可以定义我们想要的最小版本以及我们实际想要使用的子库:

find_package(SFML 2.3 COMPONENTS graphics window system REQUIRED)

REQUIRED标记使整个事情成为强制性标记,即如果找不到则会导致CMake错误。

一旦这条线成功,它将使用正确的路径和库设置一些变量,然后我们可以在定义目标时使用它们:

include_directories(${SFML_INCLUDE_DIR})
add_executable(myprogram ${MY_SOURCE_FILES})
target_link_libraries(myprogram ${SFML_LIBRARIES} ${SFML_DEPENDENCIES})

你已经完成了。如您所见,我可以在不到10行的情况下设置CMake项目,而无需任何特定于平台的路径,代码或知识。

但是,在运行此操作时,您很可能会遇到一个错误:

默认情况下,CMake可能无法找到FindSFML.cmake文件并抱怨。

您将在cmake路径下的SFML目录中找到此文件。将其复制到您的项目并告诉CMake在哪里查找它,例如:

set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

一旦完成此操作,CMake可能无法找到实际的SFML文件,尤其是在Windows上。要告诉它在哪里查找,您在调用CMake时定义SFML_ROOT

cmake -DSFML_ROOT=C:/Users/Hugo/Downloads/Old/client/SFML path/to/source

这为您提供了一个很大的优势,即您不必硬编码SFML(或任何其他库,如Boost)的路径。在您的Linux机器上,您通常不会提供任何路径,一切都应该开箱即用。