CMake項目中神器:CMakeLists.txt

首次接觸 CMake,見識了 CMakeLists.txt 的強大后,趕緊整理出來分享一下。

參考資料:《Cmake 3.6 W3Cschool參考手冊》

本文講述了一個 CMake 項目,在從單文件到多文件,單目錄到多子目錄的代碼演化過程中,CMakeLists.txt 腳本的編寫變化。

本文內(nèi)容都是在 Linux 系統(tǒng)上操作的,如果在 VS CodeVisual Status 2019 上操作的話,也是一樣的。

單文件的CMake項目

例子1

創(chuàng)建如下 CMake 項目

目錄結(jié)構(gòu)

[root@localhost cmaketest]# tree
.
├── CMakeLists.txt
└── main.cpp

0 directories, 2 files
[root@localhost cmaketest]#

創(chuàng)建CMake項目

如上,新建一個文件夾存放 CMake 項目,這里是 cmaketest 目錄。在目錄下新建兩個文件:main.cpp、CMakeLists.txt

main.cpp 中寫上如下代碼(當然你也可以寫其它的,心隨你動,哈哈)

#include <iostream>

int Func_Add(int num1, int num2)
{
    int nSum = num1 + num2;
    return nSum;
}

int main()
{
    int numSum = Func_Add(2, 3);
    std::cout << "2 + 3 = " << numSum << std::endl;

    return 0;
}

CMakeLists.txt 中寫上如下命令

cmake_minimum_required (VERSION 3.8)    

PROJECT(calcSum)

ADD_EXECUTABLE(calcSum main.cpp)

這樣一個簡單的 CMake 項目就新建好了。

CMakeLists.txt 中命令解釋:

  • cmake_minimum_required (VERSION 3.8)
    設置項目所需的 cmake 最低版本為 cmake 3.8 版本。
  • PROJECT(calcSum)
    為整個項目設置一個名字,這里起名為 calcSum
  • ADD_EXECUTABLE(calcSum main.cpp)
    添加一個目標可執(zhí)行文件 calcSum 到項目中,這個可執(zhí)行文件是使用后面指定的 main.cpp 文件生成的。

構(gòu)建和編譯CMake項目

在項目路徑下新建一個 build 目錄,用來存放構(gòu)建和編譯過程中生成的文件。
進入 build 目錄后編譯驗證如下:

