CMake使用

CMake簡介

CMake是一個跨平臺的事期、開源的構(gòu)建工具溃睹。cmake是makefile的上層工具丑婿,它們的目的正是為了產(chǎn)生可移植的makefile口予,并簡化自己動手寫makefile時的巨大工作量.目前很多開源的項目都可以通過CMake工具來輕松構(gòu)建工程娄周,例如博客之前分享的openHMD、hidapi沪停、OSVR-Core等等昆咽,代碼的分享者提供源代碼和相應(yīng)的Cmake配置文件,使用者就可以非常方便的在自己的電腦上構(gòu)建相應(yīng)的工程牙甫,進(jìn)行開發(fā)和調(diào)試掷酗。

CMake鏈接

CMake官網(wǎng)
CMake-tutorial

第一步:一個簡單的起點

最簡單的工程就是將一些源文件編譯為可執(zhí)行程序。對于簡單工程來說窟哺,只需要在CMakeList.txt添加2行內(nèi)容即可泻轰。這就是我們這個教程的起點,CMakeLists.txt文件內(nèi)容如下:

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
add_executable(Tutorial tutorial.cxx)

注意:CMake文件是不區(qū)分大小寫的且轨,這個例子中CMakeLists.txt文件中都使用小寫字母浮声。

源文件”tutorial.cxx”用來計算一個數(shù)的平方根虚婿,它的第一個版本非常簡單,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (int argc, char *argv[])
{
  if (argc < 2)
    {
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }
  double inputValue = atof(argv[1]);
  double outputValue = sqrt(inputValue);
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
}

添加版本號和配置頭文件

我們添加的第一個特性就是為我們的可執(zhí)行程序和工程提供一個版本號.你可以在源代碼中寫入版本號,然而在CMakeLists.txt中提供(版本號)更靈活.修改CMakeLists.txt增加一個版本號,內(nèi)容如下:

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
 
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )
 
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}")
 
# add the executable
add_executable(Tutorial tutorial.cxx)

因為配置文件將會被寫入到二進(jìn)制樹當(dāng)中泳挥,我們需要把這個目錄添加到頭文件路徑當(dāng)中然痊。我們接著創(chuàng)建一個TutorialConfig.h.in文件,內(nèi)容如下:

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

當(dāng)CMakE配置這個頭文件是@Tutorial_VERSION_MAJOR@@Tutorial_VERSION_MINOR@的值將會被CMakeLists.txt文件中的值替換屉符。
下一步我們修改tutorial.cxx來包含配置頭文件來使用版本號剧浸。
修改后的代碼如下:

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
 
int main (int argc, char *argv[])
{
  if (argc < 2)
    {
    fprintf(stdout,"%s Version %d.%d\n",
            argv[0],
            Tutorial_VERSION_MAJOR,
            Tutorial_VERSION_MINOR);
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }
  double inputValue = atof(argv[1]);
  double outputValue = sqrt(inputValue);
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
}

上面代碼最主要的修改就是包含了TutorialConfig.h頭文件,并且打印出版本號矗钟。

第二步:添加一個庫

現(xiàn)在我們?yōu)槲覀兊墓こ烫砑右粋€庫唆香。這個庫包含了自己實現(xiàn)的一個用來計算數(shù)的平方根函數(shù)。應(yīng)用程序可以使用這個庫來計算平方根吨艇,而不是使用編譯器提供的標(biāo)準(zhǔn)庫躬它。教程里我們會把這個庫放到一個叫做MathFunctions的子文件夾中。它包含一個只有一行內(nèi)容的CMakeLists.txt文件:

add_library(MathFunctions mysqrt.cxx)

源文件”mysqrt.cxx”有一個叫做mysqrt的函數(shù)东涡,它跟編譯器提供的sqrt函數(shù)類似冯吓。為了使用這個新庫,我們要在頂層的CMakeLists.txt中添加”add_subdirectory”調(diào)用,以便使這個庫能夠被編譯到.我們還需要添加另外一個包含文件夾以便找到包含在頭文件”MathFunctions/MathFunctions.h”中的函數(shù)原型.最后把新庫添加到應(yīng)用程序當(dāng)中,在頂層的CMakeLists.txt文件中添加如下內(nèi)容:

