Skip to content

Instantly share code, notes, and snippets.

@NickTikhomirov
Created April 1, 2019 20:23
Show Gist options
  • Save NickTikhomirov/f90dead7e7c5a601422e6c51dbc7d4f6 to your computer and use it in GitHub Desktop.
Save NickTikhomirov/f90dead7e7c5a601422e6c51dbc7d4f6 to your computer and use it in GitHub Desktop.
lab03

Laboratory work III

Данная лабораторная работа посвещена изучению систем автоматизации сборки проекта на примере CMake

Открываем сайт CMake

$ open https://cmake.org/

Tasks

  • 1. Создать публичный репозиторий с названием lab03 на сервисе GitHub
  • 2. Ознакомиться со ссылками учебного материала
  • 3. Выполнить инструкцию учебного материала
  • 4. Составить отчет и отправить ссылку личным сообщением в Slack

Tutorial

Присваиваем мой логин на GitHub переменной GITHUB_USERNAME

$ export GITHUB_USERNAME=NickTikhomirov

Подготовка к работе (идентичный блок встречался в прежних работах)

#Меняем директорию на заданную
$ cd ${GITHUB_USERNAME}/workspace
#Сохраняем предыдущую директорию
$ pushd .
~/NickTikhomirov/workspace ~
#Запускаем созданный в одной из прежних лабораторных скрипт
$ source scripts/activate

Получаем всё по lab02 с github и немного видоизменяем с целью получения заготовки lab03

#Скачиваем lab02 с github в создаваемую projects/lab03
$ git clone https://github.com/${GITHUB_USERNAME}/lab02.git projects/lab03
#Заходим в директорию, в которую было положено скачанное
$ cd projects/lab03
#Убираем привязанный прежде git
$ git remote remove origin
#Устанавливаем новый git
$ git remote add origin https://github.com/${GITHUB_USERNAME}/lab03.git

Компилируем example1

#Компилируем print.cpp с заголовками из ./include и по стандарту 11 года
$ g++ -std=c++11 -I./include -c sources/print.cpp
#Проверяем наличие файла
$ ls print.o
print.o
#Печатаем символы из файла с расширением .o - объектного файла
$ nm print.o | grep print
00000076 t __GLOBAL__sub_I__Z5printRKSsRSo
00000000 T __Z5printRKSsRSo
0000001b T __Z5printRKSsRSt14basic_ofstreamIcSt11char_traitsIcEE
#Архивируем print.o в print.a (с указанием выводить подробную информацию)
$ ar rvs print.a print.o
ar: creating print.a
a - print.o
#Получаем тип файла print.a
$ file print.a
print.a: current ar archive
#Компилируем example1.cpp с заголовками из ./include и по стандарту 11 года
$ g++ -std=c++11 -I./include -c examples/example1.cpp
#Проверяем наличие файла
$ ls example1.o
example1.o
#Линковка с последующим выводом в example1
$ g++ example1.o print.a -o example1
#Выполняем example1 и выводим его результаты
$ ./example1 && echo
hello

Компилируем example2

#Компилируем print.cpp
$ g++ -std=c++11 -I./include -c examples/example2.cpp
#Вывод содержимого итогового файла
$ nm example2.o
00000000 b .bss
00000000 d .ctors
00000000 d .data
00000000 r .eh_frame
00000000 r .eh_frame$_ZStorSt13_Ios_OpenmodeS_
00000000 d .gcc_except_table
00000000 r .rdata
00000000 r .rdata$zzz
00000000 t .text
00000000 t .text$_ZStorSt13_Ios_OpenmodeS_
         U ___cxa_atexit
         U ___dso_handle
         U ___gxx_personality_v0
         U ___main
00000136 t __GLOBAL__sub_I_main
         U __Unwind_Resume
000000f6 t __Z41__static_initialization_and_destruction_0ii
         U __Z5printRKSsRSt14basic_ofstreamIcSt11char_traitsIcEE
         U __ZNSaIcEC1Ev
         U __ZNSaIcED1Ev
         U __ZNSsC1EPKcRKSaIcE
         U __ZNSsD1Ev
         U __ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode
         U __ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev
         U __ZNSt8ios_base4InitC1Ev
         U __ZNSt8ios_base4InitD1Ev
00000000 r __ZStL19piecewise_construct
00000000 b __ZStL8__ioinit
00000000 T __ZStorSt13_Ios_OpenmodeS_
00000000 T _main
#Линковка с последующим выводом в example2
$ g++ example2.o print.a -o example2
#Выполняем example2
$ ./example2
#Выводим результат его работы, переходим на новую строку
$ cat log.txt && echo
hello

