顯示具有 cmake 標籤的文章。 顯示所有文章
顯示具有 cmake 標籤的文章。 顯示所有文章

2022年7月10日 星期日

CMake - Step 4: Installing and Testing - Testing


這章節要來解釋如何在CMAKE中加入auto test功能, 主要是透過enable_testing()啟動testing功能, 並透過add_test()間接呼叫ctest執行測試, 以及set_tests_properties(PROPERTIES PASS_REGULAR_EXPRESSION)來驗證執行結果
# Require a minimum version of cmake.
# cmake_minimum_required(VERSION <min>>[...<policy_max>] [FATAL_ERROR])
cmake_minimum_required(VERSION 3.10)

# Set the name of the project.
# project(<PROJECT-NAME< [<anguage-name>...])
# project(<PROJECT-NAME>
#         [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
#         [DESCRIPTION <project-description-string>]
#         [LANGUAGES <language-name>...])
project(Tutorial VERSION 0.1.2.3 DESCRIPTION "This is Brook 1st CMake Lib")

# Add an executable to the project using the specified source files.
# add_executable(<name> [WIN32] [MACOSX_BUNDLE]
#                [EXCLUDE_FROM_ALL]
#                [source1] [source2 ...])
add_executable(Tutorial hello.c)

# option(<variable> "" [value])
option(USE_MYMATH "Use tutorial provided math implementation" ON)

# configure_file(<input> <output>
#               [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |
#                FILE_PERMISSIONS <permissions>...]
#               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
#               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(Config.h.in Config.h)

if (USE_MYMATH)
# Add a subdirectory to the build.
# add_subdirectory(source_dir [binary_dir]
#                        [EXCLUDE_FROM_ALL])
add_subdirectory(mymath01)

# list(APPEND <list> [<element> ...])
# Appends elements to the list.
# If no variable named <list> exists in the current
# scope its value is treated as empty and the elements
# are appended to that empty list.
list(APPEND EXTRA_LIBS MyMathLib1)
else()
list(APPEND EXTRA_LIBS "m")
endif()

# Specify libraries or flags to use when linking a given target and/or its dependents.
# target_link_libraries(<target>
#                      <PRIVATE|PUBLIC|INTERFACE> ...
#                      [<PRIVATE|PUBLIC|INTERFACE> ...]...)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})

# Add include directories to a target.
# target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
#   <INTERFACE|PUBLIC|PRIVATE> [items1...]
#   [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}")

# Enable testing for current directory and below.
enable_testing()

# Start recording a function for later invocation as a command.
# function(<name> [<arg1> ...])
#         <commands>
# endfunction()
function(do_test target arg result)
  # Add a test to the project to be run by ctest(1).
  #add_test(NAME <name> COMMAND <command> [<arg>...]
  #         [CONFIGURATIONS <config>...]
  #         [WORKING_DIRECTORY <dir>]
  #          [COMMAND_EXPAND_LISTS])
  # Adds a test called <name>
  add_test(NAME Comp${arg} COMMAND ${target} ${arg})

  # Set a property of the tests.
  # set_tests_properties(test1 [test2...] PROPERTIES prop1 value1 prop2 value2)
  set_tests_properties(Comp${arg}
      PROPERTIES PASS_REGULAR_EXPRESSION ${result}
  )
endfunction()

do_test(Tutorial 4 "mymath: 16")

