最近在学习linux,就以unbutu起手来学习各种命令,都说linux编程的优势要大于Windows,抱着试一试的心态想着把Windows的代码移植到unbutu上,因为使用的SDL,所以也就存在移植的可能性。第一步就是要安装相应的依赖库,一般情况下会用到SDL2 SDL2_image SDL2_mixer SDL2_ttf SDL2_gfx等。有两种安装方法:
1.去官网下载对应的压缩包,*.tar.gz或者是*.zip的源代码。
这个方法需要解压后自己编译,而且有的还需要依赖库,比如SDL2_ttf需要freetype2库,在安装之前需要已经安装对应的依赖,然后再在解压目录中执行。可以先执行./configure来确定依赖库的安装
#主要是检测环境,相关库是否安装,然后生成Makefile
./configure
make
make install
make install需要root权限,因为对于linux的distribution来说,所谓的安装,只是把对应的文件放到对应的目录,如头文件放在/usr/include目录下,库文件放在/usr/lib/目录下。安装完成后可以自行查找对应头文件和库文件的安装路径,如
#更新数据库
updatedb
locate libSDL
首先更新数据库,然后查找,我的机器得到的查找路径如下:
另外一个则是使用find,这里不多介绍。locate的查找速度要大于find的查找速度,因为find是真正的到硬盘中查找,而locate则是在数据库中进行查找,而updatedb(需要root权限)则是主动更新对应的数据库
2.使用APT超级牛力 (需要联网)
APT相当来说比较简单,它在安装时会检测是否有依赖,如果有,则先安装依赖。当不太确定是否存在对应的源时,可以先进行查找
apt search libsdl2-dev
这个命令是查找是否存在对应的关键字带有libsdl2-dev的源,dev表示develop。安装SDL相关库则是
sudo apt install libsdl2-dev
sudo apt install libsdl2-image-dev
sudo apt install libsdl2-mixer-dev
sudo apt install libsdl2-ttf-dev
sudo apt install libsdl2-gfx-dev
命令执行完后,则安装成功。
安装完成后就可以使用SDL了,对于一般的只有几个源文件的工程来说,可以直接使用gcc/g++在命令行上编译,而对应大的工程则可以使用Makefile、cmake等。我个人倾向于cmake,cmake相当于又封装了一层,一般情况下则是手工编写cmake,然后根据编写的规则生成对应的Makefile,然后再根据Makefile进行编译。使用cmake需要先进行安装
sudo apt install cmake
因为是测试SDL,所以main.cpp CMakeLists.txt都是在同一个文件夹下。
CMakeList.txt
#工程所需最小版本号
cmake_minimum_required(VERSION 3.10)
#工程名称
project(main)
#设置模块的搜索路径
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
#找到SDL2 如果未找到,则失败
find_package(SDL2 REQUIRED)
#添加对应的头文件搜索目录
include_directories(${SDL2_INCLUDE_DIR})
#生成可执行文件
add_executable(main main.cpp)
#链接对应的函数库
target_link_libraries(main ${SDL2_LIBRARY})
#设置生成路径在源路径下
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
cmake内置了很多变量,如CMAKE_MODULE_PATH PROJECT_SOURCE_DIR,而有些语句也会产生一些变量,就比如find_package(SDL2 REQUIRED)则会产生SDL2_INCLUDE_DIR、SDL2_LIBRARY等。
注:CMAKE_SOURCE_DIR
PROJECT_SOURCE_DIR
这三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录。
也就是在 in source 编译时,他跟 CMAKE_BINARY_DIR 等变量一致。
PROJECT_SOURCE_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的
链接:https://www.cnblogs.com/xianghang123/p/3556425.html
c/c++源文件的过程为预处理->编译->链接,预处理时需要找到对应的头文件并包含进来,而在链接的时候则是找到对应的函数的实现。熟悉Makefile的应该对上面的语句的作用有所熟悉,cmake也是要获取对应的头文件可库文件。
个人也是初用cmake,对于具体的每个语句的用法,可以参考官方cmake wiki。
值得一提的是find_package(SDL2 REQUIRED)这一句,这一句的作用就是根据FindSDL2.cmake这个文件进行查找SDL2的头文件和源文件路径,而cmake并没有给出这个模块,这个模块是SDL wiki官方教程中给出的,链接如下:
https://www.willusher.io/sdl2%20tutorials/2013/08/15/lesson-0-setting-up-sdl
FindSDL2.cmake放到了本工程的cmake文件夹下(这就是为什么要设置模块的搜索路径的原因)
FindSDL2.cmake
# Locate SDL2 library
# This module defines
# SDL2_LIBRARY, the name of the library to link against
# SDL2_FOUND, if false, do not try to link to SDL2
# SDL2_INCLUDE_DIR, where to find SDL.h
#
# This module responds to the the flag:
# SDL2_BUILDING_LIBRARY
# If this is defined, then no SDL2_main will be linked in because
# only applications need main().
# Otherwise, it is assumed you are building an application and this
# module will attempt to locate and set the the proper link flags
# as part of the returned SDL2_LIBRARY variable.
#
# Don't forget to include SDL2main.h and SDL2main.m your project for the
# OS X framework based version. (Other versions link to -lSDL2main which
# this module will try to find on your behalf.) Also for OS X, this
# module will automatically add the -framework Cocoa on your behalf.
#
#
# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration
# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library
# (SDL2.dll, libsdl2.so, SDL2.framework, etc).
# Set SDL2_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_LIBRARY
# variable, but when these values are unset, SDL2_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_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 . 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_INCLUDE_DIR SDL.h
HINTS
${SDL2}
$ENV{SDL2}
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_LIBRARY_TEMP SDL2
HINTS
${SDL2}
$ENV{SDL2}
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_LIBRARY_TEMP SDL2
HINTS
${SDL2}
$ENV{SDL2}
PATH_SUFFIXES lib
lib/x86
i686-w64-mingw32/lib
PATHS
/sw
/opt/local
/opt/csw
/opt
)
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
IF(NOT SDL2_BUILDING_LIBRARY)
IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
# Non-OS X framework versions expect you to also dynamically link to
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
# seem to provide SDL2main for compatibility even though they don't
# necessarily need it.
# Lookup the 64 bit libs on x64
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
FIND_LIBRARY(SDL2MAIN_LIBRARY
NAMES SDL2main
HINTS
${SDL2}
$ENV{SDL2}
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(SDL2MAIN_LIBRARY
NAMES SDL2main
HINTS
${SDL2}
$ENV{SDL2}
PATH_SUFFIXES lib
lib/x86
i686-w64-mingw32/lib
PATHS
/sw
/opt/local
/opt/csw
/opt
)
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
ENDIF(NOT SDL2_BUILDING_LIBRARY)
# SDL2 may require threads on your system.
# The Apple build may not need an explicit flag because one of the
# frameworks may already provide it.
# But for non-OSX systems, I will use the CMake Threads package.
IF(NOT APPLE)
FIND_PACKAGE(Threads)
ENDIF(NOT APPLE)
# MinGW needs an additional library, mwindows
# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows
# (Actually on second look, I think it only needs one of the m* libraries.)
IF(MINGW)
SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
ENDIF(MINGW)
SET(SDL2_FOUND "NO")
IF(SDL2_LIBRARY_TEMP)
# For SDL2main
IF(NOT SDL2_BUILDING_LIBRARY)
IF(SDL2MAIN_LIBRARY)
SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP})
ENDIF(SDL2MAIN_LIBRARY)
ENDIF(NOT SDL2_BUILDING_LIBRARY)
# For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
# CMake doesn't display the -framework Cocoa string in the UI even
# though it actually is there if I modify a pre-used variable.
# I think it has something to do with the CACHE STRING.
# So I use a temporary variable until the end so I can set the
# "real" variable in one-shot.
IF(APPLE)
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
ENDIF(APPLE)
# For threads, as mentioned Apple doesn't need this.
# In fact, there seems to be a problem if I used the Threads package
# and try using this line, so I'm just skipping it entirely for OS X.
IF(NOT APPLE)
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
ENDIF(NOT APPLE)
# For MinGW library
IF(MINGW)
SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
ENDIF(MINGW)
# Set the final string here so the GUI reflects the final state.
SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
SET(SDL2_FOUND "YES")
ENDIF(SDL2_LIBRARY_TEMP)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
然后再在本工程路径下创建一个build文件夹,以便于方便处理cmake生成的各种文件,之后把build设置成工作路径,之后执行:
cmake ..
make
../main
之后就是main.cpp的编写
#include
int main(int argc, char **argv)
{
SDL_Window* win = nullptr;
SDL_Renderer* ren = nullptr;
bool running = true;
SDL_Init(SDL_INIT_VIDEO);
win = SDL_CreateWindow("title", 0, 0, 640, 480, SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor(ren,255,0,0,255);
SDL_Event event = {};
while (running)
{
SDL_RenderClear(ren);
SDL_RenderPresent(ren);
SDL_Delay(50);
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:running = false; break;
}
}
}
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
return 0;
}
这里要注意下,为了避免窗口无法关闭,所以设置了一个布尔型变量来控制循环。
除了上述使用FindSDL2.cmake来查找相应的SDL库的头文件和库文件路径外,还可以手动进行指定,同样先:
updatedt
locate SDL.h
locate libSDL
来查找出SDL.h头文件和SDL相关库路径,比如在我的机器中输出如下:
如前面的路径既是我们要用到的。
之后的MakeLists.txt就如下:
cmake_minimum_required(VERSION 3.10)
#链接头文件
include_directories(/usr/include/SDL2)
#添加源文件
aux_source_directory(SDL_Engine SRC_LIST)
#创建动态库
add_executable(main ${SRC_LIST})
#添加依赖
#链接
target_link_libraries(main
SDL2
SDL2_image
SDL2_mixer
SDL2_ttf
SDL2_gfx
libz)
#设置库目录的简化
set (LIBRARY_DIR "/usr/lib/x86_64-linux-gnu")
#SDL2
add_library(SDL2 SHARED IMPORTED)
set_target_properties(SDL2 PROPERTIES IMPORTED_LOCATION ${LIBRARY_DIR}/libSDL2.so)
#SDL2_image
add_library(SDL2_image SHARED IMPORTED)
set_target_properties(SDL2_image PROPERTIES IMPORTED_LOCATION ${LIBRARY_DIR}/libSDL2_image.so)
#SDL2_mixer
add_library(SDL2_mixer SHARED IMPORTED)
set_target_properties(SDL2_mixer PROPERTIES IMPORTED_LOCATION ${LIBRARY_DIR}/libSDL2_mixer.so)
#SDL2_ttf
add_library(SDL2_ttf SHARED IMPORTED)
set_target_properties(SDL2_ttf PROPERTIES IMPORTED_LOCATION ${LIBRARY_DIR}/libSDL2_ttf.so)
#SDL2_gfx
add_library(SDL2_gfx SHARED IMPORTED)
set_target_properties(SDL2_gfx PROPERTIES IMPORTED_LOCATION ${LIBRARY_DIR}/libSDL2_gfx.so)
大致类似这样,不过这样做的坏处就是使得cmake无法跨平台,所以我个人不建议这么做。
本节代码:
https://github.com/LuckDog555/SDLProject_cmake/blob/master/test1.tar.gz