Удаляем все названные файлы

$ rm -rf example1.o example2.o print.o
$ rm -rf print.a
$ rm -rf example1 example2
$ rm -rf log.txt

Пишем в файл информацию по минимальной приемлемой версии CMake

$ cat > CMakeLists.txt <<EOF
cmake_minimum_required(VERSION 3.4)
project(print)
EOF

Пишем в файл информацию по используемому стандарту языка С++

$ cat >> CMakeLists.txt <<EOF
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
EOF

Пишем в файл информацию - команду добавления библиотеки

$ cat >> CMakeLists.txt <<EOF
add_library(print STATIC \${CMAKE_CURRENT_SOURCE_DIR}/sources/print.cpp)
EOF

Пишем в файл информацию - команду подключения используемых директорий

$ cat >> CMakeLists.txt <<EOF
include_directories(\${CMAKE_CURRENT_SOURCE_DIR}/include)
EOF
#Настройка с учётом взятия CMakeLists.txt из текущей директории и сохранения его в _build
$ cmake -H. -B_build
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.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++.exe
-- Check for working CXX compiler: /usr/bin/c++.exe -- 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: /home/Никита/NickTikhomirov/workspace/projects/lab03/_build
#Выполнение всего того, что мы ранее писали в CMakeLists.txt
$ cmake --build _build
Scanning dependencies of target print
[ 50%] Building CXX object CMakeFiles/print.dir/sources/print.cpp.o
[100%] Linking CXX static library libprint.a
[100%] Built target print

Пишем в файл команды по добавлению задач на создание исполняемых файлов

$ cat >> CMakeLists.txt <<EOF
add_executable(example1 \${CMAKE_CURRENT_SOURCE_DIR}/examples/example1.cpp)
add_executable(example2 \${CMAKE_CURRENT_SOURCE_DIR}/examples/example2.cpp)
EOF

Пишем в файл команды для линковки

$ cat >> CMakeLists.txt <<EOF
target_link_libraries(example1 print)
target_link_libraries(example2 print)
EOF

Компиляция библиотеки и выполняемых файлов

#Выполняем поставленные задачи (находясь при этом в директории _build)
$ cmake --build _build
-- Configuring done
-- Generating done
-- Build files have been written to: /home/Никита/NickTikhomirov/workspace/projects/lab03/_build
[ 33%] Built target print
Scanning dependencies of target example2
[ 50%] Building CXX object CMakeFiles/example2.dir/examples/example2.cpp.o
[ 66%] Linking CXX executable example2.exe
[ 66%] Built target example2
Scanning dependencies of target example1
[ 83%] Building CXX object CMakeFiles/example1.dir/examples/example1.cpp.o
[100%] Linking CXX executable example1.exe
[100%] Built target example1
#Выполнение для print
$ cmake --build _build --target print
[100%] Built target print
#Выполнение для example1
$ cmake --build _build --target example1
[ 50%] Built target print
[100%] Built target example1
#Выполнение для example2
$ cmake --build _build --target example2
[ 50%] Built target print
[100%] Built target example2

Проверяем полученные файлы

#Проверяем наличие файла (с выводом информации о нём)
$ ls -la _build/libprint.a
-rw-r--r--+ 1 Никита Отсутствует 1872 Apr  1 17:49 _build/libprint.a
#Выполнение первого файла, вывод его результата работы и перенос строки
$ _build/example1 && echo
hello
#Выполнение второго файла
$ _build/example2
#Вывод результатов работы второго файла (сохранённых в log.txt) и перенос строки
$ cat log.txt && echo
hello
#Удаление лога
$ rm -rf log.txt

Получаем файл CMakeLists.txt в составе папки tmp. Сам файл оставляем, остальное выкидываем

#Получаем tmp с github
$ git clone https://github.com/tp-labs/lab03 tmp
remote: Enumerating objects: 24, done.
remote: Counting objects: 100% (24/24), done.
remote: Compressing objects: 100% (18/18), done.
remote: Total 67 (delta 4), reused 24 (delta 4), pack-reused 43
Unpacking objects: 100% (67/67), done.
#Переносим CMakeLists.txt из tmp
$ mv -f tmp/CMakeLists.txt .
#Удаляем tmp со всем содержимым
$ rm -rf tmp

Компиляция с учётом скачанного ранее CMakeLists

#Выводим содержимое файла
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.0)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

option(BUILD_EXAMPLES "Build examples" OFF)

