C++で開発したい。今までXcodeとかに環境は良い感じにしてもらっていたが、CMake入門する。 とりあえず今回はC++ファイルを作成しCMakeでコンパイルして実行するまで行う。
そもそも
C++で実行ファイルを作るにはコンパイルしないといけないが、クロスプラットフォームで開発する場合に環境ごとにコンパイラを選定することや、コンパイル手順を設定するのは大変やっかいである。それらが面倒なのでCMakeにもろもろお願いする。
vscode
VSCode環境でcmakeを使う。
拡張機能
- C/C++
- デバッガ -> CodeLLDB
- CMake Tools
ここを参考に設定する。デバッガはLLDBを使う。
F5
またはShift + CMD + P
でコマンドパレットを開いてCMake : Debug
を実行。
簡単なプロジェクト
C++ファイルを追加して使う簡単なプロジェクトを作る。 csvをパースして表示する簡単なクラスCSVParserと値を保存するだけのMyClassを作成
コード : github.com/gollowars/cpp_cmake_bootstrap
ファイルツリー
├── CMakeLists.txt
├── data
│ └── sample.csv
├── include
│ ├── CSVParser.h
│ └── MyClass.h
└── src
├── CSVParser.cpp
├── MyClass.cpp
└── main.cpp
main.cpp
#include <iostream>
#include <filesystem>
#include "MyClass.h"
#include "CSVParser.h"
int main(int, char**) {
std::cout << "Hello, world test7 !\n";
if (__cplusplus == 201703L) std::cout << "C++17\n";
else if (__cplusplus == 201402L) std::cout << "C++14\n";
else if (__cplusplus == 201103L) std::cout << "C++11\n";
else if (__cplusplus == 199711L) std::cout << "C++98\n";
else std::cout << "Pre-standard C++\n";
MyClass my_class(42);
std::cout << my_class.get_value() << std::endl;
std::filesystem::path current_path = std::filesystem::current_path();
std::filesystem::path data_path = current_path / "data";
std::filesystem::path sample_path = data_path / "sample.csv";
CSVParser parser(sample_path.string());
parser.parse();
parser.print();
return 0;
}
sample.csv
name,age,gender
Alice,25,Female
Bob,30,Male
Charlie,40,Male
MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass {
public:
MyClass(int value);
int get_value() const;
private:
int m_value;
};
#endif
MyClass.cpp
#include "MyClass.h"
MyClass::MyClass(int value) : m_value(value) {}
int MyClass::get_value() const {
return m_value;
}
CSVParser.h
#ifndef CSV_PARSER_H
#define CSV_PARSER_H
#include <string>
#include <vector>
class CSVParser {
public:
CSVParser(const std::string& filename);
~CSVParser();
void parse();
void print();
private:
std::string _filename;
std::vector<std::string> _fields;
};
#endif
CSVParser.cpp
#include "CSVParser.h"
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iostream>
CSVParser::CSVParser(const std::string& filename) {
_filename = filename;
}
CSVParser::~CSVParser() {
// nothing to do
}
void CSVParser::parse() {
// TODO
std::ifstream file(_filename);
std::string line;
if(file.is_open()){
std::cout << "file is open" << std::endl;
}else {
std::cout << "file is not open" << std::endl;
}
while(std::getline(file, line)) {
std::stringstream ss(line);
std::string field;
std::string linestr;
while(std::getline(ss, field, ',')) {
linestr += field + ",";
// _fields.push_back(field);
}
// std::cout << linestr << std::endl;
_fields.push_back(linestr);
}
file.close();
}
void CSVParser::print(){
std::cout << "size : " + std::to_string(_fields.size()) << std::endl;
// TODO
for(auto& field : _fields) {
std::cout << field << std::endl;
}
std::cout << std::endl;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
# プロジェクト名
project(Example VERSION 0.1.0)
# include(CTest)
# enable_testing()
# C++標準の設定
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True) ## C++11であることを指定して、C++11以外のコンパイラを使うとエラーにする
# buildターゲット(この場合はPROJECT_NAMEであるExampleに)main.cppを追加
add_executable(${PROJECT_NAME} ./src/main.cpp)
# ヘッダーファイルの読み込み
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
## ソースファイルを追加する
set(MY_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_sources(${PROJECT_NAME} PRIVATE
${MY_SOURCE_DIR}/MyClass.cpp
${MY_SOURCE_DIR}/CSVParser.cpp
)
## assetをコピーする
configure_file(${CMAKE_SOURCE_DIR}/data/sample.csv ${CMAKE_CURRENT_BINARY_DIR}/data/sample.csv COPYONLY)
get_target_property(headers ${PROJECT_NAME} SOURCES)
message(STATUS "headers : ${headers}") # これはあってもなくても良い。メッセージを出力する確認
これでCMake : Debug
すると
Hello, world test7 !
C++17
42
file is open
size : 4
name,age,gender,
Alice,25,Female,
Bob,30,Male,
Charlie,40,Male,
と無事出力
今回の完成ファイルはこちら https://github.com/gollowars/cpp_cmake_bootstrap/tree/main
C++開発シリーズ
- C++開発とCMake ~その1 : CMake入門~
- C++開発とCMake ~その2 : 自作ライブラリの作り方~
- C++開発とCMake ~その3 : 外部ライブラリを自前でビルドして使う(OSC with liblo)~
- CMakeコマンド基本中の基本
- VSCodeでC++開発 拡張機能CMake ToolsとC/C++の設定