CMake 語(yǔ)法 - 詳解 CMakeLists.txt

關(guān)于 《Android 開(kāi)發(fā)者需要知道的 Linux 知識(shí)》與 《從 Linux 內(nèi)核的角度來(lái)看 Binder 驅(qū)動(dòng)》兩篇文章被鎖定,官方申訴也未給予回復(fù)桦他,大家可以看這里:
https://blog.csdn.net/z240336124/article/details/89451641
https://blog.csdn.net/z240336124/article/details/90137352

CMake 是一個(gè)跨平臺(tái)的安裝(編譯)工具搔预,可以用簡(jiǎn)單的語(yǔ)句來(lái)描述所有平臺(tái)的安裝(編譯過(guò)程)霹期。他能夠輸出各種各樣的 Makefile 或者 project 文件,CMake 并不直接建構(gòu)出最終的軟件拯田,而是產(chǎn)生標(biāo)準(zhǔn)的建構(gòu)檔(如 Makefile 或 projects)历造。

以前做 NDK 開(kāi)發(fā)都是基于 Android.mk、Application.mk 來(lái)構(gòu)建項(xiàng)目的船庇,但從 AS 2.2 之后便開(kāi)始采用 CMake 的這種方式來(lái)構(gòu)建吭产,采用 CMake 相比與之前的 Android.mk、Application.mk 方便簡(jiǎn)單了許多鸭轮。但公司有一些古老的項(xiàng)目還是采用 Android.mk 和 Application.mk 來(lái)構(gòu)建的臣淤,因此大家還是有必要花些時(shí)間去了解這種構(gòu)建方式。但重心得放在 CMake 的構(gòu)建方式上窃爷,因此本文主要來(lái)說(shuō)說(shuō) CMake 的構(gòu)建語(yǔ)法基礎(chǔ)邑蒋。

語(yǔ)法和關(guān)鍵字要大家全部記住是不太可能的姓蜂,個(gè)人也不建議大家去死記硬背。我們只需要知道目前有哪些內(nèi)容寺董,需要生成哪些內(nèi)容即可覆糟,有不太了解甚至不知道的可以查筆記或資料刻剥。我們來(lái)詳細(xì)看下以下四個(gè)事例遮咖,相信對(duì)于以后的 CMake 構(gòu)建基本就可以不怕了。

1. 初試 cmake 的 helloworld

現(xiàn)在新建一個(gè) hello.cpp 源碼文件造虏,代碼如下:

#include <stdio.h>
int main(int argc, char* argv[]){
  printf("Hello CMake!\n");
}

之前都是采用 gcc hello.cpp -o hello 命令來(lái)生成可執(zhí)行文件御吞,但現(xiàn)在我們用 CMake 這種方式來(lái)生成,新建一個(gè) CMakeLists.txt 文件名大小寫(xiě)都按照這個(gè)來(lái):

# 指定工程名
PROJECT (HELLO)
# 現(xiàn)階段漓藕,你只需要了解 SET 指令可以用來(lái)顯式的定義變量即可
# 將 hello.cpp 賦值給 SRC_LIST 變量陶珠,也可以指定多個(gè)源文件,用空格隔開(kāi)
# SET(SRC_LIST hello.cpp add.cpp sub.cpp)
SET(SRC_LIST hello.cpp)
# 輸出打印構(gòu)建目錄
MESSAGE(STATUS "This is HELLO_BINARY_DIR " ${HELLO_BINARY_DIR})
# 輸出打印資源目錄
MESSAGE(STATUS "This is HELLO_SOURCE_DIR " ${HELLO_SOURCE_DIR})
# 輸出打印資源目錄享钞,與HELLO_SOURCE_DIR 一樣 
MESSAGE(STATUS "This is PROJECT_SOURCE_DIR " ${PROJECT_SOURCE_DIR})
# 輸出打印 CMake 資源目錄揍诽,與 PROJECT_SOURCE_DIR 一樣 
MESSAGE(STATUS "This is CMAKE_SOURCE_DIR " ${CMAKE_SOURCE_DIR})
# 生成可執(zhí)行文件 hello ,${SRC_LIST}是引用變量栗竖,也就是源文件 hello.cpp
ADD_EXECUTABLE(hello ${SRC_LIST})

新建 build 目錄暑脆,cd 到 build 目錄下,敲 cmake .. 命令狐肢,ls 一下會(huì)發(fā)現(xiàn) CMake 幫我們生成了 Makefile 等等一些文件添吗。敲 make 命令生成 hello 可執(zhí)行文件,ls 文件列表如下:

ubuntu@VM-0-9-ubuntu:~/NDK_Day88/t1/build$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  hello  Makefile

2. 構(gòu)建生成 .so 動(dòng)態(tài)庫(kù)

上面的例子看不出有啥優(yōu)勢(shì)份名,甚至說(shuō)還不如用 gcc hello.cpp -o hello 來(lái)得快碟联,但像 FFmpeg 、OpenCV 等等僵腺,類似這樣復(fù)雜的項(xiàng)目鲤孵,我們敲命令去構(gòu)建項(xiàng)目是很麻煩的。下面我們來(lái)講一個(gè)稍微復(fù)雜一點(diǎn)的例子:

mkdir 新建 3 個(gè)目錄分別為 src辰如、libs裤纹、include 。src 用來(lái)存放源文件 add.ccp丧没、sub.cpp鹰椒、div.cpp。include 用來(lái)存放頭文件 add.h呕童、div.h漆际、sub.h 。源碼如下:

#include "add.h"
int add(int num1, int num2){
        return num1 + num2;
}

#include "sub.h"                         
int sub(int num1, int num2){         
        return num1 - num2;         
}

#include "div.h"                                              
int div(int num1, int num2){                    
        return num1 / num2;                  
}

基于這些準(zhǔn)備工作夺饲,我們想用 CMake 來(lái)構(gòu)建一個(gè) libmath.so 動(dòng)態(tài)庫(kù)奸汇,并且將其生成在 libs 目錄文件夾下施符。

# 指定 cmake 最低編譯版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.14)
PROJECT (MATH)
# 把當(dāng)前工程目錄下的 src 目錄的下的所有 .cpp 和 .c 文件賦值給 SRC_LIST
# AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src SRC_LIST)
FILE(GLOB SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.cpp")
# 打印 SRC_LIST 文件列表
# MESSAGE(STATUS ${SRC_LIST})
# 指定頭文件目錄
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
# 指定輸出 .so 動(dòng)態(tài)庫(kù)的目錄位置
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
# 指定生成動(dòng)態(tài)庫(kù)
ADD_LIBRARY(math SHARED ${SRC_LIST})
# 指定生成版本號(hào),VERSION指代動(dòng)態(tài)庫(kù)版本擂找,SOVERSION指代API版本
# SET_TARGET_PROPERTIES(math PROPERTIES VERSION 1.2 SOVERSION 1)

3. 鏈接外部動(dòng)態(tài)庫(kù)和頭文件

將 libs 目錄和 include 目錄 copy 到 hello.cpp 同級(jí)目錄下戳吝,修改 hello.cpp 源碼如下:

#include <stdio.h>
#include "add.h"
#include "sub.h"
#include "div.h"

int main(int argc, char* argv[]){
        int a = 20;
        int b = 10;
        printf("%d+%d=%d\n",a,b,add(a,b));
        printf("%d-%d=%d\n",a,b,sub(a,b));
        printf("%d/%d=%d\n",a,b,div(a,b));
        return 0;
}

現(xiàn)在我引用了 include 目錄下的頭文件,同時(shí)需要鏈接 libs 目錄下的 libmath.so 贯涎,我們?cè)俅蝿?chuàng)建一個(gè) CMakeLists.txt 來(lái)生成可執(zhí)行文件 hello听哭。

# 指定cmake最低編譯版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.14)
# 指定工程的名稱
PROJECT(HELLO)
#指定頭文件目錄位置
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
#添加共享庫(kù)搜索路徑
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/lib)
#生成可執(zhí)行文件
ADD_EXECUTABLE(hello hello.cpp)
#為hello添加共享庫(kù)鏈接
TARGET_LINK_LIBRARIES(hello math)

4. 基于 FFmpeg 開(kāi)發(fā)的 CMakeLists.txt

音視頻的播放,在線直播塘雳,音視頻通話開(kāi)發(fā)陆盘,后面可能都得基于 FFmpeg 來(lái)寫(xiě)。那么首先我們需要編譯 .so 動(dòng)態(tài)庫(kù)败明,然后把動(dòng)態(tài)庫(kù)和頭文件 copy 到 AS 來(lái)開(kāi)發(fā)隘马,這里我已經(jīng)編譯好了一個(gè) 3.3.9 的版本,至于怎么寫(xiě) shell 編譯腳本妻顶,會(huì)在下篇文章中介紹酸员。目前大伙先直接拿過(guò)來(lái)用就行了。我把編譯好的 .so 動(dòng)態(tài)庫(kù)和 include 目錄拷貝到 AS 工程的 jniLibs 目錄下

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)

# 需要引入我們頭文件,以這個(gè)配置的目錄為基準(zhǔn)
include_directories(src/main/jniLibs/include)
include_directories(src/main/jniLibs/other)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

#添加共享庫(kù)搜索路徑
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi)

# 指定源文件目錄
AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src/main/cpp SRC_LIST)

add_library( 
        # Sets the name of the library.
        native-lib
        # Sets the library as a shared library.
        SHARED
        # Provides a relative path to your source file(s).
        # src/main/cpp/native-lib.cpp
        ${SRC_LIST}
        )


# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( 
        # Specifies the target library.
        # 鏈接額外的 ffmpeg 的編譯
        native-lib
        # 編解碼(最重要的庫(kù))
        avcodec-57
        # 設(shè)備信息
        avdevice-57
        # 濾鏡特效處理庫(kù)
        avfilter-6
        # 封裝格式處理庫(kù)
        avformat-57
        # 工具庫(kù)(大部分庫(kù)都需要這個(gè)庫(kù)的支持)
        avutil-55
        # 后期處理
        postproc-54
        # 音頻采樣數(shù)據(jù)格式轉(zhuǎn)換庫(kù)
        swresample-2
        # 視頻像素?cái)?shù)據(jù)格式轉(zhuǎn)換
        swscale-4

        -landroid

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

在真正實(shí)際的開(kāi)發(fā)過(guò)程中讳嘱,可能會(huì)比這些事例要復(fù)雜幔嗦,因此給的文檔大家需要用心過(guò)一遍,實(shí)際開(kāi)發(fā)過(guò)程中有些不會(huì)的呢燥,可以查閱文檔或者筆記崭添。下面我給一份真實(shí)項(xiàng)目開(kāi)發(fā)的 CMake 給大家看一下:

#-------------------------------------------------------------------
# This file is part of the CMake build system for OGRE
#     (Object-oriented Graphics Rendering Engine)
# For the latest info, see http://www.ogre3d.org/
#
# The contents of this file are placed in the public domain. Feel
# free to make use of it in any way you like.
#-------------------------------------------------------------------

######################################################################
# OGRE BUILD SYSTEM
# Welcome to the CMake build system for OGRE.
# This is the main file where we prepare the general build environment
# and provide build configuration options.
######################################################################

cmake_minimum_required(VERSION 3.3.0)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
    set(CMAKE_LINK_LIBRARY_FLAG "")
endif()

# Use relative paths
# This is mostly to reduce path size for command-line limits on windows
if(WIN32)
  # This seems to break Xcode projects so definitely don't enable on Apple builds
  set(CMAKE_USE_RELATIVE_PATHS true)
  set(CMAKE_SUPPRESS_REGENERATION true)
endif()

if (APPLE AND NOT ANDROID)
  SET(CMAKE_SIZEOF_VOID_P 4)
  set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")
  set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
  set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
  
  # otherwise apple defines a macro named check that conflicts with boost
  add_definitions(-D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0)
endif ()

project(OGRE)

# Include necessary submodules
set(CMAKE_MODULE_PATH
  "${OGRE_SOURCE_DIR}/CMake"
  "${OGRE_SOURCE_DIR}/CMake/Utils"
  "${OGRE_SOURCE_DIR}/CMake/Packages"
)

include(CMakeDependentOption)
include(MacroLogFeature)
include(OgreConfigTargets)
include(PreprocessorUtils)
set(OGRE_TEMPLATES_DIR "${OGRE_SOURCE_DIR}/CMake/Templates")
set(OGRE_WORK_DIR ${OGRE_BINARY_DIR})


#####################################################################
# Set up the basic build environment
#####################################################################

if (NOT CMAKE_BUILD_TYPE)
  # CMake defaults to leaving CMAKE_BUILD_TYPE empty. This screws up
  # differentiation between debug and release builds.
  set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: None (CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE)
endif ()

# determine Ogre version numbers
include(OgreGetVersion)
ogre_get_version(${OGRE_SOURCE_DIR}/OgreMain/include/OgrePrerequisites.h)
message(STATUS "Configuring OGRE ${OGRE_VERSION}")
# Configure version file for use by scripts
configure_file("${OGRE_TEMPLATES_DIR}/version.txt.in" "${OGRE_BINARY_DIR}/version.txt" @ONLY)

# determine if we are compiling for a 32bit or 64bit system
include(CheckTypeSize)
CHECK_TYPE_SIZE("void*" OGRE_PTR_SIZE BUILTIN_TYPES_ONLY)
if (OGRE_PTR_SIZE EQUAL 8)
  set(OGRE_PLATFORM_X64 TRUE)
else ()
  set(OGRE_PLATFORM_X64 FALSE)
endif ()

if (WIN32)
  # Create debug libraries with _d postfix
  set(CMAKE_DEBUG_POSTFIX "_d")
endif ()

# Set compiler specific build flags
if (NOT ANDROID AND UNIX OR MINGW)
  include(CheckCXXCompilerFlag)
  check_cxx_compiler_flag(-msse OGRE_GCC_HAS_SSE)
  if (OGRE_GCC_HAS_SSE)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse")
  endif ()
endif()

if(UNIX)
  # This is a set of sensible warnings that provide meaningful output
  set(OGRE_WARNING_FLAGS "-Wall -Winit-self -Wcast-qual -Wwrite-strings -Wextra -Wundef -Wmissing-declarations -Wno-unused-parameter -Wshadow -Wno-missing-field-initializers -Wno-long-long")
  if (EMSCRIPTEN)
      set(OGRE_WARNING_FLAGS "${OGRE_WARNING_FLAGS} -Wno-warn-absolute-paths")
  endif ()
  set(CMAKE_CXX_FLAGS "${OGRE_WARNING_FLAGS} ${CMAKE_CXX_FLAGS}")
endif ()
if (MSVC)
  add_definitions(-D_MT -D_USRDLL)
  # MSVC does not like Ogre::Singleton (header pragma is enough for MSVC2015+ though)
  add_definitions(/wd4661)
  if (CMAKE_BUILD_TOOL STREQUAL "nmake")
    # set variable to state that we are using nmake makefiles
    set(NMAKE TRUE)
  endif ()
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast")
  # Enable intrinsics on MSVC in debug mode
  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Oi")
  if (CMAKE_CL_64)
    # Visual Studio bails out on debug builds in 64bit mode unless
    # this flag is set...
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
    set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /bigobj")
  endif ()

  if (OGRE_PROJECT_FOLDERS)  
    # Turn on the ability to create folders to organize projects (.vcproj)
    # It creates "CMakePredefinedTargets" folder by default and adds CMake
    # defined projects like INSTALL.vcproj and ZERO_CHECK.vcproj
    set_property(GLOBAL PROPERTY USE_FOLDERS ON)
  endif()

  if (MSVC_VERSION GREATER 1500 OR MSVC_VERSION EQUAL 1500)
    option(OGRE_BUILD_MSVC_MP "Enable build with multiple processes in Visual Studio" TRUE)
  else()
    set(OGRE_BUILD_MSVC_MP FALSE CACHE BOOL "Compiler option /MP requires at least Visual Studio 2008 (VS9) or newer" FORCE)
  endif()
  if(OGRE_BUILD_MSVC_MP)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
  endif ()
  if(MSVC_VERSION GREATER 1400 OR MSVC_VERSION EQUAL 1400)
    option(OGRE_BUILD_MSVC_ZM "Add /Zm256 compiler option to Visual Studio to fix PCH errors" TRUE)
  else()
    set(OGRE_BUILD_MSVC_ZM FALSE CACHE BOOL "Compiler option /Zm256 requires at least Visual Studio 2005 (VS8) or newer" FORCE)
  endif()
  if(OGRE_BUILD_MSVC_ZM)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zm256")
  endif ()
endif ()
if (MINGW)
  add_definitions(-D_WIN32_WINNT=0x0501)
  if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
    # set architecture to i686, since otherwise some versions of MinGW can't link
    # the atomic primitives
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i686")
  endif ()
  # disable this optimisation because it breaks release builds (reason unknown)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-slp-vectorize")
  # Ignore some really annoying warnings which also happen in dependencies
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=cast-qual -Wno-unused-local-typedefs")
endif ()

include(GenerateExportHeader)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE)

if((CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") AND NOT OGRE_STATIC)
  set(OGRE_VISIBILITY_FLAGS "-DOGRE_GCC_VISIBILITY") # for legacy headers
endif()

# determine system endianess
if (MSVC OR ANDROID OR EMSCRIPTEN OR APPLE_IOS)
  # This doesn't work on VS 2010
  # MSVC only builds for intel anyway
  # all IOS devices are little endian
  set(OGRE_TEST_BIG_ENDIAN FALSE)
else()
  include(TestBigEndian)
  test_big_endian(OGRE_TEST_BIG_ENDIAN)
endif()

# Add OgreMain include path
if (APPLE_IOS)
  # Set static early for proper dependency detection
  set(OGRE_STATIC TRUE)
endif()

# definitions for samples
set(OGRE_LIBRARIES OgreMain)
set(OGRE_MeshLodGenerator_LIBRARIES OgreMeshLodGenerator)
set(OGRE_Paging_LIBRARIES OgrePaging)
set(OGRE_Terrain_LIBRARIES OgreTerrain)
set(OGRE_Volume_LIBRARIES OgreVolume)
set(OGRE_Plugin_PCZSceneManager_LIBRARIES Plugin_PCZSceneManager)
set(OGRE_Plugin_OctreeZone_LIBRARIES Plugin_OctreeZone)

# Specify build paths
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${OGRE_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${OGRE_BINARY_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OGRE_BINARY_DIR}/bin")
if (WIN32 OR APPLE)
  if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
    # We don't want to install in default system location, install is really for the SDK, so call it that
    set(CMAKE_INSTALL_PREFIX
      "${OGRE_BINARY_DIR}/sdk" CACHE PATH "OGRE install prefix" FORCE
    )
  endif (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
endif(WIN32 OR APPLE)

# Set up iOS overrides.
if (APPLE_IOS)
  set(CMAKE_EXE_LINKER_FLAGS "-framework OpenGLES -framework Foundation -framework CoreGraphics -framework QuartzCore -framework UIKit")
  set(XCODE_ATTRIBUTE_GCC_UNROLL_LOOPS "YES")
  set(XCODE_ATTRIBUTE_LLVM_VECTORIZE_LOOPS "YES")
  set(XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer")
  set(XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
  set(OGRE_BUILD_RENDERSYSTEM_GLES2 TRUE CACHE BOOL "Forcing OpenGL ES 2 RenderSystem for iOS" FORCE)
  set(OGRE_STATIC TRUE CACHE BOOL "Forcing static build for iOS" FORCE)
  set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.yourcompany.\${PRODUCT_NAME:rfc1034identifier}")
elseif (ANDROID)
  set(TargetPlatform "Android")
  set(OGRE_PLATFORM OGRE_PLATFORM_ANDROID)
  set(OGRE_CONFIG_ENABLE_VIEWPORT_ORIENTATIONMODE FALSE CACHE BOOL "Disable viewport orientation Android" FORCE)
  option(OGRE_BUILD_ANDROID_JNI_SAMPLE "Enable JNI Sample" FALSE)

  set(OGRE_BUILD_RENDERSYSTEM_GLES2 TRUE CACHE BOOL "Forcing OpenGL ES 2 RenderSystem for Android" FORCE)

  set(OGRE_BUILD_PLUGIN_PCZ FALSE CACHE BOOL "Disable pcz on Android" FORCE)
  set(OGRE_BUILD_PLUGIN_BSP FALSE CACHE BOOL "Disable bsp scenemanager on Android" FORCE)
  set(OGRE_BUILD_TOOLS FALSE CACHE BOOL "Disable tools on Android" FORCE)
  set(OGRE_STATIC TRUE CACHE BOOL "Forcing static build for Android" FORCE)

  # workaround for the legacy android toolchain
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(EMSCRIPTEN)
  add_definitions(-DEMSCRIPTEN=1 -D__EMSCRIPTEN__=1)
  set(TargetPlatform "Emscripten")
  set(OGRE_PLATFORM OGRE_PLATFORM_EMSCRIPTEN)

  set(OGRE_BUILD_RENDERSYSTEM_GLES2 TRUE CACHE BOOL "Forcing OpenGL ES 2 RenderSystem for Emscripten" FORCE)
  set(OGRE_BUILD_RENDERSYSTEM_GL FALSE CACHE BOOL "Disable OpenGL RenderSystem for Emscripten" FORCE)

  set(OGRE_BUILD_PLUGIN_STBI TRUE CACHE BOOL "Enable STBIImageCodec on Emscripten (Smaller Footprint)" FORCE)
  set(OGRE_BUILD_PLUGIN_FREEIMAGE FALSE CACHE BOOL "Disable Freeimage on Emscripten (Smaller Footprint)" FORCE)
  set(OGRE_BUILD_PLUGIN_PCZ FALSE CACHE BOOL "Disable pcz on Emscripten" FORCE)
  set(OGRE_BUILD_PLUGIN_BSP FALSE CACHE BOOL "Disable pcz on Emscripten" FORCE)
  set(OGRE_BUILD_TOOLS FALSE CACHE BOOL "Disable tools on Emscripten" FORCE)
  set(OGRE_BUILD_TESTS FALSE CACHE BOOL "Disable tests on Emscripten" FORCE)
  set(OGRE_BUILD_COMPONENT_VOLUME FALSE CACHE BOOL "Disable volume component on Emscripten" FORCE)
  set(OGRE_BUILD_COMPONENT_PAGING FALSE CACHE BOOL "Disable paging component on Emscripten" FORCE)
  set(OGRE_BUILD_COMPONENT_TERRAIN FALSE CACHE BOOL "Disable terrain component on Emscripten" FORCE)
  set(OGRE_STATIC TRUE CACHE BOOL "Forcing static build for Emscripten" FORCE)

  set(OGRE_CONFIG_THREADS "0" CACHE STRING "Threading is unstable on Emscripten" FORCE)
elseif (APPLE AND NOT APPLE_IOS)

  set(XCODE_ATTRIBUTE_SDKROOT macosx)
  if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
    execute_process(COMMAND xcodebuild -version -sdk "${XCODE_ATTRIBUTE_SDKROOT}" Path | head -n 1 OUTPUT_VARIABLE CMAKE_OSX_SYSROOT)
    string(REGEX REPLACE "(\r?\n)+$" "" CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT}")
  else()
    set(CMAKE_OSX_SYSROOT macosx)
  endif()

  if (NOT CMAKE_OSX_ARCHITECTURES)
    if(OGRE_BUILD_RENDERSYSTEM_GL3PLUS)
      if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
        set(CMAKE_OSX_ARCHITECTURES "${ARCHS_STANDARD_64_BIT}")
      else()
        set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_64_BIT)")
      endif()
    else()
      if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
        set(CMAKE_OSX_ARCHITECTURES "${ARCHS_STANDARD_32_64_BIT}")
      else()
        set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
      endif()
    endif()
  endif()

  # Make sure that the OpenGL render system is selected for non-iOS Apple builds
  set(OGRE_BUILD_RENDERSYSTEM_GLES2 FALSE)
endif ()

if(OGRE_BUILD_COMPONENT_MESHLODGENERATOR)
  set(OGRE_CONFIG_ENABLE_MESHLOD TRUE CACHE BOOL "Forcing Mesh Lod" FORCE)
endif()

# Enable the PVRTC codec if OpenGL ES is being built
if(OGRE_BUILD_RENDERSYSTEM_GLES2)
  set(OGRE_CONFIG_ENABLE_PVRTC TRUE CACHE BOOL "Forcing PVRTC codec for OpenGL ES" FORCE)
  set(OGRE_CONFIG_ENABLE_ETC TRUE CACHE BOOL "Forcing ETC codec for OpenGL ES" FORCE)
endif()

# Enable the ETC codec if OpenGL 3+ is being built
if(OGRE_BUILD_RENDERSYSTEM_GL3PLUS)
  set(OGRE_CONFIG_ENABLE_ETC TRUE CACHE BOOL "Forcing ETC codec for OpenGL 3+" FORCE)
endif()

# Find dependencies
include(Dependencies)

######################################################################
# Provide user options to customise the build process
######################################################################

# Customise what to build
option(OGRE_STATIC "Static build" FALSE)
option(OGRE_ENABLE_PRECOMPILED_HEADERS "Use precompiled headers to speed up build" TRUE)
set(OGRE_RESOURCEMANAGER_STRICT "2" CACHE STRING 
  "Make ResourceManager strict for faster operation. Possible values:
  0 - OFF search in all groups twice - for case sensitive and insensitive lookup [DEPRECATED]
  1 - PEDANTIC require an explicit resource group. Case sensitive lookup.
  2 - STRICT search in default group if not specified otherwise. Case sensitive lookup.
  ")
set_property(CACHE OGRE_RESOURCEMANAGER_STRICT PROPERTY STRINGS 0 1 2)

cmake_dependent_option(OGRE_BUILD_RENDERSYSTEM_D3D9 "Build Direct3D9 RenderSystem" TRUE "WIN32;DirectX9_FOUND;NOT WINDOWS_STORE;NOT WINDOWS_PHONE" FALSE)
cmake_dependent_option(OGRE_BUILD_RENDERSYSTEM_D3D11 "Build Direct3D11 RenderSystem" TRUE "WIN32;DirectX11_FOUND OR WINDOWS_STORE OR WINDOWS_PHONE" FALSE)
cmake_dependent_option(OGRE_BUILD_RENDERSYSTEM_GL3PLUS "Build OpenGL 3+ RenderSystem" TRUE "OPENGL_FOUND;NOT WINDOWS_STORE;NOT WINDOWS_PHONE" FALSE)
cmake_dependent_option(OGRE_BUILD_RENDERSYSTEM_GL "Build OpenGL RenderSystem" TRUE "OPENGL_FOUND;NOT APPLE_IOS;NOT WINDOWS_STORE;NOT WINDOWS_PHONE" FALSE)
cmake_dependent_option(OGRE_BUILD_RENDERSYSTEM_GLES2 "Build OpenGL ES 2.x RenderSystem" FALSE "OPENGLES2_FOUND;NOT WINDOWS_STORE;NOT WINDOWS_PHONE" FALSE)
option(OGRE_BUILD_PLUGIN_BSP "Build BSP SceneManager plugin" TRUE)
option(OGRE_BUILD_PLUGIN_OCTREE "Build Octree SceneManager plugin" TRUE)
option(OGRE_BUILD_PLUGIN_PFX "Build ParticleFX plugin" TRUE)
cmake_dependent_option(OGRE_BUILD_PLUGIN_PCZ "Build PCZ SceneManager plugin" TRUE "" FALSE)
cmake_dependent_option(OGRE_BUILD_COMPONENT_PAGING "Build Paging component" TRUE "" FALSE)
cmake_dependent_option(OGRE_BUILD_COMPONENT_MESHLODGENERATOR "Build MeshLodGenerator component" TRUE "" FALSE)
cmake_dependent_option(OGRE_BUILD_COMPONENT_TERRAIN "Build Terrain component" TRUE "" FALSE)
cmake_dependent_option(OGRE_BUILD_COMPONENT_VOLUME "Build Volume component" TRUE "" FALSE)
cmake_dependent_option(OGRE_BUILD_COMPONENT_PROPERTY "Build Property component" TRUE "" FALSE)
cmake_dependent_option(OGRE_BUILD_PLUGIN_CG "Build Cg plugin" TRUE "Cg_FOUND;NOT APPLE_IOS;NOT WINDOWS_STORE;NOT WINDOWS_PHONE" FALSE)
cmake_dependent_option(OGRE_BUILD_COMPONENT_OVERLAY "Build Overlay component" TRUE "FREETYPE_FOUND" FALSE)
option(OGRE_BUILD_COMPONENT_HLMS "Build HLMS component" TRUE)
cmake_dependent_option(OGRE_BUILD_COMPONENT_BITES "Build OgreBites component" TRUE "OGRE_BUILD_COMPONENT_OVERLAY" FALSE)
cmake_dependent_option(OGRE_BUILD_COMPONENT_PYTHON "Build Python bindings" TRUE "NOT OGRE_STATIC" FALSE)
option(OGRE_BUILD_COMPONENT_JAVA "Build Java (JNI) bindings" TRUE)
option(OGRE_BUILD_COMPONENT_RTSHADERSYSTEM "Build RTShader System component" TRUE)
cmake_dependent_option(OGRE_BUILD_RTSHADERSYSTEM_CORE_SHADERS "Build RTShader System FFP core shaders" TRUE "OGRE_BUILD_COMPONENT_RTSHADERSYSTEM" FALSE)
cmake_dependent_option(OGRE_BUILD_RTSHADERSYSTEM_EXT_SHADERS "Build RTShader System extensions shaders" TRUE "OGRE_BUILD_COMPONENT_RTSHADERSYSTEM" FALSE)

cmake_dependent_option(OGRE_BUILD_SAMPLES "Build Ogre demos" TRUE "OGRE_BUILD_COMPONENT_OVERLAY;OGRE_BUILD_COMPONENT_BITES" FALSE)
cmake_dependent_option(OGRE_BUILD_TOOLS "Build the command-line tools" TRUE "NOT APPLE_IOS;NOT WINDOWS_STORE;NOT WINDOWS_PHONE" FALSE)
cmake_dependent_option(OGRE_BUILD_XSIEXPORTER "Build the Softimage exporter" FALSE "Softimage_FOUND" FALSE)
cmake_dependent_option(OGRE_BUILD_LIBS_AS_FRAMEWORKS "Build frameworks for libraries on OS X." TRUE "APPLE;NOT OGRE_BUILD_PLATFORM_APPLE_IOS" FALSE)
option(OGRE_BUILD_TESTS "Build the unit tests & PlayPen" FALSE)
option(OGRE_CONFIG_DOUBLE "Use doubles instead of floats in Ogre" FALSE)
option(OGRE_CONFIG_NODE_INHERIT_TRANSFORM "Tells the node whether it should inherit full transform from it's parent node or derived position, orientation and scale" FALSE)
set(OGRE_CONFIG_THREADS "3" CACHE STRING 
    "Enable Ogre thread safety support for multithreading. Possible values:
    0 - no thread safety. DefaultWorkQueue is not threaded.
    1 - background resource preparation and loading is thread safe. Threaded DefaultWorkQueue. [DEPRECATED]
    2 - only background resource preparation is thread safe. Threaded DefaultWorkQueue. [DEPRECATED]
    3 - no thread safety. Threaded DefaultWorkQueue."
)
set_property(CACHE OGRE_CONFIG_THREADS PROPERTY STRINGS 0 1 2 3)
set(OGRE_CONFIG_THREAD_PROVIDER "std" CACHE STRING
    "Select the library to use for thread support. Possible values:
    boost - Boost thread library. [DEPRECATED]
    poco  - Poco thread library. [DEPRECATED]
    tbb   - ThreadingBuildingBlocks library. [DEPRECATED]
    std   - STL thread library (requires compiler support)."
)
set_property(CACHE OGRE_CONFIG_THREAD_PROVIDER PROPERTY STRINGS boost poco tbb std)
cmake_dependent_option(OGRE_BUILD_PLUGIN_FREEIMAGE "Build FreeImage codec." TRUE "FreeImage_FOUND" FALSE)
cmake_dependent_option(OGRE_BUILD_PLUGIN_EXRCODEC "Build EXR Codec plugin" TRUE "OPENEXR_FOUND;" FALSE)
option(OGRE_BUILD_PLUGIN_STBI "Enable STBI image codec." TRUE)
option(OGRE_CONFIG_ENABLE_MESHLOD "Enable Mesh Lod." TRUE)
option(OGRE_CONFIG_ENABLE_DDS "Build DDS codec." TRUE)
option(OGRE_CONFIG_ENABLE_PVRTC "Build PVRTC codec." FALSE)
option(OGRE_CONFIG_ENABLE_ETC "Build ETC codec." TRUE)
option(OGRE_CONFIG_ENABLE_ASTC "Build ASTC codec." FALSE)
option(OGRE_CONFIG_ENABLE_QUAD_BUFFER_STEREO "Enable stereoscopic 3D support" FALSE)
cmake_dependent_option(OGRE_CONFIG_ENABLE_ZIP "Build ZIP archive support. If you disable this option, you cannot use ZIP archives resource locations. The samples won't work." TRUE "ZZip_FOUND" FALSE)
option(OGRE_CONFIG_ENABLE_VIEWPORT_ORIENTATIONMODE "Include Viewport orientation mode support." FALSE)
cmake_dependent_option(OGRE_CONFIG_ENABLE_GLES2_CG_SUPPORT "Enable Cg support to ES 2 render system" FALSE "OGRE_BUILD_RENDERSYSTEM_GLES2" FALSE)
cmake_dependent_option(OGRE_CONFIG_ENABLE_GLES2_GLSL_OPTIMISER "Enable GLSL optimiser use in GLES 2 render system" FALSE "OGRE_BUILD_RENDERSYSTEM_GLES2" FALSE)
cmake_dependent_option(OGRE_CONFIG_ENABLE_GL_STATE_CACHE_SUPPORT "Enable OpenGL state cache management" FALSE "OGRE_BUILD_RENDERSYSTEM_GL OR OGRE_BUILD_RENDERSYSTEM_GLES2 OR OGRE_BUILD_RENDERSYSTEM_GL3PLUS" FALSE)
cmake_dependent_option(OGRE_CONFIG_ENABLE_GLES3_SUPPORT "Enable OpenGL ES 3.x Features" FALSE "OPENGLES3_FOUND;OGRE_BUILD_RENDERSYSTEM_GLES2" FALSE)
option(OGRE_CONFIG_ENABLE_TBB_SCHEDULER "Enable TBB's scheduler initialisation/shutdown." TRUE)
# Customise what to install
option(OGRE_INSTALL_CMAKE "Install CMake scripts." TRUE)
option(OGRE_INSTALL_SAMPLES "Install Ogre demos." TRUE)
option(OGRE_INSTALL_TOOLS "Install Ogre tools." TRUE)
option(OGRE_INSTALL_DOCS "Install documentation." TRUE)
option(OGRE_INSTALL_SAMPLES_SOURCE "Install samples source files." FALSE)
cmake_dependent_option(OGRE_INSTALL_PDB "Install debug pdb files" TRUE "MSVC" FALSE)
option(OGRE_PROFILING "Enable internal profiling support." FALSE)
cmake_dependent_option(OGRE_CONFIG_STATIC_LINK_CRT "Statically link the MS CRT dlls (msvcrt)" FALSE "MSVC" FALSE)
set(OGRE_LIB_DIRECTORY "lib${LIB_SUFFIX}" CACHE STRING "Install path for libraries, e.g. 'lib64' on some 64-bit Linux distros.")
if (WIN32)
    option(OGRE_INSTALL_VSPROPS "Install Visual Studio Property Page." FALSE)
    if (OGRE_INSTALL_VSPROPS)
        configure_file(${OGRE_TEMPLATES_DIR}/OGRE.props.in ${OGRE_BINARY_DIR}/OGRE.props)
        install(FILES ${OGRE_BINARY_DIR}/OGRE.props DESTINATION "${CMAKE_INSTALL_PREFIX}")
    endif ()
endif ()

# determine threading options
include(PrepareThreadingOptions)

# For Visual studio enable project folders by default.
# Hide option from other compilers.
if (MSVC)
    option(OGRE_PROJECT_FOLDERS "Organize project into project folders." TRUE)
endif ()

# hide advanced options
mark_as_advanced(
  OGRE_BUILD_RTSHADERSYSTEM_CORE_SHADERS
  OGRE_BUILD_RTSHADERSYSTEM_EXT_SHADERS
  OGRE_CONFIG_DOUBLE
  OGRE_CONFIG_NODE_INHERIT_TRANSFORM
  OGRE_CONFIG_ENABLE_MESHLOD
  OGRE_CONFIG_ENABLE_DDS
  OGRE_CONFIG_ENABLE_PVRTC
  OGRE_CONFIG_ENABLE_ETC
  OGRE_CONFIG_ENABLE_ASTC
  OGRE_CONFIG_ENABLE_VIEWPORT_ORIENTATIONMODE
  OGRE_CONFIG_ENABLE_ZIP
  OGRE_CONFIG_ENABLE_GL_STATE_CACHE_SUPPORT
  OGRE_CONFIG_ENABLE_GLES2_CG_SUPPORT
  OGRE_CONFIG_ENABLE_GLES2_GLSL_OPTIMISER
  OGRE_CONFIG_ENABLE_GLES3_SUPPORT
  OGRE_CONFIG_ENABLE_TBB_SCHEDULER
  OGRE_INSTALL_SAMPLES_SOURCE
  OGRE_PROFILING
  OGRE_CONFIG_STATIC_LINK_CRT
  OGRE_LIB_DIRECTORY
)

###################################################################
# configure global build settings based on selected build options
###################################################################
include(ConfigureBuild)

set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${OGRE_LIB_DIRECTORY}")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

###################################################################
# disable way too common compiler warnings on project level
###################################################################
if(MSVC)
    add_definitions( /wd4251 /wd4275 )
endif()

##################################################################
# Now setup targets
##################################################################

# install resource files
include(InstallResources)

# enable PCH support
include(PrecompiledHeader)

# Setup OgreMain project
add_subdirectory(OgreMain)

# Setup RenderSystems
add_subdirectory(RenderSystems)

# Setup Plugins
add_subdirectory(PlugIns)

# Setup Components
add_subdirectory(Components)

# Setup tests (before samples so that PlayPen is included in browser)
if (OGRE_BUILD_TESTS)
  # enable CTest
  ENABLE_TESTING()
  INCLUDE(CTest)
  add_subdirectory(Tests)
endif ()

# Setup samples
add_subdirectory(Samples)

# Setup command-line tools
if (OGRE_BUILD_TOOLS)
  add_subdirectory(Tools)
endif ()

# Setup XSIExporter
if (OGRE_BUILD_XSIEXPORTER)
  add_subdirectory(Tools/XSIExport)
endif ()

# Install documentation
add_subdirectory(Docs)

# Install media files
if (OGRE_INSTALL_SAMPLES OR OGRE_INSTALL_SAMPLES_SOURCE)
  add_subdirectory(Samples/Media)
endif ()

# Install CMake modules
if (OGRE_INSTALL_CMAKE)
  add_subdirectory(CMake)
endif ()

# Provide CPack packaging target
include(Packaging)


# Show feature summary
include(FeatureSummary)

視頻鏈接:https://pan.baidu.com/s/10tAwmGFsLVS9tG_dzJKmuA
視頻密碼:1d0w

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市叛氨,隨后出現(xiàn)的幾起案子呼渣,更是在濱河造成了極大的恐慌,老刑警劉巖寞埠,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屁置,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡仁连,警方通過(guò)查閱死者的電腦和手機(jī)蓝角,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)饭冬,“玉大人使鹅,你說(shuō)我怎么就攤上這事〔伲” “怎么了患朱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)炊苫。 經(jīng)常有香客問(wèn)我裁厅,道長(zhǎng)冰沙,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任执虹,我火速辦了婚禮拓挥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘袋励。我一直安慰自己侥啤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布插龄。 她就那樣靜靜地躺著愿棋,像睡著了一般科展。 火紅的嫁衣襯著肌膚如雪均牢。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天才睹,我揣著相機(jī)與錄音徘跪,去河邊找鬼。 笑死琅攘,一個(gè)胖子當(dāng)著我的面吹牛垮庐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坞琴,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼哨查,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了剧辐?” 一聲冷哼從身側(cè)響起寒亥,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荧关,沒(méi)想到半個(gè)月后溉奕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忍啤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年加勤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片同波。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鳄梅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出未檩,到底是詐尸還是另有隱情戴尸,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布讹挎,位于F島的核電站校赤,受9級(jí)特大地震影響吆玖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜马篮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一沾乘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浑测,春花似錦翅阵、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至岖圈,卻和暖如春讹语,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜂科。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工顽决, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人导匣。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓才菠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親贡定。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赋访,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348