modern_cpp_hw1

6 篇文章 0 订阅


作业地址: homework_1.pdf (uni-bonn.de)

练习内容:Bash and build system

下载作业:

$ wget https://www.ipb.uni-bonn.de/html/teaching/modern-cpp-2021/homeworks/homework_1.zip
$ mkdir homework_1
$ unzip homework_1.zip  -d ./homework_1/ && rm homework_1.zip

解压之后的作业目录如下所示:

$ tree .
|-- homework_1
| 	|-- task_1
| 	| 	`-- test_folder
| 	`-- task_2
| 		|-- include
| 		| 	`-- ipb_arithmetic
| 		|-- results
| 		| 	|-- bin
| 		| 	`-- lib
| 		`-- src
|-- homework_2
|-- ...

Assignment A (4 points)

用一行语句回答下面四个问题,将结果保存在homework_1/task_1/commands.sh中,语句需要在本地的homework_1/task_1中验证通过。

  1. 计算data.dat有多少行
  2. 计算包含dolor或者dalor单词的语句的行数
  3. 计算在data.dat中有多少个单词?
  4. 计算这些单词里有多少个以mol开头?

提示:wc命令可能会用到。

答案:

$ cat data.dat | wc -l
$ cat data.dat | grep 'd[a,o]lor' | wc -l
$ cat data.dat | wc -w
$ cat data.dat | tr ' ' '\n' | grep '^mol' | wc -l

Assignment B (6 points)

Build System只是工具而已,我们不用深究,只用知道怎么用即可。在Assignment B 中,会给你一个很简单的主程序,该主程序调用了ipb_arithmetic中的两个方法,你需要build 主程序、库文件和将两者链接起来。

本部分的文件结构和实际中的项目类似,包括三部分:

  • Source Files,用来存放源代码
  • Include, 用来存放你的应用/库文件的API
  • Results Artifacts,用来存放输出的二进制文件和库文件

Note:如果调用的是没有开源的第三方库,则可能只有Include 和 Results Artifacts。

补充:在Windows中的项目文件夹开发,参考博客

task_2的文件结构:

.
├── include
│   ├── ipb_arithmetic
│   │   ├── subtract.hpp
│   │   └── sum.hpp
│   └── ipb_arithmetic.hpp
├── LICENSE
├── README.md
├── results
│   ├── bin
│   │   └── example_output
│   └── lib
└── src
    ├── main.cpp
    ├── subtract.cpp
    └── sum.cpp
Exercise1: Build by hand (2 points)

本部分需要你使用old fashion的方法去build library and main program:

  • 使用-c 选项编译得到目标文件,而不使用linker
  • 你需要使用-I ./include/指定编译器寻找header files的位置
  • 你需要通过-o选项指定中间输出的文件的名字

提交内容:一份位于repo根目录位置的 完整的 build bash script build.sh

Task 1: Build the ipb_arithmetic library (1 point)
  1. 创建一个空的文件夹,命名为./build

  2. 编译得到substract.osum.o,可参考的命令c++ -c -I dir/ src/<filename.cpp> -o build/<name.o>,此时./build/目录下会有两个文件:substract.osum.o

  3. 参考下面的代码创建你的library

    # always start the name of your liarary with 'lib'
    ar rcs build/libipb_arithmetic.a build/sum.o build/substract.o
    
Task 2: Build the example program (1 point)

现在你需要build你的主程序,然后和刚刚的库文件链接在一起,当你一切结束后,需要把二进制文件放在results/bin/下面,并命名为test_ipb_arithmetic

Answer for Task1
#!/bin/bash
mkdir build
c++ -c ./src/subtract.cpp -I include/ -o build/subtract.o
c++ -c ./src/sum.cpp -I include/ -o build/sum.o
c++ -c ./src/main.cpp -I include/ -o build/main.o
ar rcs build/libipb_arithmetic.a build/sum.o build/subtract.o
c++ build/main.o -o build/test_ipb_arithmetic -L build/ -l ipb_arithmetic
cp build/test_ipb_arithmetic results/bin/test_ipb_arithmetic

注意:c++的链接命令,-L后面是库文件的目录地址,-l后面是库文件的名称(不要加lib前缀和.a后缀)。

执行后的输出结果:

在这里插入图片描述

Exercise2 : Build by cmake (2points)

该部分使用CMake编译项目,特别注意CMake的版本变更很快,在网上查找资料时,一定注意自己所阅读的doc的版本,在ubuntu20.04中,CMake的版本是3.21.3。(注,笔者所用的cmake版本是3.16.3,可以使用cmake --version查看)

这次我们依然基于Exercise1中的例子,不过是采用cmake实现,需要提交CMakeLists.txt文件。

Answer for Task2

在Task2中可能要提供多个CMakeLists.txt(注意这里可以参考cmake官方的tutorial

cmake_minimum_required(VERSION 3.1)

project(MyMath)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_subdirectory(src)

add_executable(test_ipb_arithmetic src/main.cpp)

target_link_libraries(test_ipb_arithmetic PUBLIC ipb_arithmetic)

target_include_directories(test_ipb_arithmetic PUBLIC "${PROJECT_SOURCE_DIR}/include"  )

src/CMakeLists.txt

add_library(ipb_arithmetic subtract.cpp sum.cpp)
# 尤其注意这里的头文件是给subtract.cpp 和 sum.cpp 的,千万不要漏掉
# 如果库的开发者并不需要引用项目的内容,则可以将此处修改为INTERFACE,这是现代cmake的体现,即 Usage Requirement
target_include_directories(ipb_arithmetic
          PRIVATE ${CMAKE_SOURCE_DIR}/include
          )

此时的文件夹结构如下所示:

在这里插入图片描述

我们运行测试结果是否正确:

在这里插入图片描述

结果一切OK

Exercise3 : Install your library (2points)

这里提供了一些你将来使用第三方library的建议:

  1. 在当前repo下创建一个./install/文件夹
  2. 提供一个install.sh脚本用来安装在发送你的库文件时所需要的所有文件,值得一提的是,这些文件应当在results文件夹中。
  3. 更新你的CMakeLists.txt,以便增加新的target,例如当你运行make install来build 系统的时候,它将会在install文件夹中安装所有需要的文件。

提示1:你应该使用变量CMAKE_INSTALL_PREFIX来指向本地的./local目录,否则cmake将在你的电脑上安装第三方库,这需要超级管理者权限。

提示2install函数可能会有帮助

提示3:当完成所有的练习后,这应当是你所提交的文件夹的样子(当然在cmake之前)

|-- build
| 	|-- libipb_arithmetic.a
| 	|-- main.o
| 	|-- subtract.o
| 	|-- sum.o
| 	`-- test_ipb_arithmetic
|-- build.sh
|-- CMakeLists.txt
|-- include
| 	|-- ipb_arithmetic
| 	| 	|-- subtract.hpp
| 	| 	`-- sum.hpp
| 	`-- ipb_arithmetic.hpp
|-- install
| 	|-- include
| 	| 	|-- ipb_arithmetic
| 	| 	| 	|-- subtract.hpp
| 	| 	| 	`-- sum.hpp
|	| 	`-- ipb_arithmetic.hpp
| 	`-- lib
| 		`-- libipb_arithmetic.a
|-- LICENSE
|-- README.md
|-- results
| 	|-- bin
| 	| 	|-- example_output
| 	| 	`-- test_ipb_arithmetic
| 	`-- lib
| 		`-- libipb_arithmetic.a
`-- src
	|-- CMakeLists.txt
	|-- main.cpp
	|-- subtract.cpp
	`-- sum.cpp
Answer for Task 3

首先,我们在当前repo的目录下创建bash 脚本文件 install.sh,把results/文件夹填充成最终想要的效果:

# build.sh执行之前的results/
|-- results
| 	|-- bin
| 	 	`-- example_output
| 	`-- lib
# build.sh执行之后的results/
|-- results
| 	|-- bin
| 	| 	|-- example_output
| 	| 	`-- test_ipb_arithmetic
| 	`-- lib
| 		`-- libipb_arithmetic.a