include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions) 
 
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions)

注意:這里需要自己手動在MathFunctions文件夾里添加mysqrt.cxxMathFunctions.h文件,這兩個文件里的代碼可以參考文章最后提供的附件疮跑。

現(xiàn)在讓我們把MathFunctions庫做成可選的.當(dāng)然在這個教程的工程中這個操作有點多余.但是在你的其他工程中,多數(shù)情況會有大量的依賴第三方的庫文件.添加一個可選庫,需要在最高層的CMakeLists.txt文件中添加一些內(nèi)容:

# should we use our own math functions?
option (USE_MYMATH 
        "Use tutorial provided math implementation" ON) 

這個USE_MYMATH將會顯示在CMake GUI當(dāng)中,并且默認(rèn)值為ON,這個設(shè)置將會被保存到CACHE當(dāng)中,所以用戶每次打開工程時不必重新配置.下一步需要做一些修改,以便使MathFunctions庫參與編譯和鏈接.這個修改是在頂層的CMakeLists.txt文件中,內(nèi)容如下:

# add the MathFunctions library?
#
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
  add_subdirectory (MathFunctions)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
 
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})

通過配置USB_MYMATH來決定是否編譯和使用MathFunctions.
注意上面的EXTRA_LIBS變量是用來收集每一個可選庫的,以便他們鏈接到可執(zhí)行程序中.這是一個保持大項目工程可選庫清潔的通用方法.相應(yīng)的源代碼修改是很直觀的,如下:

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif
 
int main (int argc, char *argv[])
{
  if (argc < 2)
    {
    fprintf(stdout,"%s Version %d.%d\n", argv[0],
            Tutorial_VERSION_MAJOR,
            Tutorial_VERSION_MINOR);
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }
 
  double inputValue = atof(argv[1]);
 
#ifdef USE_MYMATH
  double outputValue = mysqrt(inputValue);
#else
  double outputValue = sqrt(inputValue);
#endif
 
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
}

在源文件中,我們也使用了USE_MYMATH,CMake通過修改配置文件TutorialConfig.h.in配置文件來為源文件這個提供支持,添加內(nèi)容如下:

#cmakedefine USE_MYMATH

第三步:安裝和測試

下一步我們將為我們的工程添加安裝規(guī)則和測試.安裝規(guī)則相當(dāng)簡單,為了安裝MathFunctions庫和頭文件,我們需要在MathFunctions文件夾的CMakeLists.txt文件中,添加如下內(nèi)容:

install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

對于應(yīng)用程序,需要在最頂層的CMakeLists.txt文件中安裝可執(zhí)行程序和配置頭文件.

# add the install targets
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"        
         DESTINATION include)

注意:上面這幾行內(nèi)容,需要添加在如下代碼之后,否則編譯會報錯,提示找不到Tutorial

# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})

這就是所有要做的.到這里你應(yīng)該可以構(gòu)建這個教程了,然后輸入make install(或則使用IDE編譯出INSTALL目標(biāo)),它將安裝適當(dāng)?shù)念^文件组贺、庫和可執(zhí)行程序。
CMake變量CMAKE_INSTALL_PREFIX用來決定這些文件將被安裝的根路徑.
添加測試也是很簡單的.在頂層的CMakeLists.txt文件中添加一些簡單的測試,來確認(rèn)應(yīng)用程序工作正常祸挪。

include(CTest)

