2021年8月11日 星期三

basic CMakeLists.txt for hello_world

$ tree
cmake-hello-world/
├── CMakeLists.txt
├── linux-android.toolchain.cmake
└── src
    ├── main.cpp
    └── TestHello
        ├── test.cpp
        └── test.h

CMakeLists.txt (下面還有一個,比較好用, Cross compile for Android)
cmake_minimum_required (VERSION 3.10)
project (CMakeHelloWorld)

#version number
set (CMakeHelloWorld_VERSION_MAJOR 1)
set (CMakeHelloWorld_VERSION_MINOR 0)

message (STATUS "CXX is $ENV{CXX}")

set(argument_list)

option(USE_ANDROID "" OFF) #OFF by default
if (USE_ANDROID)
    set (CMAKE_ANDROID_ARCH_ABI arm64-v8a)
    set (ANDROID_STL "c++_static")
    set (CMAKE_CXX_COMPILER $ENV{CXX})
    set (CMAKE_AR $ENV{AR})
    set (CMAKE_RANLIB $ENV{RANLIB})
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()


include_directories(src/TestHello)         # 指定 include header path        
set(HELLO_SOURCES src/TestHello/test.cpp)    # 設定變數, 將第二個所給予的內容指定到第一個變數名稱當中
#set(HELLO_SOURCES src/HelloWorld.cpp)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)   # PROJECT....是CMAKE寫好的變數
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

#add_library(test_hello SHARED src/main.cpp src/TestHello/test.cpp src/TestHello/test.h)

add_library(hello ${HELLO_SOURCES})
#add_library(hello2 ${HELLO_SOURCES2})
add_executable(main src/main.cpp ${HELLO_SOURCES})    #  產生可執行檔
if (USE_ANDROID)
    #target_link_libraries需寫在add_executable的下方
    target_link_libraries(main hello -latomic -lc++_static -lc++abi)
else()
    target_link_libraries(main hello)
endif()
APP_STL := c++_shared or c++_static
不要在ndk中使用系统预编译好的C++库

main.cpp
#include <test.h>

using namespace std;

int main(void)
{
    Test t;
    t.Hello();
}

test.cpp
#include "test.h"

using namespace std;

void Test::Hello(void)
{
    cout << "Hello, world!\n" << endl;
}

test.h
#include <stdio.h>
#include <iostream>

using namespace std;

class Test{
    public:
        void Hello (void);
};

compile
$ mkdir build; cd build
$ cmake ..
or
$ cmake -D USE_ANDROID=ON ..
沒有問題後
$ cd build
$ make


ref:
1. cmake
2. How to cross-compile for embedded with CMake like a champ
3. 不要在ndk中使用系统预编译好的C++库
4. CMake 入門/運算子
5. 关于安卓的交叉编译

CMakeLists.txt
cmake_minimum_required (VERSION 3.10)
project (CMakeHelloWorld)

#version number
set (CMakeHelloWorld_VERSION_MAJOR 1)
set (CMakeHelloWorld_VERSION_MINOR 0)

message (STATUS "CXX is $ENV{CXX}")

set(argument_list)

option(USE_ANDROID "" OFF) #OFF by default
if (USE_ANDROID)
    set (CMAKE_ANDROID_ARCH_ABI arm64-v8a)
    set (ANDROID_STL "c++_static")
    set (CMAKE_CXX_COMPILER $ENV{CXX})
    set (CMAKE_AR $ENV{AR})
    set (CMAKE_RANLIB $ENV{RANLIB})
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")

endif()


include_directories(src/TestHello)         # 指定 include header path        
#set(HELLO_SOURCES src/TestHello/test.cpp)    # 設定變數, 將第二個所給予的內容指定到第一個變數名稱當中
file(GLOB SOURCES src/TestHello/*.cpp src/TestHello/*.h)
#set(HELLO_SOURCES src/HelloWorld.cpp)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)   # PROJECT....是CMAKE寫好的變數
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

#add_library(test_hello SHARED src/main.cpp src/TestHello/test.cpp src/TestHello/test.h)

#add_library(hello ${HELLO_SOURCES})
#add_library(hello2 ${HELLO_SOURCES2})
add_executable(main src/main.cpp ${SOURCES})    #  產生可執行檔
if (USE_ANDROID)
    target_link_libraries(main  -latomic -lc++_static -lc++abi)
else()
    target_link_libraries(main)
endif()

linux-android.toolchain.cmake
if (USE_ANDROID)
    if (NOT NDKDIR)
        message(FATAL_ERROR "Set NDK_DIR, Recommended version 22.1.7171670")
    endif()

#set (NDK "/opt/android_studio/sdk/ndk/22.1.7171670")
set (TOOLCHAIN "${NDKDIR}/toolchains/llvm/prebuilt/linux-x86_64")

#set (CMAKE_ANDROID_API 29)
set (ANDROID_STL "c++_static")

if (${CMAKE_ANDROID_ARCH_ABI} STREQUAL "arm64-v8a")
    set (TARGET "aarch64-linux-android")
elseif (${CMAKE_ANDROID_ARCH_ABI} STREQUAL "armeabi-v7a")
    set (TARGET "armv7a-linux-androideabi")
else()
    set (TARGET "x86_64-linux-android")
endif()

set (CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${TARGET}${CMAKE_ANDROID_API}-clang)
message (STATUS "1111111111 is ${CMAKE_C_COMPILER}")
set (CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${TARGET}${CMAKE_ANDROID_API}-clang++)
set (CMAKE_AR     ${TOOLCHAIN}/bin/${TARGET}$-ar)
set (CMAKE_RANLIB ${TOOLCHAIN}/bin/${TARGET}$-ranlib)

# set searching rules for cross-compiler
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()

compile
$ mkdir build; cd build
$ cmake -D USE_ANDROID=ON -D CMAKE_TOOLCHAIN_FILE=../linux-android.toolchain.cmake  -D NDKDIR=/opt/android_studio/sdk/ndk/22.1.7171670 -D CMAKE_ANDROID_ARCH_ABI=arm64-v8a -D CMAKE_ANDROID_API=29 ..
沒有問題後
$ make

沒有留言:

張貼留言