上述範例主要透過do_test(Tutorial 4 "mymath: 16")執行測試, 而do_test為我們自訂的function, 透過add_test(NAME Comp${arg} COMMAND ${target} ${arg})執行ctest與set_tests_properties(Comp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result})驗證執行結果, 這裡的${result}就等於"mymath: 16", 要根據輸出結果作對應修改.
執行結果如下
[brook@:~/Projects/cmake/04-2]$ mkdir build && cd build
[brook@:~/Projects/cmake/04-2/build]$ cmake ../src/ && make all test ARGS="-V"
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/04-2/build
Scanning dependencies of target MyMathLib1
[ 25%] Building C object mymath01/CMakeFiles/MyMathLib1.dir/mymath01.c.o
[ 50%] Linking C static library libMyMathLib1.a
[ 50%] Built target MyMathLib1
Scanning dependencies of target Tutorial
[ 75%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
/build/brook/Projects/cmake/04-2/src/hello.c:6:9: note: #pragma message: use mymath
 #pragma message("use mymath")
         ^~~~~~~
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
Running tests...
UpdateCTestConfiguration  from :/build/brook/Projects/cmake/04-2/build/DartConfiguration.tcl
UpdateCTestConfiguration  from :/build/brook/Projects/cmake/04-2/build/DartConfiguration.tcl
Test project /build/brook/Projects/cmake/04-2/build
Constructing a list of tests
Done constructing a list of tests
Updating test list for fixtures
Added 0 tests to meet fixture requirements
Checking test dependency graph...
Checking test dependency graph end
test 1
    Start 1: Comp4

1: Test command: /build/brook/Projects/cmake/04-2/build/Tutorial "4"
1: Test timeout computed to be: 9.99988e+06
1: mymath: 16
1/1 Test #1: Comp4 ............................   Passed    0.01 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.01 sec
[brook@:~/Projects/cmake/04-2/build]$ cmake ../src/ && make all test
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/04-2/build
[ 50%] Built target MyMathLib1
[100%] Built target Tutorial
Running tests...
Test project /build/brook/Projects/cmake/04-2/build
    Start 1: Comp4
1/1 Test #1: Comp4 ............................   Passed    0.00 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.01 sec


利用make test ARGS="-V"多印一些ctest的output, 這樣比較容易debug


2022年7月2日 星期六

CMake - Step 4: Installing and Testing - Installing


install() 用來產生installation rules, 這個章節主要談兩個install指令,install(TARGETS)與install(FILES).cmake的install選像是在3.15之後才支援, 之前的版本請直接用"make install [DESTDIR=<destdir>]
          
[brook@:~/Projects/cmake/04]$ tree
.
`-- src
    |-- CMakeLists.txt
    |-- Config.h.in
    |-- hello.c
    `-- mymath01
        |-- CMakeLists.txt
        |-- mymath01.c
        `-- mymath01.h

2 directories, 6 files
[brook@:~/Projects/cmake/04]$ cat src/CMakeLists.txt
# Require a minimum version of cmake.
# cmake_minimum_required(VERSION <min>[...<policy_max>] [FATAL_ERROR])
cmake_minimum_required(VERSION 3.10)

# Set the name of the project.
# project(<PROJECT-NAME< [<anguage-name>...])
# project(<PROJECT-NAME>
#         [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
#         [DESCRIPTION <project-description-string>]
#         [LANGUAGES <language-name>...])
project(Tutorial VERSION 0.1.2.3 DESCRIPTION "This is Brook 1st CMake Lib")

# Add an executable to the project using the specified source files.
# add_executable(<name> [WIN32] [MACOSX_BUNDLE]
#                [EXCLUDE_FROM_ALL]
#                [source1] [source2 ...])
add_executable(Tutorial hello.c)

# option(<variable> "<help_text>" [value])
option(USE_MYMATH "Use tutorial provided math implementation" ON)

# configure_file(<input> <output>
#               [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |
#                FILE_PERMISSIONS <permissions>...]
#               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
#               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(Config.h.in Config.h)

if (USE_MYMATH)
# Add a subdirectory to the build.
# add_subdirectory(source_dir [binary_dir]
#                        [EXCLUDE_FROM_ALL])
add_subdirectory(mymath01)

# list(APPEND <list> [<element> ...])
# Appends elements to the list.
# If no variable named <list> exists in the current
# scope its value is treated as empty and the elements
# are appended to that empty list.
list(APPEND EXTRA_LIBS MyMathLib1)
else()
list(APPEND EXTRA_LIBS "m")
endif()

# Specify libraries or flags to use when linking a given target and/or its dependents.
# target_link_libraries(<target>
#                      <PRIVATE|PUBLIC|INTERFACE> ...
#                      [<PRIVATE|PUBLIC|INTERFACE> ...]...)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})

# Add include directories to a target.
# target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
#   <INTERFACE|PUBLIC|PRIVATE> [items1...]
#   [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}")

install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/Config.h" DESTINATION include)

[brook@:~/Projects/cmake/04]$ cat src/mymath01/CMakeLists.txt
# Add a library to the project using the specified source files.
# add_library(<name> [STATIC | SHARED | MODULE]
#             [EXCLUDE_FROM_ALL]
#                       source1 [source2 ...])
add_library(MyMathLib1 mymath01.c)

# target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
#  <INTERFACE|PUBLIC|PRIVATE> [items1...]
#    [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
# target_include_directories(MyMathLib1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(MyMathLib1 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

# install(TARGETS targets... [EXPORT <export-name>]
#        [RUNTIME_DEPENDENCIES args...|RUNTIME_DEPENDENCY_SET <set-name>]
#        [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
#          PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|FILE_SET <set-name>]
#          [DESTINATION <dir>]
#          [PERMISSIONS permissions...]
#          [CONFIGURATIONS [Debug|Release|...]]
#          [COMPONENT <component>]
#          [NAMELINK_COMPONENT <component>]
#          [OPTIONAL] [EXCLUDE_FROM_ALL]
#          [NAMELINK_ONLY|NAMELINK_SKIP]
#          ] [...]
#         [INCLUDES DESTINATION [<dir> ...]]
install(TARGETS MyMathLib1 DESTINATION lib)

# install(<FILES|PROGRAMS> files...
#        TYPE <type> | DESTINATION <dir>
#              [PERMISSIONS permissions...]
#              [CONFIGURATIONS [Debug|Release|...]]
#              [COMPONENT <component>]
#              [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])
install(FILES mymath01.h DESTINATION include)

[brook@:~/Projects/cmake/04]$ mkdir build && cd build
[brook@:~/Projects/cmake/04/build]$ cmake ../src
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/04/build
[brook@:~/Projects/cmake/04/build]$ cmake --build .
Scanning dependencies of target MyMathLib1
[ 25%] Building C object mymath01/CMakeFiles/MyMathLib1.dir/mymath01.c.o
[ 50%] Linking C static library libMyMathLib1.a
[ 50%] Built target MyMathLib1
Scanning dependencies of target Tutorial
[ 75%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
/build/brook/Projects/cmake/04/src/hello.c:6:9: note: #pragma message: use mymath
 #pragma message("use mymath")
         ^~~~~~~
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/04/build]$ make install
[ 50%] Built target MyMathLib1
[100%] Built target Tutorial
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/bin/Tutorial
CMake Error at cmake_install.cmake:47 (file):
  file INSTALL cannot copy file
  "/build/brook/Projects/cmake/04/build/Tutorial" to
  "/usr/local/bin/Tutorial".


Makefile:117: recipe for target 'install' failed
make: *** [install] Error 1
[brook@:~/Projects/cmake/04/build]$ make install DESTDIR=/build/brook/Projects/cmake
[ 50%] Built target MyMathLib1
[100%] Built target Tutorial
Install the project...
-- Install configuration: ""
-- Installing: /build/brook/Projects/cmake/usr/local/bin/Tutorial
-- Installing: /build/brook/Projects/cmake/usr/local/include/Config.h
-- Installing: /build/brook/Projects/cmake/usr/local/lib/libMyMathLib1.a
-- Installing: /build/brook/Projects/cmake/usr/local/include/mymath01.h
[brook@:~/Projects/cmake/04/build]$ tree /build/brook/Projects/cmake/usr/
/build/brook/Projects/cmake/usr/
`-- local
    |-- bin
    |   `-- Tutorial
    |-- include
    |   |-- Config.h
    |   `-- mymath01.h
    `-- lib
        `-- libMyMathLib1.a

4 directories, 4 files


這裡的install主要用了Target/FILES兩個選項, 再搭配DESTINATION參數, DESTINATION是指要安裝到哪個目錄去, 可以是相對路徑或是絕對路徑(relative or absolute paths). 可以透過CMAKE_INSTALL_PREFIX在cmake時設定prefix, 或在make時透過DESTDIR去改變
          
[brook@:~/Projects/cmake/04/src]$ cmake -DCMAKE_INSTALL_PREFIX=/build/brook/Projects/cmake
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/04/src
[brook@:~/Projects/cmake/04/src]$ cmake --build .
Scanning dependencies of target MyMathLib1
[ 25%] Building C object mymath01/CMakeFiles/MyMathLib1.dir/mymath01.c.o
[ 50%] Linking C static library libMyMathLib1.a
[ 50%] Built target MyMathLib1
Scanning dependencies of target Tutorial
[ 75%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
/build/brook/Projects/cmake/04/src/hello.c:6:9: note: #pragma message: use mymath
 #pragma message("use mymath")
         ^~~~~~~
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/04/src]$ make install
[ 50%] Built target MyMathLib1
[100%] Built target Tutorial
Install the project...
-- Install configuration: ""
-- Installing: /build/brook/Projects/cmake/bin/Tutorial
-- Installing: /build/brook/Projects/cmake/include/Config.h
-- Installing: /build/brook/Projects/cmake/lib/libMyMathLib1.a
-- Installing: /build/brook/Projects/cmake/include/mymath01.h
[brook@:~/Projects/cmake/04/src]$ make install DESTDIR=/build/brook/Projects/cmake/04
[ 50%] Built target MyMathLib1
[100%] Built target Tutorial
Install the project...
-- Install configuration: ""
-- Installing: /build/brook/Projects/cmake/04/build/brook/Projects/cmake/bin/Tutorial
-- Installing: /build/brook/Projects/cmake/04/build/brook/Projects/cmake/include/Config.h
-- Installing: /build/brook/Projects/cmake/04/build/brook/Projects/cmake/lib/libMyMathLib1.a
-- Installing: /build/brook/Projects/cmake/04/build/brook/Projects/cmake/include/mymath01.h



2022年6月26日 星期日

CMake - Step 3: Adding Usage Requirements for a Library


這個章節想表達, CMAKE可以透過以下這幾個API, 對include或link有更多的控制
  • target_compile_definitions()
  • target_compile_options()
  • target_include_directories()
  • target_link_libraries()
不過這章只提到target_include_directories(), 其INTERFACE/PUBLIC屬性可以讓consumer能找到該header file, 所以之前Step 2的list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")就可以移除了
[brook@:~/Projects/cmake/03]$ tree src
src
|-- CMakeLists.txt
|-- Config.h.in
|-- hello.c
`-- mymath01
    |-- CMakeLists.txt
    |-- mymath01.c
    `-- mymath01.h

1 directory, 6 files

[brook@:~/Projects/cmake/03]$ cat src/CMakeLists.txt
# Require a minimum version of cmake.
# cmake_minimum_required(VERSION <min>>[...<policy_max>] [FATAL_ERROR])
cmake_minimum_required(VERSION 3.10)

# Set the name of the project.
# project(<PROJECT-NAME< [<anguage-name>...])
# project(<PROJECT-NAME>
#         [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
#         [DESCRIPTION <project-description-string>]
#         [LANGUAGES <language-name>...])
project(Tutorial VERSION 0.1.2.3 DESCRIPTION "This is Brook 1st CMake Lib")

# Add an executable to the project using the specified source files.
# add_executable(<name> [WIN32] [MACOSX_BUNDLE]
#                [EXCLUDE_FROM_ALL]
#                [source1] [source2 ...])
add_executable(Tutorial hello.c)

# option(<variable> "<help_text>" [value])
option(USE_MYMATH "Use tutorial provided math implementation" ON)

# configure_file(<input> <output>
#               [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |
#                FILE_PERMISSIONS <permissions>...]
#               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
#               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(Config.h.in Config.h)

if (USE_MYMATH)
# Add a subdirectory to the build.
# add_subdirectory(source_dir [binary_dir]
#                        [EXCLUDE_FROM_ALL])
add_subdirectory(mymath01)

# list(APPEND <list> [<element> ...])
# Appends elements to the list.
# If no variable named <list> exists in the current
# scope its value is treated as empty and the elements
# are appended to that empty list.
list(APPEND EXTRA_LIBS MyMathLib1)
else()
list(APPEND EXTRA_LIBS "m")
endif()

# Specify libraries or flags to use when linking a given target and/or its dependents.
# target_link_libraries(<target>
#                      <PRIVATE|PUBLIC|INTERFACE> <item>...
#                      [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})

# Add include directories to a target.
# target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
#   <INTERFACE|PUBLIC|PRIVATE> [items1...]
#   [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}")
[brook@:~/Projects/cmake/03]$ cat src/Config.h.in
#cmakedefine USE_MYMATH
[brook@:~/Projects/cmake/03]$ cat src/hello.c
#include <stdio.h>
#include <stdlib.h>
#include "Config.h"

#ifdef USE_MYMATH
#pragma message("use mymath")
#include "mymath01.h"
#else
#pragma message("use system")
#include 
#endif

int main(int argc, char *argv[])
{
#ifdef USE_MYMATH
        printf("mymath: %d\n", squar(atoi(argv[1])));
#else
        printf("system: %d\n", (int)pow(atoi(argv[1]), 2));
#endif
        return 0;
}

[brook@:~/Projects/cmake/03]$ cat src/mymath01/CMakeLists.txt
# Add a library to the project using the specified source files.
# add_library(<name> [STATIC | SHARED | MODULE]
#             [EXCLUDE_FROM_ALL]
#                       source1 [source2 ...])
add_library(MyMathLib1 mymath01.c)

# target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
#  <INTERFACE|PUBLIC|PRIVATE> [items1...]
#    [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
#Remember INTERFACE means things that consumers require but the producer doesn't.
# target_include_directories(MyMathLib1 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(MyMathLib1 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
[brook@:~/Projects/cmake/03]$ cat src/mymath01/mymath01.h
#ifndef MYMATH01_H
#define MYMATH01_H

int squar(int a);

#endif
[brook@:~/Projects/cmake/03]$ cat src/mymath01/mymath01.c
#include "mymath01.h"

int squar(int a)
{
        return a*a;
}

執行結果
[brook@:~/Projects/cmake/03]$ mkdir build && cd build
[brook@:~/Projects/cmake/03/build]$ cmake ../src
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/03/build
[brook@:~/Projects/cmake/03/build]$ make
Scanning dependencies of target MyMathLib1
[ 25%] Building C object mymath01/CMakeFiles/MyMathLib1.dir/mymath01.c.o
[ 50%] Linking C static library libMyMathLib1.a
[ 50%] Built target MyMathLib1
Scanning dependencies of target Tutorial
[ 75%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
/build/brook/Projects/cmake/03/src/hello.c:6:9: note: #pragma message: use mymath
 #pragma message("use mymath")
         ^~~~~~~
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/03/build]$ ./Tutorial 3
mymath: 9
[brook@:~/Projects/cmake/03/build]$ rm -rf *
[brook@:~/Projects/cmake/03/build]$ cmake ../src -DUSE_MYMATH=off
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/03/build
[brook@:~/Projects/cmake/03/build]$ make
Scanning dependencies of target Tutorial
[ 50%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
/build/brook/Projects/cmake/03/src/hello.c:9:9: note: #pragma message: use system
 #pragma message("use system")
         ^~~~~~~
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/03/build]$ ./Tutorial 3
system: 9




2022年6月25日 星期六

CMake - Step 2: Adding A Library As An Option


很多時候我們會在專案中決定使用哪個library, 這裡會舉個範例, 使用自訂的library或是使用系統的library,首先要在最上層的CMakeLists.txt中用option()定義我們的變數USE_MYMATH, on代表用自訂的library, 否則用系統的library, 所以相對應的target_link_libraries()與target_include_directories()也要根據USE_MYMATH稍微做一下調整, 所以我們用EXTRA_LIBS與EXTRA_INCLUDES分別去儲存對應的header file位置與相關的library資訊
# Require a minimum version of cmake.
# cmake_minimum_required(VERSION <min>>[...<policy_max>] [FATAL_ERROR])
cmake_minimum_required(VERSION 3.10)

# Set the name of the project.
# project(<PROJECT-NAME< [<anguage-name>...])
# project(<PROJECT-NAME>
#         [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
#         [DESCRIPTION <project-description-string>]
#         [LANGUAGES <language-name>...])
project(Tutorial VERSION 0.1.2.3 DESCRIPTION "This is Brook 1st CMake Lib")

# Add an executable to the project using the specified source files.
# add_executable(<name> [WIN32] [MACOSX_BUNDLE]
#                [EXCLUDE_FROM_ALL]
#                [source1] [source2 ...])
add_executable(Tutorial hello.c)

# option(<variable> "<help_text>" [value])
option(USE_MYMATH "Use tutorial provided math implementation" ON)

# configure_file(<input> <output>
#               [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |
#                FILE_PERMISSIONS <permissions>...]
#               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
#               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(Config.h.in Config.h)

if (USE_MYMATH)
# Add a subdirectory to the build.
# add_subdirectory(source_dir [binary_dir]
#                        [EXCLUDE_FROM_ALL])
add_subdirectory(mymath01)

# list(APPEND <list> [<element> ...])
# Appends elements to the list.
# If no variable named <list> exists in the current
# scope its value is treated as empty and the elements
# are appended to that empty list.
list(APPEND EXTRA_LIBS MyMathLib1)
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/mymath01")
else()
list(APPEND EXTRA_LIBS "m")
endif()

# Specify libraries or flags to use when linking a given target and/or its dependents.
# target_link_libraries(<target>
#                      <PRIVATE|PUBLIC|INTERFACE> ...
#                      [<PRIVATE|PUBLIC|INTERFACE> ...]...)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})

# Add include directories to a target.
# target_include_directories(&;lt;target> [SYSTEM] [AFTER|BEFORE]
#   &;lt;INTERFACE|PUBLIC|PRIVATE> [items1...]
#   [&;lt;INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}" ${EXTRA_INCLUDES})

接著會利用Config.h.in的cmakedefine去define USE_MYMATH, hello.c則需要include "Config.h"並且利用#ifdef/#else/#endif做一些對應的修改
[brook@:~/Projects/cmake/02-2]$ tree
.
`-- src
    |-- CMakeLists.txt
    |-- Config.h.in
    |-- hello.c
    `-- mymath01
        |-- CMakeLists.txt
        |-- mymath01.c
        `-- mymath01.h

2 directories, 6 files
[brook@:~/Projects/cmake/02-2]$ cat src/Config.h.in
#cmakedefine USE_MYMATH
[brook@:~/Projects/cmake/02-2]$ cat src/hello.c
#include <stdio.h>
#include <stdlib.h>
#include "Config.h"

#ifdef USE_MYMATH
#pragma message("use mymath")
#include "mymath01.h"
#else
#pragma message("use system")
#include 
#endif

int main(int argc, char *argv[])
{
#ifdef USE_MYMATH
        printf("mymath: %d\n", squar(atoi(argv[1])));
#else
        printf("system: %d\n", (int)pow(atoi(argv[1]), 2));
#endif
        return 0;
}

[brook@:~/Projects/cmake/02-2/build]$ cmake ../src
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/02-2/build
[brook@:~/Projects/cmake/02-2/build]$ make
Scanning dependencies of target MyMathLib1
[ 25%] Building C object mymath01/CMakeFiles/MyMathLib1.dir/mymath01.c.o
[ 50%] Linking C static library libMyMathLib1.a
[ 50%] Built target MyMathLib1
Scanning dependencies of target Tutorial
[ 75%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
/build/brook/Projects/cmake/02-2/src/hello.c:6:9: note: #pragma message: use mymath
 #pragma message("use mymath")
         ^~~~~~~
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/02-2/build]$ ./Tutorial 3
mymath: 9
[brook@:~/Projects/cmake/02-2/build]$ cmake ../src/ -DUSE_MYMATH=off
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/02-2/build
[brook@:~/Projects/cmake/02-2/build]$ make
Scanning dependencies of target Tutorial
[ 50%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
/build/brook/Projects/cmake/02-2/src/hello.c:9:9: note: #pragma message: use system
 #pragma message("use system")
         ^~~~~~~
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/02-2/build]$ ./Tutorial 3
system: 9





2022年6月19日 星期日

CMake - Step 2: Adding a Library


這篇主要要談如何建立一個library, 首先我們再src底下創建目錄mymath01用來放置我們的library, 裡面的soucre code包含mymath01.c與mymath01.h, 所以src/CMakeList.txt需要用add_subdirectory(mymath01)告訴CMake要編譯src/mymath01, 而src/mymath01/CMakeList.txt需要描述如何編譯Library, 主要是用add_library()告訴CMake這個library要用哪些source code編譯.
[brook@:~/Projects/cmake/02]$ tree
.
`-- src
    |-- CMakeLists.txt
    `-- mymath01
        |-- CMakeLists.txt
        |-- mymath01.c
        `-- mymath01.h

2 directories, 4 files
[brook@:~/Projects/cmake/02]$ cat src/CMakeLists.txt
# Require a minimum version of cmake.
# cmake_minimum_required(VERSION <min>>[...<policy_max>] [FATAL_ERROR])
cmake_minimum_required(VERSION 3.10)

# Set the name of the project.
# project(<PROJECT-NAME< [<anguage-name>...])
# project(<PROJECT-NAME>
#         [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
#         [DESCRIPTION <project-description-string>]
#         [LANGUAGES <language-name>...])
project(Tutorial VERSION 0.1.2.3 DESCRIPTION "This is Brook 1st CMake Lib")

# Add a subdirectory to the build.
# add_subdirectory(source_dir [binary_dir]
#                        [EXCLUDE_FROM_ALL])
add_subdirectory(mymath01)


[brook@:~/Projects/cmake/02]$ cat src/mymath01/CMakeLists.txt
# Add a library to the project using the specified source files.
# add_library( [STATIC | SHARED | MODULE]
#             [EXCLUDE_FROM_ALL]
#                       source1 [source2 ...])
add_library(MyMathLib1 mymath01.c)

[brook@:~/Projects/cmake/02]$ cat src/mymath01/mymath01.h
#ifndef MYMATH01_H
#define MYMATH01_H

int squar(int a);

#endif
[brook@:~/Projects/cmake/02]$ cat src/mymath01/mymath01.c
#include "mymath01.h"

int squar(int a)
{
  return a*a;
}

[brook@:~/Projects/cmake/02]$ mkdir build && cd build
[brook@:~/Projects/cmake/02/build]$ cmake ../src/
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/02/build
[brook@:~/Projects/cmake/02/build]$ cmake --build .
Scanning dependencies of target MyMathLib1
[ 50%] Building C object mymath01/CMakeFiles/MyMathLib1.dir/mymath01.c.o
[100%] Linking C static library libMyMathLib1.a
[100%] Built target MyMathLib1
[brook@:~/Projects/cmake/02/build]$ ls
CMakeCache.txt  CMakeFiles  Makefile  cmake_install.cmake  mymath01
[brook@:~/Projects/cmake/02/build]$ ls mymath01/
CMakeFiles  Makefile  cmake_install.cmake  libMyMathLib1.a
[brook@:~/Projects/cmake/02/build]$ nm mymath01/libMyMathLib1.a

mymath01.c.o:
0000000000000000 T squar

接著我們結合"Step 1"學的創建一個hello.c來引用MyMathLib1, 我們要用target_link_libraries()將MyMathLib1 link進來.
[brook@:~/Projects/cmake/02]$ tree
.
`-- src
    |-- CMakeLists.txt
    |-- hello.c
    `-- mymath01
        |-- CMakeLists.txt
        |-- mymath01.c
        `-- mymath01.h

2 directories, 5 files

[brook@:~/Projects/cmake/02]$ cat src/CMakeLists.txt
# Require a minimum version of cmake.
# cmake_minimum_required(VERSION <min>>[...<policy_max>] [FATAL_ERROR])
cmake_minimum_required(VERSION 3.10)

# Set the name of the project.
# project(<PROJECT-NAME< [<anguage-name>...])
# project(<PROJECT-NAME>
#         [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
#         [DESCRIPTION <project-description-string>]
#         [LANGUAGES <language-name>...])
project(Tutorial VERSION 0.1.2.3 DESCRIPTION "This is Brook 1st CMake Lib")

# Add an executable to the project using the specified source files.
# add_executable(<name> [WIN32] [MACOSX_BUNDLE]
#                [EXCLUDE_FROM_ALL]
#                [source1] [source2 ...])
add_executable(Tutorial hello.c)

# Specify libraries or flags to use when linking a given target and/or its dependents.
# target_link_libraries(<target>
#                      <PRIVATE|PUBLIC|INTERFACE> ...
#                      [<PRIVATE|PUBLIC|INTERFACE> ...]...)
target_link_libraries(Tutorial PUBLIC MyMathLib1)

# Add include directories to a target.
# target_include_directories(&;lt;target> [SYSTEM] [AFTER|BEFORE]
#   &;lt;INTERFACE|PUBLIC|PRIVATE> [items1...]
#   [&;lt;INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_include_directories(Tutorial PUBLIC "${PROJECT_SOURCE_DIR}/mymath01")

# Add a subdirectory to the build.
# add_subdirectory(source_dir [binary_dir]
#                        [EXCLUDE_FROM_ALL])
add_subdirectory(mymath01)

[brook@:~/Projects/cmake/02]$ cat src/hello.c
#include <stdio.h>
#include <stdlib.h>
#include "mymath01.h"

int main(int argc, char *argv[])
{
  printf("%d\n", squar(atoi(argv[1])));
  return 0;
}
[brook@:~/Projects/cmake/02]$ mkdir build && cd build
[brook@:~/Projects/cmake/02/build]$ cmake ../src
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/02/build
[brook@:~/Projects/cmake/02/build]$ ls
CMakeCache.txt  CMakeFiles  Makefile  cmake_install.cmake  mymath01
[brook@:~/Projects/cmake/02/build]$ cmake --build .
Scanning dependencies of target MyMathLib1
[ 25%] Building C object mymath01/CMakeFiles/MyMathLib1.dir/mymath01.c.o
[ 50%] Linking C static library libMyMathLib1.a
[ 50%] Built target MyMathLib1
Scanning dependencies of target Tutorial
[ 75%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/02/build]$ ls
CMakeCache.txt  CMakeFiles  Makefile  Tutorial  cmake_install.cmake  mymath01
[brook@:~/Projects/cmake/02/build]$ ./Tutorial  5
25

預設是build STATIC, 如果要改成SHARED, 只要加上SHARED這個Key word就可以了add_library(MyMathLib1 SHARED mymath01.c), 並利用set_target_properties()給shared library version與soversion.
[brook@:~/Projects/cmake/02-1]$ mkdir build && cd build
[brook@:~/Projects/cmake/02-1/build]$ cat ../src/mymath01/CMakeLists.txt
# Add a library to the project using the specified source files.
# add_library(<name> [STATIC | SHARED | MODULE]
#             [EXCLUDE_FROM_ALL]
#                       source1 [source2 ...])
add_library(MyMathLib1 SHARED mymath01.c)
set_target_properties(MyMathLib1 PROPERTIES VERSION 1.2.3 SOVERSION 1)

[brook@:~/Projects/cmake/02-1/build]$ cmake ../src
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/02-1/build
[brook@:~/Projects/cmake/02-1/build]$ cmake --build .
Scanning dependencies of target MyMathLib1
[ 25%] Building C object mymath01/CMakeFiles/MyMathLib1.dir/mymath01.c.o
[ 50%] Linking C shared library libMyMathLib1.so
[ 50%] Built target MyMathLib1
Scanning dependencies of target Tutorial
[ 75%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/02-1/build]$ ls -al mymath01/
total 32
drwxrwxrwx 3 brook chbg 4096 Jun 26 21:51 .
drwxrwxrwx 4 brook chbg 4096 Jun 26 21:51 ..
drwxrwxrwx 3 brook chbg 4096 Jun 26 21:51 CMakeFiles
-rw-rw-rw- 1 brook chbg 5602 Jun 26 21:50 Makefile
-rw-rw-rw- 1 brook chbg 1135 Jun 26 21:50 cmake_install.cmake
lrwxrwxrwx 1 brook chbg   18 Jun 26 21:51 libMyMathLib1.so -> libMyMathLib1.so.1
lrwxrwxrwx 1 brook chbg   22 Jun 26 21:51 libMyMathLib1.so.1 -> libMyMathLib1.so.1.2.3
-rwxrwxrwx 1 brook chbg 7440 Jun 26 21:51 libMyMathLib1.so.1.2.3





2022年6月11日 星期六

Table Of Content for "CMake Tutorial"



Step 1: A Basic Starting Point
Step 2: Adding a Library
- Step 2: Adding A Library As An Option
Step 3: Adding Usage Requirements for a Library
Step 4: Installing and Testing
Step 5: Adding System Introspection
Step 6: Adding a Custom Command and Generated File
Step 7: Packaging an Installer
Step 8: Adding Support for a Testing Dashboard
Step 9: Selecting Static or Shared Libraries
Step 10: Adding Generator Expressions
Step 11: Adding Export Configuration
Step 12: Packaging Debug and Release



2022年6月3日 星期五

CMake - Step 1: A Basic Starting Point


本文是CMake Tutorial的心得, CMake是一個用於build, test與package的cross-platform tool, 基本上是透過撰寫CMakeLists來描述如何build, test與package專案,接著會產生makefile, 再透過makefile產生最終的target(executable, library, or both)
讓我們從最簡單的CMakeLists.txt開始,基本上CMakeLists.txt的指令是不分大小寫的
# Require a minimum version of cmake.
# cmake_minimum_required(VERSION <min>>[...<policy_max>] [FATAL_ERROR])
cmake_minimum_required(VERSION 3.10)

# Set the name of the project.
# project(<PROJECT-NAME< [<anguage-name>...])
# project(<PROJECT-NAME>
#         [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
#         [DESCRIPTION <project-description-string>]
#         [HOMEPAGE_URL <url-string>]
#         [LANGUAGES <language-name>...])
project(Tutorial VERSION 0.1.2 DESCRIPTION "This is Brook 1st CMake")

# Add an executable to the project using the specified source files.
# add_executable(<name> [WIN32] [MACOSX_BUNDLE]
#                [EXCLUDE_FROM_ALL]
#                [source1] [source2 ...])
add_executable(Tutorial hello.c)

hello.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        printf("hello world\n");
        return 0;
}

有了CMakeLists.txt與source code, 就可以使用cmake [options] <path-to-source>建立Makefile, 並使用cmake --build <dir>去build targe
[brook@:~/Projects/cmake]$ tree
.
`-- src
    |-- CMakeLists.txt
    `-- hello.c

1 directory, 2 files
[brook@:~/Projects/cmake]$ mkdir build && cd build
[brook@:~/Projects/cmake/build]$ cmake ../src/
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/build
[brook@:~/Projects/cmake/build]$ ls
CMakeCache.txt  CMakeFiles  Makefile  cmake_install.cmake
[brook@:~/Projects/cmake/build]$ cmake --build .
Scanning dependencies of target Tutorial
[ 50%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/build]$ ls
CMakeCache.txt  CMakeFiles  Makefile  Tutorial  cmake_install.cmake
[brook@:~/Projects/cmake/build]$ ./Tutorial
hello world


Adding a Version Number and Configured Header File

前面的CMakeLists.txt中描述了project(Tutorial VERSION 0.1.2 DESCRIPTION "This is Brook 1st CMake"), 但是沒在C code中被用到, 所以, 我們將這些變數加入configure a header file 並傳遞給source code
# Require a minimum version of cmake.
# cmake_minimum_required(VERSION <min>>[...<policy_max>] [FATAL_ERROR])
cmake_minimum_required(VERSION 3.10)

# Set the name of the project.
# project(<PROJECT-NAME< [<anguage-name>...])
# project(<PROJECT-NAME>
#         [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
#         [DESCRIPTION <project-description-string>]
#         [LANGUAGES <language-name>...])
project(Tutorial VERSION 0.1.2 DESCRIPTION "This is Brook 1st CMake")

# Add an executable to the project using the specified source files.
# add_executable(<name> [WIN32] [MACOSX_BUNDLE]
#                [EXCLUDE_FROM_ALL]
#                [source1] [source2 ...])
add_executable(Tutorial hello.c)


# Copy a file to another location and modify its contents.
# configure_file(<input> <output>
#                [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |
#                 FILE_PERMISSIONS <permissions>...]
#                [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
#                [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
configure_file(Config.h.in Config.h)

# Add include directories to a target.
# target_include_directories(&;lt;target> [SYSTEM] [AFTER|BEFORE]
#   &;lt;INTERFACE|PUBLIC|PRIVATE> [items1...]
#   [&;lt;INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}")


首先先透過configure_file()設定configure file的input與output, 在CMake建立Makefile過程中, 就會將configure的input變數取代後, 產生configure的output檔. 由於configure header file要被source code給include進來, 所以還得透過target_include_directories()設定對應的include path. 相關執行步驟如下:
[brook@:~/Projects/cmake]$ tree
.
`-- src
    |-- CMakeLists.txt
    |-- Config.h.in
    `-- hello.c

1 directory, 3 files
[brook@:~/Projects/cmake]$ cat src/Config.h.in
// the configured options and settings for Tutorial

#define VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define VERSION_MINOR @Tutorial_VERSION_MINOR@

[brook@:~/Projects/cmake]$ cat src/hello.c
#include <stdio.h>
#include <stdlib.h>
#include "Config.h"

int main(int argc, char *argv[])
{
        printf("hello world(version: %d.%d)\n", VERSION_MAJOR, VERSION_MINOR);
        return 0;
}

[brook@:~/Projects/cmake]$ mkdir build && cd build
[brook@:~/Projects/cmake/build]$ cmake ../src/
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/build
[brook@:~/Projects/cmake/build]$ ls
CMakeCache.txt  CMakeFiles  Config.h  Makefile  cmake_install.cmake
[brook@:~/Projects/cmake/build]$ cmake --build .
Scanning dependencies of target Tutorial
[ 50%] Building C object CMakeFiles/Tutorial.dir/hello.c.o
[100%] Linking C executable Tutorial
[100%] Built target Tutorial
[brook@:~/Projects/cmake/build]$ ./Tutorial
hello world(version: 0.1)
[brook@:~/Projects/cmake/build]$ cat Config.h
// the configured options and settings for Tutorial
#define VERSION_MAJOR 0
#define VERSION_MINOR 1

在這裡我們有用到幾個CMake的變數, 包含PROJECT_BINARY_DIR, <PROJECT-NAME>_VERSION_MAJOR, PROJECT_BINARY_DIR等等, 這些都可以參考cmake-variables(7)取得更多的變數與相關細節, 我這裡就簡單介紹幾個基本的, 並透過Configure header file讓大家稍微理解一下對應的值
[brook@:~/Projects/cmake/build]$ cat ../src/Config.h.in
// the configured options and settings for Tutorial
#define VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define VERSION_MINOR @Tutorial_VERSION_MINOR@

// <PROJECT-NAME>_BINARY_DIR
// A variable is created with the name used in the project() command,
// and is the binary directory for the project.
#define Tutorial_BINARY_DIR @Tutorial_BINARY_DIR@

// <PROJECT-NAME>_SOURCE_DIR
// Top level source directory for the named project.
// A variable is created with the name used in the project() command,
// and is the source directory for the project.
#define Tutorial_SOURCE_DIR @Tutorial_SOURCE_DIR@

// <PROJECT-NAME>_VERSION
// Value given to the VERSION option of the most recent call
// to the project() command with project name <PROJECT-NAME>
#define Tutorial_VERSION "@Tutorial_VERSION@"
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#define Tutorial_VERSION_PATCH @Tutorial_VERSION_PATCH@
#define Tutorial_VERSION_TWEAK @Tutorial_VERSION_TWEAK@

// Full path to build directory for project.
// This is the binary directory of the most recent project() command.
#define PROJECT_BINARY_DIR @PROJECT_BINARY_DIR@

// Short project description given to the project command.
// This is the description given to the most recent project() command.
#define PROJECT_DESCRIPTION "@PROJECT_DESCRIPTION@"

// Name of the project given to the project command.
// This is the name given to the most recent project() command.
#define PROJECT_NAME @PROJECT_NAME@

// Top level source directory for the current project.
// This is the source directory of the most recent project() command.
#define PROJECT_SOURCE_DIR @PROJECT_SOURCE_DIR@

// Value given to the VERSION option of the most recent call to the project() command
#define PROJECT_VERSION "@PROJECT_VERSION@"
#define PROJECT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define PROJECT_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define PROJECT_VERSION_PATCH @PROJECT_VERSION_PATCH@
#define PROJECT_VERSION_TWEAK @PROJECT_VERSION_TWEAK@

[brook@:~/Projects/cmake/build]$ cmake ../src/
-- Configuring done
-- Generating done
-- Build files have been written to: /build/brook/Projects/cmake/build
[brook@:~/Projects/cmake/build]$ cat Config.h
// the configured options and settings for Tutorial
#define VERSION_MAJOR 0
#define VERSION_MINOR 1

// <PROJECT-NAME>_BINARY_DIR
// A variable is created with the name used in the project() command,
// and is the binary directory for the project.
#define Tutorial_BINARY_DIR /build/brook/Projects/cmake/build

// <PROJECT-NAME>_SOURCE_DIR
// Top level source directory for the named project.
// A variable is created with the name used in the project() command,
// and is the source directory for the project.
#define Tutorial_SOURCE_DIR /build/brook/Projects/cmake/src

// <PROJECT-NAME>_VERSION
// Value given to the VERSION option of the most recent call
// to the project() command with project name <PROJECT-NAME>
#define Tutorial_VERSION "0.1.2"
#define Tutorial_VERSION_MAJOR 0
#define Tutorial_VERSION_MINOR 1
#define Tutorial_VERSION_PATCH 2
#define Tutorial_VERSION_TWEAK

// Full path to build directory for project.
// This is the binary directory of the most recent project() command.
#define PROJECT_BINARY_DIR /build/brook/Projects/cmake/build

// Short project description given to the project command.
// This is the description given to the most recent project() command.
#define PROJECT_DESCRIPTION "This is Brook 1st CMake"

// Name of the project given to the project command.
// This is the name given to the most recent project() command.
#define PROJECT_NAME Tutorial

// Top level source directory for the current project.
// This is the source directory of the most recent project() command.
#define PROJECT_SOURCE_DIR /build/brook/Projects/cmake/src

// Value given to the VERSION option of the most recent call to the project() command
#define PROJECT_VERSION "0.1.2"
#define PROJECT_VERSION_MAJOR 0
#define PROJECT_VERSION_MINOR 1
#define PROJECT_VERSION_PATCH 2
#define PROJECT_VERSION_TWEAK




熱門文章