project(print)

add_library(print STATIC ${CMAKE_CURRENT_SOURCE_DIR}/sources/print.cpp)

target_include_directories(print PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  $<INSTALL_INTERFACE:include>
)

if(BUILD_EXAMPLES)
  file(GLOB EXAMPLE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/examples/*.cpp")
  foreach(EXAMPLE_SOURCE ${EXAMPLE_SOURCES})
    get_filename_component(EXAMPLE_NAME ${EXAMPLE_SOURCE} NAME_WE)
    add_executable(${EXAMPLE_NAME} ${EXAMPLE_SOURCE})
    target_link_libraries(${EXAMPLE_NAME} print)
    install(TARGETS ${EXAMPLE_NAME}
      RUNTIME DESTINATION bin
    )
  endforeach(EXAMPLE_SOURCE ${EXAMPLE_SOURCES})
endif()

install(TARGETS print
    EXPORT print-config
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
)

install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include)
install(EXPORT print-config DESTINATION cmake)

#Снова настройка
$ cmake -H. -B_build -DCMAKE_INSTALL_PREFIX=_install
-- Configuring done
-- Generating done
-- Build files have been written to: /home/Никита/NickTikhomirov/workspace/projects/lab03/_build

#Выполняем задачи для install
$ cmake --build _build --target install
[100%] Built target print
Install the project...
-- Install configuration: ""
-- Installing: /home/Никита/NickTikhomirov/workspace/projects/lab03/_install/lib/libprint.a
-- Installing: /home/Никита/NickTikhomirov/workspace/projects/lab03/_install/include
-- Installing: /home/Никита/NickTikhomirov/workspace/projects/lab03/_install/include/print.hpp
-- Installing: /home/Никита/NickTikhomirov/workspace/projects/lab03/_install/cmake/print-config.cmake
-- Installing: /home/Никита/NickTikhomirov/workspace/projects/lab03/_install/cmake/print-config-noconfig.cmake
#Вывод _install в форме дерева
$ tree _install
_install
├── cmake
│   ├── print-config.cmake
│   └── print-config-noconfig.cmake
├── include
│   └── print.hpp
└── lib
    └── libprint.a

3 directories, 4 files

Выкладываем результаты нашей работы на github

#Добавляем на файл CMakeLists.txt на github
$ git add CMakeLists.txt
#Добавляем коммит об этом
$ git commit -m"added CMakeLists.txt"
[master 0860a0c] added CMakeLists.txt
 1 file changed, 36 insertions(+)
 create mode 100644 CMakeLists.txt
#Push в ветку "мастер"
$ git push origin master
Counting objects: 21, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (16/16), done.
Writing objects: 100% (21/21), 3.59 KiB | 367.00 KiB/s, done.
Total 21 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), done.
To https://github.com/NickTikhomirov/lab03.git
 * [new branch]      master -> master

Report

$ popd
$ export LAB_NUMBER=03
$ git clone https://github.com/tp-labs/lab${LAB_NUMBER} tasks/lab${LAB_NUMBER}
$ mkdir reports/lab${LAB_NUMBER}
$ cp tasks/lab${LAB_NUMBER}/README.md reports/lab${LAB_NUMBER}/REPORT.md
$ cd reports/lab${LAB_NUMBER}
$ edit REPORT.md
$ gistup -m "lab${LAB_NUMBER}"

Homework

Представьте, что вы стажер в компании "Formatter Inc.".

Задание 1

Вам поручили перейти на систему автоматизированной сборки CMake. Исходные файлы находятся в папке formatter_lib. В этой директории находятся файлы для статической библиотеки formatter. Создайте CMakeList.txt в директории formatter_lib, с помощью которого можно будет собирать статическую библиотеку formatter.

Задание 2

У компании "Formatter Inc." есть перспективная библиотека, которая является расширением предыдущей библиотеки. Т.к. вы уже овладели навыком созданием CMakeList.txt для статической библиотеки formatter, ваш руководитель поручает заняться созданием CMakeList.txt для библиотеки formatter_ex, которая в свою очередь использует библиотеку formatter.

Задание 3

Конечно же ваша компания предоставляет примеры использования своих библиотек. Чтобы продемонстрировать как работать с библиотекой formatter_ex, вам необходимо создать два CMakeList.txt для двух простых приложений:

  • hello_world, которое использует библиотеку formatter_ex;
  • solver, приложение которое испольует статические библиотеки formatter_ex и solver_lib.

Удачной стажировки!

Links

Copyright (c) 2015-2019 The ISC Authors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment