SDL2 cmake配置

  • Post author:
  • Post category:其他


好久没有上来写博客了,经历了股市的牛熊转换,一不小心就被割了韭菜。今天总算可以冷静下来写篇博客了。



内容提要

SDL2是用C语言写的跨平台的多媒体库,而且支持多种语言(话说支持go语言,真是难得啊,改天可以玩玩)。

今天主要吐槽下Windows+mingw+sdl2开发库的cmake配置。



环境配置

  1. 下载windows的mingw安装包,官网地址:http://www.mingw-w64.org
  2. 下载SDL2 选择mingw版本 https://www.libsdl.org/download-2.0.php
  3. 下载SDL2_image、SDL2_ttf等依赖库,这里就不一一列举了,必应一下,你就知道。
  4. 至于IDE的选择看个人喜好了,我个人偏好clion(受了Android Studio的毒害啊,快捷键方便的很,几乎无缝切换)



问题浮现

添加cmake的配置真是一坑填完又添新坑,…(为了文明起见,此处省略 n * 3个文字)。



坑1

首先是添加SDL2这个基础库,本来以为只需要

find_package(SDL2 REQUIRED)
link_libraries(SDL2)

就能解决。

结果cmake build的时候一直报错

undefined reference to WinMain


link的时候找不到WinMain这个方法,很明显就是缺少了依赖啊。


解决


经过多次尝试,发现需要显式添加SDL2_LIBRARES

find_package(SDL2 REQUIRED)
add_executable(hello main.c)
target_link_libraries(hello
		${SDL2_LIBRARIES}
)



坑2

依葫芦画瓢,添加sdl_image依赖库

find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
link_libraries(SDL2_image)
add_executable(hello main.c)
target_link_libraries(hello
		${SDL2_LIBRARIES}

结果可想而知,刷新cmake的时候就报错了

CMake Error at CMakeLists.txt:8 (find_package):
  By not providing "FindSDL2_image.cmake" in CMAKE_MODULE_PATH this project
  has asked CMake to find a package configuration file provided by
  "SDL2_image", but CMake did not find one.

  Could not find a package configuration file provided by "SDL2_image" with
  any of the following names:

    SDL2_imageConfig.cmake
    sdl2_image-config.cmake

  Add the installation prefix of "SDL2_image" to CMAKE_PREFIX_PATH or set
  "SDL2_image_DIR" to a directory containing one of the above files.  If
  "SDL2_image" provides a separate development package or SDK, be sure it has
  been installed.

大概意思就说没有FindSDL2_image.cmake的文件,也没有配置文件SDL2_imageConfig.cmake。那为什么find_package能找到SDL2,怎么就不能找到SDL2_image呢?

原来SDL2里面自带了cmake配置,SDL2_image这个模块没有给配置文件,所以find_pacake命令不知道去哪里找,理所当然找不到啊(find_package一脸委屈)。


解决


既然知道了原因,那就好办了,要么我们给他配置一个cmake文件,要么我们就‘…(欲知后事如何,请看下面分解)

  1. 方法一 配置cmake

    这个稍微有点麻烦,可以根据SDL2的cmake配置,在SDL2的cmake里面新建文件夹SDL2_image,里面再创建SDL2_imageConfig.cmake,
# Locate SDL2_image library
# This module defines
# SDL2_IMAGE_LIBRARY, the name of the library to link against
# SDL2_IMAGE_FOUND, if false, do not try to link to SDL2_image
# SDL2_IMAGE_INCLUDE_DIR, where to find SDL_image.h
#
# Additional Note: If you see an empty SDL2_IMAGE_LIBRARY_TEMP in your configuration
# and no SDL2_IMAGE_LIBRARY, it means CMake did not find your SDL2_Image library
# (SDL2_image.dll, libsdl2_image.so, SDL2_image.framework, etc).
# Set SDL2_IMAGE_LIBRARY_TEMP to point to your SDL2 library, and configure again.
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
# as appropriate. These values are used to generate the final SDL2_IMAGE_LIBRARY
# variable, but when these values are unset, SDL2_IMAGE_LIBRARY does not get created.
#
# $SDL2 is an environment variable that would
# correspond to the ./configure --prefix=$SDL2
# used in building SDL2.
# l.e.galup 9-20-02
#
# Modified by Eric Wing.
# Added code to assist with automated building by using environmental variables
# and providing a more controlled/consistent search behavior.
# Added new modifications to recognize OS X frameworks and
# additional Unix paths (FreeBSD, etc).
# Also corrected the header search path to follow "proper" SDL2 guidelines.
# Added a search for SDL2main which is needed by some platforms.
# Added a search for threads which is needed by some platforms.
# Added needed compile switches for MinGW.
#
# On OSX, this will prefer the Framework version (if found) over others.
# People will have to manually change the cache values of
# SDL2_IMAGE_LIBRARY to override this selection or set the CMake environment
# CMAKE_INCLUDE_PATH to modify the search paths.
#
# Note that the header path has changed from SDL2/SDL.h to just SDL.h
# This needed to change because "proper" SDL2 convention
# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
# reasons because not all systems place things in SDL2/ (see FreeBSD).
#
# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake
# module with the minor edit of changing "SDL" to "SDL2" where necessary. This
# was not created for redistribution, and exists temporarily pending official
# SDL2 CMake modules.
# 
# Note that on windows this will only search for the 32bit libraries, to search
# for 64bit change x86/i686-w64 to x64/x86_64-w64

#=============================================================================
# Copyright 2003-2009 Kitware, Inc.
#
# CMake - Cross Platform Makefile Generator
# Copyright 2000-2014 Kitware, Inc.
# Copyright 2000-2011 Insight Software Consortium
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)

FIND_PATH(SDL2_IMAGE_INCLUDE_DIR SDL_image.h
	HINTS
	${SDL2}
	$ENV{SDL2}
	$ENV{SDL2_IMAGE}
	PATH_SUFFIXES include/SDL2 include SDL2
	i686-w64-mingw32/include/SDL2
	x86_64-w64-mingw32/include/SDL2
	PATHS
	~/Library/Frameworks
	/Library/Frameworks
	/usr/local/include/SDL2
	/usr/include/SDL2
	/sw # Fink
	/opt/local # DarwinPorts
	/opt/csw # Blastwave
	/opt
)

# Lookup the 64 bit libs on x64
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
	FIND_LIBRARY(SDL2_IMAGE_LIBRARY_TEMP
		NAMES SDL2_image
		HINTS
		${SDL2}
		$ENV{SDL2}
		$ENV{SDL2_IMAGE}
		PATH_SUFFIXES lib64 lib
		lib/x64
		x86_64-w64-mingw32/lib
		PATHS
		/sw
		/opt/local
		/opt/csw
		/opt
	)
# On 32bit build find the 32bit libs
ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
	FIND_LIBRARY(SDL2_IMAGE_LIBRARY_TEMP
		NAMES SDL2_image
		HINTS
		${SDL2}
		$ENV{SDL2}
		$ENV{SDL2_IMAGE}
		PATH_SUFFIXES lib
		lib/x86
		i686-w64-mingw32/lib
		PATHS
		/sw
		/opt/local
		/opt/csw
		/opt
	)
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)

SET(SDL2_IMAGE_FOUND "NO")
	IF(SDL2_IMAGE_LIBRARY_TEMP)
	# Set the final string here so the GUI reflects the final state.
	SET(SDL2_IMAGE_LIBRARY ${SDL2_IMAGE_LIBRARY_TEMP} CACHE STRING "Where the SDL2_image Library can be found")
	# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
	SET(SDL2_IMAGE_LIBRARY_TEMP "${SDL2_IMAGE_LIBRARY_TEMP}" CACHE INTERNAL "")
	SET(SDL2_IMAGE_FOUND "YES")
ENDIF(SDL2_IMAGE_LIBRARY_TEMP)

INCLUDE(FindPackageHandleStandardArgs)

FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_IMAGE REQUIRED_VARS SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR)


这里直接使用全球最大同性交友网站上一个热心市民的配置

(感谢作者的无私分享),下面为作者仓库地址 https://github.com/LuckDog555/SDLProject_cmake


这样就可以了!

2. 方法二 使用find_library

既然find_package找不到,那我们就换条思路,简单粗暴的使用find_library!

find_package(SDL2 REQUIRED)
find_library(NAME SDL2_image REQUIRED)
link_libraries(SDL2_image)
add_executable(hello main.c)
target_link_libraries(hello
		${SDL2_LIBRARIES}

直接

find_library(NAME SDL2_image REQUIRED)

然后

link_libraries(SDL2_image)

就搞定了!



结语

当然了,添加依赖库,cmake里面有好多姿势,今天的讲(装)解(逼)就到此为止了。如果哪位朋友遇到cmake配置的坑,欢迎留言分享哦!



版权声明:本文为victor888886原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。