# does the application run
add_test (TutorialRuns Tutorial 25)
# does it sqrt of 25
add_test (TutorialComp25 Tutorial 25)
set_tests_properties (TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")
# does it handle negative numbers
add_test (TutorialNegative Tutorial -25)
set_tests_properties (TutorialNegative PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0")
# does it handle small numbers
add_test (TutorialSmall Tutorial 0.0001)
set_tests_properties (TutorialSmall PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01")
# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")

在構(gòu)建完成之后需要運行”ctest”命令來運行上面的測試.第一個測試用例用來確保應(yīng)用程序是否有段錯誤,crash,返回值非0.這個是一個簡單的CTest測試.接下來的幾個測試都是利用”PASS_REGULAR_EXPRESSION”測試屬性來驗證輸出是否包含特定字符串.在這個例子當(dāng)中驗證平方根計算是否正確,以及當(dāng)輸入錯誤信息時候輸出使用信息.如果你希望添加更多測試來測試不同的輸入值,你可以考慮創(chuàng)建一個宏像如下這樣:

#define a macro to simplify adding tests, then use it
macro (do_test arg result)
  add_test (TutorialComp${arg} Tutorial ${arg})
  set_tests_properties (TutorialComp${arg}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)
 
# do a bunch of result based tests
do_test (25 "25 is 5")
do_test (-25 "-25 is 0")

do_test的每一次調(diào)用,就會有一次測試被添加到工程當(dāng)中,測試的名字、輸入贞间、結(jié)果,基于傳遞的參數(shù).

第四步:添加系統(tǒng)自檢

下一步讓我們考慮添加一些代碼到我們的工程,以支持目標(biāo)平臺沒有的特性.在這個例子當(dāng)中,我們將添加一些代碼來驗證目標(biāo)平臺是否具有l(wèi)og和exp函數(shù).當(dāng)然幾乎所有的平臺都有這些函數(shù),教程假設(shè)一下這種少數(shù)情況.如果平臺有l(wèi)og函數(shù),那么我們在mysqrt函數(shù)中用它來計算輸出.第一步我們利用CheckFunctionExists.cmake宏測試這些函數(shù)是否有效,在頂層CMakeLists.txt文件中添加如下內(nèi)容:

# does this system provide the log and exp functions?
include (CheckFunctionExists)
check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)

接著我們修改”TutorialConfig.h.in”來定義那些CMake在平臺上查找到的值,修改如下:

// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

在使用log和exp之前,確定他們是否被定義,是非常重要的.在CMake中,配置文件的命令會立刻使用目前的配置.最后在mysqrt函數(shù)中,我們可以提供一個基于log和exp函數(shù)的實現(xiàn),代碼如下:

// if we have both log and exp then use them
#if defined (HAVE_LOG) && defined (HAVE_EXP)
  result = exp(log(x)*0.5);
#else // otherwise use an iterative approach
  . . .

注意:這里需要在”mysqrt.cxx”文件里添加頭文件#include “TutorialConfig.h”,否則找不到定義的宏贿条。

第5步:添加/生成一個通用的文件

這一節(jié)我們將演示如何添加一個源文件到一個應(yīng)用程序當(dāng)中.在這個例子當(dāng)中,我們將會創(chuàng)建一個已經(jīng)計算好的平方根表,它作為構(gòu)建過程的一部分,并且編譯進(jìn)我們的應(yīng)用程序.為了實現(xiàn)這個功能,我們需要一個程序來生成這個表.在MathFunctions子文件夾中我們添加一個叫做MakeTable.cxx的文件,它的內(nèi)容如下:

// A simple program that builds a sqrt table 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
int main (int argc, char *argv[])
{
  int i;
  double result;
 
  // make sure we have enough arguments
  if (argc < 2)
    {
    return 1;
    }
  
  // open the output file
  FILE *fout = fopen(argv[1],"w");
  if (!fout)
    {
    return 1;
    }
  
  // create a source file with a table of square roots
  fprintf(fout,"double sqrtTable[] = {\n");
  for (i = 0; i < 10; ++i)
    {
    result = sqrt(static_cast<double>(i));
    fprintf(fout,"%g,\n",result);
    }
 
  // close the table with a zero
  fprintf(fout,"0};\n");
  fclose(fout);
  return 0;
}

注意,這個表格是用C++代生成的,并且文件的名字是通過該程序的運行參數(shù)傳入的.下一步就是添加一個適當(dāng)?shù)拿畹組athFunctions的CMakeLists.txt文件來構(gòu)建MakeTable應(yīng)用程序,然后在構(gòu)建過程中運行它.完成這些操作,我們需要添加如下命令:

# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
 
# add the command to generate the source code
add_custom_command (
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  DEPENDS MakeTable
  )
 
# add the binary tree directory to the search path for 
# include files
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
 
# add the main library
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h  )