注意这里的test_ipb_arithmethic就是可执行文件,在Excercise1中我们把它放在build/下面,然后通过下面的install.sh将文件拷贝到results/bin中:

# install.sh
cp build/libipb_arithmetic.a results/lib/
cp build/test_ipb_arithmetic results/bin/

这里比较让我疑惑的是,最终要提交的结果中并没有install.sh,我觉得可以把这里的两条命令添加到build.sh(其实第二条命令在build.sh中已经有了),修改后的build.sh如下:

#!/bin/bash
mkdir build
c++ -c ./src/subtract.cpp -I include/ -o build/subtract.o
c++ -c ./src/sum.cpp -I include/ -o build/sum.o
c++ -c ./src/main.cpp -I include/ -o build/main.o
ar rcs build/libipb_arithmetic.a build/sum.o build/subtract.o
c++ build/main.o -o build/test_ipb_arithmetic -L build/ -l ipb_arithmetic
cp build/test_ipb_arithmetic results/bin/test_ipb_arithmetic
cp build/libipb_arithmetic.a results/lib/

第二步,我们修改顶层的CMakeLists.txt

最终要实现的效果如下所示:

|-- install
| 	|-- include
| 	| 	|-- ipb_arithmetic
| 	| 	| 	|-- subtract.hpp
| 	| 	| 	`-- sum.hpp
|	| 	`-- ipb_arithmetic.hpp
| 	`-- lib
| 		`-- libipb_arithmetic.a