[root@localhost cmaketest]# mkdir build
[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.7s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# make
[ 50%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
[100%] Linking CXX executable calcSum
[100%] Built target calcSum
[root@localhost build]# ls
calcSum  CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile
[root@localhost build]# ./calcSum 
2 + 3 = 5
[root@localhost build]# 

這就是單個文件的 CMake 項目中 CMakeLists.txt 的編寫。

多個文件的CMake項目

我們開發(fā)一個項目,代碼文件肯定不只有一個 main.cpp 那么簡單??隙〞泻芏嘣次募?。這里先說一下有兩個文件:main.cpputil.hCMake 項目。

例子2

目錄結(jié)構(gòu)

[root@localhost cmaketest]# tree
.
├── build
├── CMakeLists.txt
├── main.cpp
└── util.h

0 directories, 3 files
[root@localhost cmaketest]#

修改項目

將第一個例子中 main.cpp 中的 Func_Add() 函數(shù)的代碼提取到 util.h 中,main.cpp 中保留剩下的。其它不變。如下

util.h 文件中的代碼:

#ifndef __UTIL_H__
#define __UTIL_H__

#include <iostream>

int Func_Add(int num1, int num2)
{
    int nSum = num1 + num2;
    return nSum;
}

#endif

main.cpp 文件中的代碼:

#include "util.h"

int main()
{
    int numSum = Func_Add(2, 3);
    std::cout << "2 + 3 = " << numSum << std::endl;

    return 0;
}

編譯項目

現(xiàn)在,不用修改 CMakeLists.txt 文件,直接編譯的話也是OK的:

[root@localhost cmaketest]# rm -rf build/*
[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# make
[ 50%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
[100%] Linking CXX executable calcSum
[100%] Built target calcSum
[root@localhost build]# ls
calcSum  CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile
[root@localhost build]# ./calcSum 
2 + 3 = 5

原因想必大家也都知道,在預處理的時候,會將 util.h 頭文件中的內(nèi)容整合到 main.cpp 中,這就相當于和例子1一樣了。

但是我們?nèi)粘i_發(fā)時,很多時候都不會將函數(shù)的實現(xiàn),即函數(shù)體放到頭文件中,頭文件中只放函數(shù)的聲明,.cpp 源文件中才放函數(shù)的實現(xiàn)。即如下。

例子3

目錄結(jié)構(gòu):

[root@localhost cmaketest]# tree
.
├── build
├── CMakeLists.txt
├── main.cpp
├── util.cpp
└── util.h

1 directory, 4 files
[root@localhost cmaketest]#

修改項目

新增一個 util.cpp 文件如下:

#include "util.h"

int Func_Add(int num1, int num2)
{
    int nSum = num1 + num2;
    return nSum;
}

頭文件 util.h 中代碼修改為:

#ifndef __UTIL_H__
#define __UTIL_H__
#include < iostream >

int Func_Add(int num1, int num2);

#endif

編譯項目

[root@localhost cmaketest]# rm -rf build/*
[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.5s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# make
[ 50%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
[100%] Linking CXX executable calcSum
CMakeFiles/calcSum.dir/main.cpp.o:在函數(shù)‘main’中:
main.cpp:(.text+0x13):對‘Func_Add(int, int)’未定義的引用
collect2: 錯誤:ld 返回 1
make[2]: *** [calcSum] 錯誤 1
make[1]: *** [CMakeFiles/calcSum.dir/all] 錯誤 2
make: *** [all] 錯誤 2
[root@localhost build]# 

可見,我們構(gòu)建項目后,使用 make 命令編譯時,會報錯:main.cpp:(.text+0x13):對‘Func_Add(int, int)’未定義的引用。
這是由于,我們在 CMakeLists.txt 中語句 ADD_EXECUTABLE(calcSum main.cpp) 只指定了一個依賴源文件 main.cpp, 但是現(xiàn)在的話,要想生成 calcSum 可執(zhí)行文件,需要依賴 main.cpp、util.cpp 兩個源文件才可以。

修改CMakeLists.txt

cmake_minimum_required (VERSION 3.8)

PROJECT(calcSum)

ADD_EXECUTABLE(calcSum main.cpp util.cpp)

上面我們將 util.cpp 源文件也指定在依賴項中,用空格分割。

再編譯項目

[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# make
[ 33%] Building CXX object CMakeFiles/calcSum.dir/util.cpp.o
[ 66%] Linking CXX executable calcSum
[100%] Built target calcSum
[root@localhost build]# ./calcSum 
2 + 3 = 5
[root@localhost build]# 

發(fā)現(xiàn)編譯成功了。ADD_EXECUTABLE() 的第一個參數(shù)是目標可執(zhí)行文件的名字,后面的為依賴源文件,當編譯需要依賴多個源文件時,可以將依賴的源文件加在后面,源文件和源文件之間用空格分割。

單個子目錄的CMake項目

例子4

我們的項目不可能所有的文件都放在同一個主目錄下,實際開發(fā)中項目都會分很多子目錄,比如下面的

目錄結(jié)構(gòu)

[root@localhost cmaketest]# tree
.
├── build
├── CMakeLists.txt
├── main.cpp
└── src
? ? ? ?├── util.cpp
? ? ? ?└── util.h

2 directories, 4 files
[root@localhost cmaketest]#

修改項目

在項目主目錄下新建一個 src 目錄,然后將文件 util.hutil.cpp 文件移動到 src 目錄下。

編譯項目

[root@localhost cmaketest]# rm -rf build/*
[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.5s)
CMake Error at CMakeLists.txt:5 (ADD_EXECUTABLE):
  Cannot find source file:

    util.cpp

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
  .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc

CMake Error at CMakeLists.txt:5 (ADD_EXECUTABLE):
  No SOURCES given to target: calcSum

CMake Generate step failed.  Build files cannot be regenerated correctly.
[root@localhost build]# 

發(fā)現(xiàn)在執(zhí)行 cmake 命令構(gòu)建項目時就報錯了:

CMake Error at CMakeLists.txt:5 (ADD_EXECUTABLE):
? ? Cannot find source file:

? ? ? ? util.cpp

無法找到依賴的源文件 util.cpp,這是由于將 util.cpp 文件移動到 src 后,并沒有在 CMakeLists.txt 中修改依賴源文件的路徑,所以 cmake 編譯器在主目錄下查找時無法找到。

修改CMakeLists.txt文件

cmake_minimum_required (VERSION 3.8)

PROJECT(calcSum)

ADD_EXECUTABLE(calcSum main.cpp src/util.cpp)

構(gòu)建項目

[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# 

發(fā)現(xiàn)可以成功建立了。接著我們執(zhí)行 make 編譯項目。

編譯項目

[root@localhost build]# make
[ 33%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
/home/fenghx/myCMakePro/cmaketest/main.cpp:1:18: 致命錯誤:util.h:沒有那個文件或目錄
 #include "util.h"
                  ^
編譯中斷。
make[2]: *** [CMakeFiles/calcSum.dir/main.cpp.o] 錯誤 1
make[1]: *** [CMakeFiles/calcSum.dir/all] 錯誤 2
make: *** [all] 錯誤 2
[root@localhost build]# 

這里又報錯了,無法找到 util.h 頭文件??上攵鸵婚_始找不到 util.cpp 是一樣。我們試著將頭文件加到依賴項中,看行不行。

修改CMakeLists.txt文件

cmake_minimum_required (VERSION 3.8)

PROJECT(calcSum)

ADD_EXECUTABLE(calcSum main.cpp src/util.cpp src/util.h)

重新編譯

[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# make
[ 33%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
/home/fenghx/myCMakePro/cmaketest/main.cpp:1:18: 致命錯誤:util.h:沒有那個文件或目錄
 #include "util.h"
                  ^
編譯中斷。
make[2]: *** [CMakeFiles/calcSum.dir/main.cpp.o] 錯誤 1
make[1]: *** [CMakeFiles/calcSum.dir/all] 錯誤 2
make: *** [all] 錯誤 2
[root@localhost build]# 

發(fā)現(xiàn)這樣還是無法找到 util.h 頭文件,那應該如何才能讓編譯器找到這個頭文件呢,無非就是告訴編譯器這個頭文件的路徑,這就需要用到:include_directories()

  • include_directories(路徑名稱)
    添加一個頭文件路徑到項目構(gòu)建中去。

修改CMakeLists.txt文件

cmake_minimum_required (VERSION 3.8)

PROJECT(calcSum)

INCLUDE_DIRECTORIES(src/)

ADD_EXECUTABLE(calcSum main.cpp src/util.cpp)

如上,我們將相對路徑 src/ 添加到了項目的構(gòu)件中,然后再編譯項目。

編譯項目

[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# make
[ 33%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/calcSum.dir/src/util.cpp.o
[100%] Linking CXX executable calcSum
[100%] Built target calcSum
[root@localhost build]# ./calcSum 
2 + 3 = 5
[root@localhost build]# 

發(fā)現(xiàn)此時就已經(jīng)可以編譯生成可執(zhí)行文件了。

子目錄中有很多的源文件的CMake項目

如果子目錄中有很多的 .cpp 源文件,單單把這么多的源文件都寫到依賴項中,就很費勁了,密密麻麻可讀性也不好,而且如果要新建 .cpp 源文件的話,豈不是每次添加都得編輯一下 CMakeLists.txt 文件,太麻煩了,有沒有辦法解決這個事情呢?

有辦法:

  • aux_source_directory(路徑名稱 變量名稱)
    搜索指定目錄下的所有源文件,并將他們保存在給定的變量中。

修改CMakeLists.txt文件

cmake_minimum_required (VERSION 3.8)

PROJECT(calcSum)

INCLUDE_DIRECTORIES(src/)

AUX_SOURCE_DIRECTORY(src/ SUB_SOURCE_FILE)

ADD_EXECUTABLE(calcSum main.cpp ${SUB_SOURCE_FILE})

如上,AUX_SOURCE_DIRECTORY() 會搜索 src/ 目錄下的所有源文件,將它們保存到指定的變量 SUB_SOURCE_FILE 中。之后我們直接在 ADD_EXECUTABLE() 中使用這個變量就可以了,使用變量的方法為:==${變量名}==。

編譯項目

[root@localhost cmaketest]# rm -rf build/*
[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.5s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# make
[ 33%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/calcSum.dir/src/util.cpp.o
[100%] Linking CXX executable calcSum
[100%] Built target calcSum
[root@localhost build]# ./calcSum 
2 + 3 = 5
[root@localhost build]#

可見,在使用 make 編譯的時候確實找到 util.cpp 源文件了。這樣就不用我們每次都要添加依賴的源文件了。是不是很帥。

多個子目錄的CMake項目

再來想想,項目中一般不會只有一個子目錄,往往有很多個子目錄,如果子目錄很多,那只使用 AUX_SOURCE_DIRECTORY() 的話顯然要寫很多行,并且變量也要定義很多,不太好,那該怎么辦呢?有沒有傳遞多個目錄的方法呢?

有,使用 file() 文件操作命令。

  • file(GLOB 變量名 路徑1 路徑2 .....)
    按照一定規(guī)則搜索給定路徑列表中的所有文件,將文件名都保存在給定的變量中。

修改CMakeLists.txt文件

cmake_minimum_required (VERSION 3.8)

PROJECT(calcSum)

INCLUDE_DIRECTORIES(src/)

FILE(GLOB SOURCE_FILES 
        ${PROJECT_SOURCE_DIR}/*.cpp
        ${PROJECT_SOURCE_DIR}/src/*.cpp
)

ADD_EXECUTABLE(calcSum ${SOURCE_FILES})

這里的變量 PROJECT_SOURCE_DIRCMake 中的一個變量,代表的是當前項目的根目錄。上面命令是將根目錄下的所有 .cpp 文件和 src/ 目錄下的所有 .cpp 文件都搜索出來,存放到變量 SOURCE_FILES 中,這樣,在命令 ADD_EXECUTABLE() 中就可以直接使用變量 SOURCE_FILES ,而不需要編寫依賴的源文件了。

編譯項目

[root@localhost cmaketest]# rm -rf build/*
[root@localhost cmaketest]# cd build/
[root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# make
[ 33%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/calcSum.dir/src/util.cpp.o
[100%] Linking CXX executable calcSum
[100%] Built target calcSum
[root@localhost build]# ./calcSum 
2 + 3 = 5
[root@localhost build]# 

發(fā)現(xiàn)真的是可以的,完美解決不爽的問題。

需要指定編譯器版本的CMake項目

修改項目

如果將 main.cpp 改為如下:

#include "util.h"

int main()
{
    auto numSum = Func_Add(2, 3);
    std::cout << "2 + 3 = " << numSum << std::endl;

    return 0;
}

我用 auto 自動識別類型定義了變量 numSum,來接受 Func_Add() 返回的值。

編譯項目

[root@localhost cmaketest]# cd build/
[root@localhost build]# make
[ 33%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
/home/fenghx/myCMakePro/cmaketest/main.cpp: 在函數(shù)‘int main()’中:
/home/fenghx/myCMakePro/cmaketest/main.cpp:5:7: 錯誤:‘numSum’不是一個類型名
  auto numSum = Func_Add(2, 3);
       ^
/home/fenghx/myCMakePro/cmaketest/main.cpp:6:29: 錯誤:‘numSum’在此作用域中尚未聲明
  std::cout << "2 + 3 = " << numSum << std::endl;
                             ^
make[2]: *** [CMakeFiles/calcSum.dir/main.cpp.o] 錯誤 1
make[1]: *** [CMakeFiles/calcSum.dir/all] 錯誤 2
make: *** [all] 錯誤 2
[root@localhost build]#

這里就會報錯,原因是 auto 關鍵字是 C++11 標準里面的,而在不指定 C++ 標準版本的情況下,編譯器是不會執(zhí)行 C++11 標準的。

那如何來設置 C++11 標準呢?有辦法,如下:

  • set(CMAKE_CXX_STANDARD 11)
    設置C++標準為 C++11

修改CMakeLists.txt文件

cmake_minimum_required (VERSION 3.8)

SET(CMAKE_CXX_STANDARD 11)

PROJECT(calcSum)

INCLUDE_DIRECTORIES(src/)

FILE(GLOB SOURCE_FILES 
        ${PROJECT_SOURCE_DIR}/*.cpp
        ${PROJECT_SOURCE_DIR}/src/*.cpp
)

ADD_EXECUTABLE(calcSum ${SOURCE_FILES})

編譯項目

[root@localhost build]# rm -rf ./*
[root@localhost build]# ls
[root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/fenghx/myCMakePro/cmaketest/build
[root@localhost build]# make
[ 33%] Building CXX object CMakeFiles/calcSum.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/calcSum.dir/src/util.cpp.o
[100%] Linking CXX executable calcSum
[100%] Built target calcSum
[root@localhost build]# ./calcSum 
2 + 3 = 5
[root@localhost build]# 

如上,完美解決問題。

需要連接動態(tài)庫的CMake項目

另外,如果你要鏈接動態(tài)庫,那么就要使用 target_link_libraries()

  • target_link_libraries(目標可執(zhí)行文件名 動態(tài)庫名)
    指定要鏈接給目標可執(zhí)行文件的動態(tài)庫

更多的 CMakeLists.txt 編寫技巧,請參考《Cmake 3.6 W3Cschool參考手冊》


CMake項目中CMakeLists.txt的編寫就分享到這里,感謝你的翻閱,希望能幫到你。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容