cmake・CMakeLists.txt - QSerialPort

 クラウディア
1. 概要
2. 状況
3. include_directories
4. -fPIC
5. qt_version_tag
6. Qt5::SerialPort
7. find_package

1. 概要

 シリアルポートの通信プログラムを書く際に、「Qt5」の「QSerialPort」を使ってみようと思ったのです。  ソースに関しては、別の章に書くかもしれないが・・・。  その際に、「CMakeLists.txt」を書くのにあれこれメモしておかなければならないことがあったので残します。  「CMakeLists.txt」自体ではなく、単にコンパイルオプションの話もありますが・・・。  本ページは、下記のサイトを参考にさせていただきました。
clang++ CPLUS_INCLUDE_PATH を使ったインクルードパスの追加」
「c++ - Why do I get this "error: undefined reference to `qt_version_tag' "?」
「cmake - How to fix undefined reference to QSerialPortInfo?

2. 状況

 ソースとして、下記のものがあります。

main.cpp
serial.cpp
serial.hpp
 「serial.cpp」の中で、「QSerialPort」を使うクラスを定義しています・・・ぞと。  最初に作成した、「CMakeLists.txt」の内容が。

cmake_minimum_required(VERSION 3.12)
project(sample CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-g -O0")

set(EXEC_NAME sample)
file(GLOB SOURCE *.cpp *.hpp)
add_executable(${EXEC_NAME} ${SOURCE})

target_link_libraries(${EXEC_NAME})
 ビルドは、前のページと重なりますが。

mkdir -pv build && cd build

cmake ..

make
 で行います。

3. include_directories

 まず、「make」のときに。

In file included from /home/hogehoge/sample/main.cpp:1:
/home/hogehoge/sample/serial.hpp:27:10: fatal error: QtSerialPort/QSerialPort: そのようなファイルやディレクトリはありません
   27 | #include <QtSerialPort/QSerialPort>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
 てなエラーになりました。  インクルードパスが、足りませなんだ。  「CMakeLists.txt」の「CMAKE_CXX_FLAGS」の記述の後に、下記の行を加えます。

include_directories(/usr/include/x86_64-linux-gnu/qt5)

4.  -fPIC

 次に。

In file included from /usr/include/x86_64-linux-gnu/qt5/QtCore/qiodevice.h:43,
                 from /usr/include/x86_64-linux-gnu/qt5/QtSerialPort/qserialport.h:44,
                 from /usr/include/x86_64-linux-gnu/qt5/QtSerialPort/QSerialPort:1,
                 from /home/hogehoge/sample/serial.hpp:27,
                 from /home/hogehoge/sample/main.cpp:1:
/usr/include/x86_64-linux-gnu/qt5/QtCore/qglobal.h:1287:4: error: #error "You must build your code with position independent code if Qt was built with -reduce-relocations. " "Compile your code with -fPIC (and not with -fPIE)."
 1287 | #  error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\
      |    ^~~~~
 てな、エラーが・・・。  「CMAKE_CXX_FLAGS」の行を書き換えます。

set(CMAKE_CXX_FLAGS "-g -O0 -fPIC")

5. qt_version_tag

 次に。

/usr/bin/ld: CMakeFiles/sample.dir/main.cpp.o:(.qtversion[qt_version_tag]+0x0): undefined reference to `qt_version_tag'
collect2: error: ld returned 1 exit status
 てな、エラーが・・・。  これは、参考サイトのお世話になりました。  「CMAKE_CXX_FLAGS」の行を書き換えます。

set(CMAKE_CXX_FLAGS "-g -O0 -fPIC -DQT_NO_VERSION_TAGGING")

6. Qt5::SerialPort

 今度は。

/usr/bin/ld: CMakeFiles/sample.dir/serial.cpp.o: in function `Serial::Serial()':
/home/hogehoge/sample/serial.cpp:22:(.text+0x33): undefined reference to `QSerialPort::QSerialPort(QObject*)'
/usr/bin/ld: CMakeFiles/sample.dir/serial.cpp.o: in function `Serial::~Serial()':
/home/hogehoge/sample/serial.cpp:34:(.text+0x70): undefined reference to `QSerialPort::~QSerialPort()'
collect2: error: ld returned 1 exit status
 ライブラリが足りてないので・・・。  「target_link_libraries」の行を、書き換えます。

target_link_libraries(${EXEC_NAME} Qt5::SerialPort)

7. find_package

 今度は。

CMake Error at CMakeLists.txt:15 (target_link_libraries):
  Target "sample" links to:

    Qt5::SerialPort

  but the target was not found.  Possible reasons include:
 これも参考サイトのお世話になって、「CMAKE_CXX_FLAGS」の行の後に、下記の行を追加します。

find_package(Qt5 CONFIG REQUIRED Core Widgets Gui SerialPort)
 これで、やっと「make」が通るようになりました。
AbemaTV 無料体験