在学习FFMPEG的过程中遇到了SDL,但将SDL头文件引入ios项目的时候,发现找不到头文件 -_-!SDL加入项目是需要通用库和头文件的。
我现在的需求是一个能适配iPhone4以上机型和模拟器的通用库。
别急,先回忆一下各个机型和arm体系结构的关系:
Armv6 --- iPhone3G (都老掉牙了,亲~)
Armv7 --- iPhone3GS/4 or iPad
Armv7s --- iPhone5
Simulator --- i386(这个就不属于arm体系了)
对于打库之类的神马,我个人觉得比较麻烦,网上版本很多,解释具体原因的却很少,而且很多资料都过时了,不适应现在的需求。
不过你如果感兴趣,了解一下也是很好的,这里有一篇老外的比较新的blog: 《How to prepare your mac for ios development with ffmpeg libraries
》,
详细告诉了我们在打静态通用库(XXX.a)的步骤,就只有一个Perl脚本,算是比较基础的了。你可以从中看到一些配置项,对你以后理解各种脚本是有好处的。
这里有两个链接:
1. https://bitbucket.org/DavidLudwig/sdl/src/a325f77bae36?at=default
2. https://github.com/manifest/sdl-ios-framework
第一个链接我还没尝试过,好像是一个shell脚本,用来生成所需的通用库和头文件的。
我主要是尝试的第二个脚本,貌似是用Python写的,很好理解,只是我对其中的各种环境变量比较生疏。
贴上执行脚本的readme,说的是执行脚本的前提条件,链接里也能找到:
Depends on
tools, you could install them with homebrew brew install hg
rubygems, you could install them with sudo gem install colorize
What frameworks are available?
- SDL
- SDL_image
- SDL_mixer
- Tremor
How to use?
rake
or rake SDL :build
to download sources and build SDL.framework
rake build_all
:
to download and install all available frameworks
仔细看了一下,发现这个脚本只是用来生成适配Armv7和Simulator的通用库,可是我还需要匹配Armv7s。
没办法,硬着头皮改了一下吧。
经过一遍又一遍的尝试,终于被我改好了,附上
rakefile文件
:
#
------------------------------------------------------------------------------
# Builds a SDL framework
for
the iOS
# Copyright (c)
2011
-
2012
Andrei Nesterov
# See LICENSE
for
licensing information
#
------------------------------------------------------------------------------
#
# Creates a pseudo
-
framework which could be used to build iOS applications
for
# both simulator and device
#
#
------------------------------------------------------------------------------
#
# Depends on tools:
# hg
# git
# svn
#
# Depends on rubygems:
# colorize
#
#
------------------------------------------------------------------------------
#
# To configure the script, define:
# Conf configuration (:release or :debug)
# Arch1 architecture
for
the device
'
s library (e.g. :armv7)
# Arch2 architecture
for
the device
'
s library (e.g. :armv7s)
# SDK version number of the iOS SDK (e.g.
"
4.3
"
)
#
#
------------------------------------------------------------------------------
require
'
rubygems
'
require
'
colorize
'
require
'
find
'
#
---
Configure
----------------------------------------------------------------
module Configure
Conf
=
:release
Arch1
=
:armv7
Arch2
=
:armv7s
SDK
=
'
6.1
'
end
#
---
Constants
----------------------------------------------------------------
module Global
RootDir
=
Dir.pwd
TemplatesDir
=
"
#{RootDir}/templates
"
SourcesDir
=
"
#{RootDir}/src
"
BuildDir
=
"
#{RootDir}/build
"
end
#
---
Common
-------------------------------------------------------------------
def message(text)
tailSize
=
75
-
text.length;
puts
"
\n>>> #{text} #{'-' * (tailSize < 0 ? 0 : tailSize)}
"
.green
end
def refresystem_dir(path)
system
%
{ rm
-
rf #{path} }
if
FileTest.exists
?
path
system
%
{ mkdir
-
p #{path} }
end
module Builder
def build_library(project, dest, target, conf, sdk, arch)
dest
=
library_bundle_path(dest, conf, sdk, arch)
sdk, arch
=
compute_platform(sdk, arch)
args
=
[]
args
<<
%
{
-
sdk
"
#{sdk}
"
}
args
<<
%
{
-
configuration
"
#{conf}
"
}
args
<<
%
{
-
target
"
#{target}
"
}
args
<<
%
{
-
arch
"
#{arch.to_str}
"
}
args
<<
%
{
-
project
"
#{project}
"
}
args
<<
%
{TARGETED_DEVICE_FAMILY
=
"
1,2
"
}
args
<<
%
{BUILT_PRODUCTS_DIR
=
"
build
"
}
args
<<
%
{CONFIGURATION_BUILD_DIR
=
"
#{dest}
"
}
args
<<
%
{CONFIGURATION_TEMP_DIR
=
"
#{dest}.build
"
}
refresystem_dir dest
Dir.chdir File.dirname(project)
do
system
%
{xcodebuild #{args.join
"
"
}}
end
end
def build_framework_library(frameworkLib, deviceLib1, deviceLib2, simulatorLib)
refresystem_dir(File.dirname(frameworkLib))
system
%
{lipo
-
create #{deviceLib1} #{deviceLib2} #{simulatorLib}
-
o #{frameworkLib}}
end
def build_framework(name, version, identifier, dest, headers, project, target, conf, sdk, arch1, arch2)
build_library(project, dest, target, conf, sdk, arch1);
build_library(project, dest, target, conf, sdk, arch2);
build_library(project, dest, target, conf, sdk, :i386);
libFileName
=
nil
Find.find(library_bundle_path(dest, conf, sdk, arch1))
do
|
path
|
libFileName
=
File.basename(path)
if
path
=~
/
\A.
*
\.a\z
/
end
Find.find(library_bundle_path(dest, conf, sdk, arch2))
do
|
path
|
libFileName
=
File.basename(path)
if
path
=~
/
\A.
*
\.a\z
/
end
libFilePath
=
"
#{dest}/universal-#{conf}/#{libFileName}
"
build_framework_library(
libFilePath,
"
#{library_bundle_path(dest, conf, sdk, arch1)}/#{libFileName}
"
,
"
#{library_bundle_path(dest, conf, sdk, arch2)}/#{libFileName}
"
,
"
#{library_bundle_path(dest, conf, sdk, :i386)}/#{libFileName}
"
)
create_framework(name, version, identifier, dest, headers, libFilePath)
end
def create_framework(name, version, identifier, dest, headers, lib)
frameworkVersion
=
"
A
"
frameworkBundle
=
framework_bundle_path(dest, name)
# creating framework
'
s directories
refresystem_dir frameworkBundle
system
%
{ mkdir
"
#{frameworkBundle}/Versions
"
}
system
%
{ mkdir
"
#{frameworkBundle}/Versions/#{frameworkVersion}
"
}
system
%
{ mkdir
"
#{frameworkBundle}/Versions/#{frameworkVersion}/Resources
"
}
system
%
{ mkdir
"
#{frameworkBundle}/Versions/#{frameworkVersion}/Headers
"
}
system
%
{ mkdir
"
#{frameworkBundle}/Versions/#{frameworkVersion}/Documentation
"
}
# creating framework
'
s symlinks
system
%
{ ln
-
s
"
#{frameworkVersion}
"
"
#{frameworkBundle}/Versions/Current
"
}
system
%
{ ln
-
s
"
Versions/Current/Headers
"
"
#{frameworkBundle}/Headers
"
}
system
%
{ ln
-
s
"
Versions/Current/Resources
"
"
#{frameworkBundle}/Resources
"
}
system
%
{ ln
-
s
"
Versions/Current/Documentation
"
"
#{frameworkBundle}/Documentation
"
}
system
%
{ ln
-
s
"
Versions/Current/#{File.basename lib}
"
"
#{frameworkBundle}/#{name}
"
}
# copying lib
system
%
{ cp
"
#{lib}
"
"
#{frameworkBundle}/Versions/#{frameworkVersion}
"
}
# copying includes
FileList[
"
#{headers}/*.h
"
].each
do
|
source
|
system
%
{ cp
"
#{source}
"
"
#{frameworkBundle}/Headers
"
}
end
# creating plist
File.open(
"
#{frameworkBundle}/Resources/Info.plist
"
,
"
w
"
)
do
|
f
|
f.puts
'
DOCTYPE plist PUBLIC
"
-//Apple//DTD PLIST 1.0//EN
"
"
http://www.apple.com/DTDs/PropertyList-1.0.dtd
"
>
<
plist version
=
"
1.0
"
>
'
f.puts
"
<
key
>
CFBundleDevelopmentRegion
key
>
<
string
>
Englisystem
string
>
<
key
>
CFBundleExecutable
key
>
<
string
>
#{name}
string
>
<
key
>
CFBundleIdentifier
key
>
<
string
>
#{identifier}
string
>
<
key
>
CFBundleInfoDictionaryVersion
key
>
<
string
>
6.0
string
>
<
key
>
CFBundlePackageType
key
>
<
string
>
FMWK
string
>
<
key
>
CFBundleSignature
key
>
<
string
>????
string
>
<
key
>
CFBundleVersion
key
>
<
string
>
#{version}
string
>
dict
>
plist
>
"
end
end
def library_bundle_path(path, conf, sdk, arch)
sdk, arch
=
compute_platform(sdk, arch)
"
#{path}/#{sdk}-#{arch}-#{conf}
"
end
def framework_bundle_path(path, name)
"
#{path}/#{name}.framework
"
end
def compute_platform(sdk, arch)
return
[sdk, arch]
if
arch.
class
==
String
[arch
==
:i386
?
"
iphonesimulator
"
+
sdk :
"
iphoneos
"
+
sdk, arch.to_s]
end
private
:library_bundle_path, :framework_bundle_path, :compute_platform
end
#
---
Package
------------------------------------------------------------------
class
Package
extend Builder
def self.build(conf, sdk, arch1, arch2)
download
unpack
install(config(conf), sdk, arch1, arch2)
end
def self.unpack
end
def self.config conf
conf
==
:release
?
"
Release
"
:
"
Debug
"
end
end
#
---
SDL
----------------------------------------------------------------------
class
SDL
<
Package
ProjFile
=
"
SDL.xcodeproj
"
SourcesDir
=
(FileTest.exists
?
ProjFile)
?
"
#{Global::RootDir}/../..
"
:
"
#{Global::SourcesDir}/SDL
"
BuildDir
=
"
#{Global::BuildDir}/sdl
"
Version
=
"
2.0
"
def self.download
message
"
downloading SDL
"
system
%
{hg clone
"
http://hg.libsdl.org/SDL
"
"
#{SourcesDir}
"
}
end
def self.install(conf, sdk, arch1, arch2)
message
"
building SDL
"
self.build_framework(
"
SDL
"
,
Version,
"
org.libsdl
"
,
BuildDir,
"
#{SourcesDir}/include
"
,
"
#{SourcesDir}/Xcode-iOS/SDL/#{ProjFile}
"
,
"
libSDL
"
,
conf,
sdk,
arch1,
arch2
)
end
end
#
---
SDL_image
----------------------------------------------------------------
class
SDL_image
<
Package
SourcesDir
=
"
#{Global::SourcesDir}/sdl_image
"
BuildDir
=
"
#{Global::BuildDir}/sdl_image
"
Version
=
"
1.2.12
"
def self.download
message
"
downloading SDL_image
"
system
%
{hg clone
"
http://hg.libsdl.org/SDL_image
"
"
#{SourcesDir}
"
}
end
def self.install(conf, sdk, arch1, arch2)
message
"
building SDL_image
"
self.build_framework(
"
SDL_image
"
,
Version,
"
org.libsdl
"
,
BuildDir,
"
#{SourcesDir}
"
,
"
#{SourcesDir}/Xcode-iOS/SDL_image.xcodeproj
"
,
"
libSDL_image
"
,
conf,
sdk,
arch1,
arch2
)
end
end
#
---
SDL_mixer
----------------------------------------------------------------
class
SDL_mixer
<
Package
SourcesDir
=
"
#{Global::SourcesDir}/sdl_mixer
"
BuildDir
=
"
#{Global::BuildDir}/sdl_mixer
"
Version
=
"
1.2.12
"
def self.download
message
"
downloading SDL_mixer
"
system
%
{hg clone
"
http://hg.libsdl.org/SDL_mixer
"
"
#{SourcesDir}
"
}
end
def self.install(conf, sdk, arch1, arch2)
message
"
creating links on vorbis headers for successful SDL_mixer building
"
refresystem_dir(headersDir
=
"
#{Global::SourcesDir}/libtremor
"
)
system
%
{ ln
-
s
"
#{Tremor::BuildDir}/vorbis.framework/Headers
"
"
#{headersDir}/ogg
"
}
system
%
{ ln
-
s
"
#{Tremor::BuildDir}/vorbis.framework/Headers
"
"
#{headersDir}/tremor
"
}
message
"
building SDL_mixer
"
self.build_framework(
"
SDL_mixer
"
,
Version,
"
org.libsdl
"
,
BuildDir,
"
#{SourcesDir}
"
,
"
#{SourcesDir}/Xcode-iOS/SDL_mixer.xcodeproj
"
,
"
Static Library
"
,
conf,
sdk,
arch1,
arch2
)
system
%
{ rm
-
rf #{headersDir} }
end
end
#
---
Tremor
-------------------------------------------------------------------
class
Tremor
<
Package
SourcesDir
=
"
#{Global::SourcesDir}/cocos2d
"
BuildDir
=
"
#{Global::BuildDir}/tremor
"
Version
=
"
1.3.2
"
def self.download
message
"
downloading Cocos2d
"
system
%
{git clone
"
https://github.com/cocos2d/cocos2d-iphone.git
"
"
#{SourcesDir}
"
}
end
def self.install(conf, sdk, arch1, arch2)
message
"
switching to v1.x brunch
"
Dir.chdir(SourcesDir)
do
system
'
git checkout master
'
end
message
"
building Tremor
"
self.build_framework(
"
vorbis
"
,
Version,
"
org.xiph
"
,
BuildDir,
"
#{SourcesDir}/external/Tremor
"
,
"
#{SourcesDir}/cocos2d-ios.xcodeproj
"
,
"
vorbis
"
,
conf,
sdk,
arch1,
arch2
)
end
end
#
---
Tasks
--------------------------------------------------------------------
require
'
rake/clean
'
Libs
=
[:SDL, :SDL_image, :Tremor, :SDL_mixer]
desc
"
Download sources and build SDL.framework
"
task :
default
=>
[
"
SDL:build
"
]
do
end
desc
"
Download sources and build all targets [#{Libs.join
"
,
"
}]
"
task :build_all
do
Libs.each
do
|
classname
|
Object.const_get(classname).build Configure::Conf, Configure::SDK, Configure::Arch1, Configure::Arch2
end
end
Libs.each
do
|
classname
|
namespace
classname
do
obj
=
Object.const_get(classname)
desc
"
Download sources and build #{classname}.framework
"
task :build
do
obj.build Configure::Conf, Configure::SDK, Configure::Arch1, Configure::Arch2
end
desc
"
Only download #{classname} sources
"
task :download
do
obj.download
obj.unpack
end
desc
"
Only build #{classname}.framework
"
task :install
do
obj.install Configure::Conf, Configure::SDK, Configure::Arch1, Configure::Arch2
end
desc
"
Remove all files associated with #{classname}
"
task :clobber
do
CLOBBER
=
Rake::FileList.
new
CLOBBER.include obj::SourcesDir, obj::BuildDir
Rake::Task[:clobber].execute
end
end
end
CLOBBER.include Global::SourcesDir, Global::BuildDir
一切都是自动化安装,
稍微注意一下的是自己的sdk版本,我的是6.1。
还有最后一个小问题,SDL需要4个framework支持:
CoreGraphics
QuartzCore
OpenGLES
AudioToolbox
所以ios项目也要对应的引入这4个framework。