关于cmake中的install命令,可以参考CMake之install方法的使用 - 知乎 (zhihu.com),这里最终要求的install/文件夹位于本项目内,而不是默认的usr/local/,所以作业中建议修改根目录选项CMAKE_INSTALL_PREFIX

# 修改安装路径为当前项目目录下的install/文件夹
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install)

按照作业的要求,我们使用install将库文件、可执行文件和头文件安装到指定目录,这里的根目录就是上面的CMAKE_INSTALL_PREFIX

# 修改安装路径为当前项目目录下的install/文件夹
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install)
# 将库文件、可执行文件和头文件安装到指定目录
install(TARGETS test_ipb_arithmetic ipb_arithmetic
        EXPORT MyLibTargets # find_package会用到
        # LIBRARY DESTINATION lib  # 动态库安装路径
        ARCHIVE DESTINATION lib  # 静态库安装路径
        RUNTIME DESTINATION bin  # 可执行文件安装路径
        )
install(DIRECTORY  ${CMAKE_SOURCE_DIR}/include  DESTINATION  include )

从最终结果看,这里并没有要求安装可执行文件以及版本信息等额外的cmake文件,所以略去。

这里修改后的CMakeLists.txt如下:

cmake_minimum_required(VERSION 3.1)

project(MyMath)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# 修改安装路径为当前项目目录下的install/文件夹
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install)


add_subdirectory(src)

add_executable(test_ipb_arithmetic src/main.cpp)

target_link_libraries(test_ipb_arithmetic PUBLIC ipb_arithmetic)

target_include_directories(test_ipb_arithmetic PUBLIC "${PROJECT_SOURCE_DIR}/include"  )

# 将库文件、可执行文件和头文件安装到指定目录
install(TARGETS test_ipb_arithmetic ipb_arithmetic
        EXPORT MyLibTargets # find_package会用到
        # LIBRARY DESTINATION lib  # 动态库安装路径
        ARCHIVE DESTINATION lib  # 静态库安装路径
        RUNTIME DESTINATION bin  # 可执行文件安装路径
        )
install(DIRECTORY  ${CMAKE_SOURCE_DIR}/include  DESTINATION  include )

src/CMakeLists.txt不需要修改:

add_library(ipb_arithmetic subtract.cpp sum.cpp)
# 尤其注意这里的头文件是给subtract.cpp 和 sum.cpp 的,千万不要漏掉
# 如果库的开发者并不需要引用项目的内容,则可以将此处修改为INTERFACE,这是现代cmake的体现,即 Usage Requirement
target_include_directories(ipb_arithmetic
          PRIVATE ${CMAKE_SOURCE_DIR}/include
          )

cmake过程的输出:

在这里插入图片描述

最后cmake之后的install/

在这里插入图片描述

最终整理后的项目结构:

在这里插入图片描述

参考文献

[1] 有关Git基本使用方法:ubuntu配置git并使用github管理项目

[2] 有关CMake的更多使用方法,可以参考了CMake Tutorial — CMake 3.17.5 DocumentationCMake教程_知乎简略版CMake教程_CSDN完整版,后两个教程基本就是官方Tutorial的翻译,所以更推荐官方教程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值