首先,可執(zhí)行程序MakeTable像所有可執(zhí)行程序一樣被添加.接著我們添加一些命令來讓MakeTable生成Table.h.然后我們讓CMake知道m(xù)ysqrt.cxx依賴于生成的Table.h.這需要為MathFunctions庫把生成的Table.h文件添加到源文件列表當(dāng)中,我們還需要添加當(dāng)前的二進(jìn)制文件夾添加到include文件夾列表當(dāng)中,以便Table.h文件可以被mysqrt.cxx找到并包含.當(dāng)工程被構(gòu)建時,它將會先構(gòu)建MakeTable可執(zhí)行程序.它將運行MakeTable來生成Table.h文件.最后,它編譯包含了Table.h文件的mysqrt.cxx來生成MathFunctions庫.為了達(dá)到這個目的,頂層的CMakeLists.txt需要添加如下代碼:

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
include(CTest)
 
# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
 
# does this system provide the log and exp functions?
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
 
check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)
 
# should we use our own math functions
option(USE_MYMATH 
  "Use tutorial provided math implementation" ON)
 
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )
 
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories ("${PROJECT_BINARY_DIR}")
 
# add the MathFunctions library?
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
  add_subdirectory (MathFunctions)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
 
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})
 
# add the install targets
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"        
         DESTINATION include)
 
# does the application run
add_test (TutorialRuns Tutorial 25)
 
# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage
  PROPERTIES 
  PASS_REGULAR_EXPRESSION "Usage:.*number"
  )
 
 
#define a macro to simplify adding tests
macro (do_test arg result)
  add_test (TutorialComp${arg} Tutorial ${arg})
  set_tests_properties (TutorialComp${arg}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
    )
endmacro (do_test)
 
# do a bunch of result based tests
do_test (4 "4 is 2")
do_test (9 "9 is 3")
do_test (5 "5 is 2.236")
do_test (7 "7 is 2.645")
do_test (25 "25 is 5")
do_test (-25 "-25 is 0")
do_test (0.0001 "0.0001 is 0.01")

TutorialConfig.h.in包含如下內(nèi)容:

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
 
// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

MathFunctions文件夾中的CMakeLists.txt文件,內(nèi)容如下:

# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
# add the command to generate the source code
add_custom_command (
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  DEPENDS MakeTable
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  )
# add the binary tree directory to the search path 
# for include files
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
 
# add the main library
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h)
 
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

第6步:構(gòu)建一個安裝器

接著假設(shè)我們想把工程發(fā)布給其他人使用.我們希望提供不同平臺的二進(jìn)制文件和源文件.這里與我們之前在第三步中的安裝有一些不同,那時我們安裝我們已經(jīng)從源代碼構(gòu)建出來的二進(jìn)制文件.在這個例子中,我們將構(gòu)建一個安裝包,它支持二進(jìn)制安裝,以及cygwin、 debian增热、RPMs等工具的包管理特性.為了實現(xiàn)這個功能,我們會使用CPack來創(chuàng)建平臺相關(guān)的安裝包.我們需要在頂層的CMakeLists.txt文件中的最后添加一些代碼,內(nèi)容如下:

# build a CPack driven installer package
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE  
     "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
include (CPack)

官方教程中沒有License.txt文件,所有要手動在頂層目錄下添加一個”License.txt”文件
以上就是我們所有要做的.以包含InstallRequiredSystemLibraries為開始.這個模塊將包含工程在目前平臺上所需要的所有運行時庫.接著我們設(shè)置一些CPack變量,包括我們保存license的地方,工程的版本信息.版本信息就是用了我們教程中之前設(shè)置的變量值.最后我們包含CPake模塊,它將使用這些變量和一些系統(tǒng)的其他屬性來設(shè)置安裝包.
下一步是以通常的方法構(gòu)建工程,然后在CPack上運行它.為了構(gòu)建二進(jìn)制發(fā)行包,你需要運行如下命令:

cpack --config CPackConfig.cmake

為了創(chuàng)建一個源文件發(fā)行包,你需要運行:

cpack --config CPackSourceConfig.cmake

注意:這里的2條命令需要在構(gòu)建工程的目錄下運行!

第7步:添加對Dashboard支持

將我們的測試結(jié)果添加到Dashboard上是非常容易的.在教程的前面步驟當(dāng)中我們已經(jīng)為我們的工程定義了一些測試.我們只需要運行這些測試,并且提交他們到一個dashboard上.為了支持dashboard我們需要在頂層的CMakeLists.txt文件中包含CTest模塊.

# enable dashboard scripting
include (CTest)

我們還需要創(chuàng)建一個CTestConfig.cmake文件,用來為dashboard指定工程名字.

set (CTEST_PROJECT_NAME "Tutorial")

CTest運行時將讀取這個文件.你可以在你的工程中運行CMake來生成一個簡單的dashboard,進(jìn)入構(gòu)建目錄下,然后執(zhí)行”ctest -D Experimental”,將會把你的dashboard結(jié)果上傳到Kitware’s工程dashboard上.

參考

https://blog.csdn.net/dabenxiong666/article/details/53998998

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末整以,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子峻仇,更是在濱河造成了極大的恐慌公黑,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摄咆,死亡現(xiàn)場離奇詭異凡蚜,居然都是意外死亡,警方通過查閱死者的電腦和手機吭从,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門朝蜘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涩金,你說我怎么就攤上這事谱醇∠局伲” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵副渴,是天一觀的道長奈附。 經(jīng)常有香客問我,道長煮剧,這世上最難降的妖魔是什么斥滤? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮轿秧,結(jié)果婚禮上中跌,老公的妹妹穿的比我還像新娘。我一直安慰自己菇篡,他們只是感情好漩符,可當(dāng)我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著驱还,像睡著了一般嗜暴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上议蟆,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天闷沥,我揣著相機與錄音侣滩,去河邊找鬼梦鉴。 笑死慷暂,一個胖子當(dāng)著我的面吹牛壹粟,可吹牛的內(nèi)容都是我干的乐导。 我是一名探鬼主播悔叽,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼步绸,長吁一口氣:“原來是場噩夢啊……” “哼毡庆!你這毒婦竟也來了蔚约?” 一聲冷哼從身側(cè)響起奄妨,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎苹祟,沒想到半個月后砸抛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡树枫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年直焙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砂轻。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡箕般,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出舔清,到底是詐尸還是另有隱情丝里,我是刑警寧澤曲初,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站杯聚,受9級特大地震影響臼婆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜幌绍,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一颁褂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧傀广,春花似錦颁独、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贮聂,卻和暖如春靠柑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吓懈。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工歼冰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耻警。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓隔嫡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親甘穿。 傳聞我的和親對象是個殘疾皇子腮恩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 注:首發(fā)地址 1. 前言 當(dāng)在做 Android NDK 開發(fā)時,如果不熟悉用 CMake 來構(gòu)建扒磁,讀不懂 CMa...
    cfanr閱讀 24,381評論 1 53
  • 資源 本文檔翻譯自官方 cmake turorial 庆揪。更新日期:2018年9月27日式曲。譯者這里以 windows...
    劉亞彬92閱讀 86,308評論 3 13
  • 1.安裝 $sudo apt-get install cmake 2.示例:簡單的文件目錄 sample |—...
    荷包蛋醬閱讀 29,647評論 0 15
  • CMake學(xué)習(xí) 本篇分享一下有關(guān)CMake的一些學(xué)習(xí)心得以及相關(guān)使用妨托。 本文目錄如下: [1、CMake介紹] [...
    AlphaGL閱讀 12,246評論 11 79
  • 本文不介紹cmake命令使用方法吝羞,也不講CMakeLists.txt的語法兰伤,有需要的讀者可以看我另外相關(guān)的文章即可...
    konishi5202閱讀 1,113評論 0 5