CMake multi main() entrance project construction (brush topic direction)

In ACM algorithm competition / LeetCode using C + + to brush questions and other scenarios, usually:

  • A lot of C + + source code needs to be maintained
  • Multiple main function entries are required to facilitate test execution
  • Some self written public function class libraries (such as debug output vector, etc.) are referenced in multiple files

This paper introduces the method of managing all codes through CMake and some self generated configuration file tools and a unified library.

CMake is a platform independent tool that can customize the C + + compilation process and generate Makefile files for specific platforms. Supported by Intellij CLion by default.

You need to first create a C + + project through CLion:

 

Create the directory structure you need: we put all the source code cpp and other files are placed in / src, and some tool classes are placed in / src/utils

 

 

 

 

 

 

CMakeLists.txt file is our CMake compilation process configuration file. To support multiple main () function entries, we use add_ The executable command adds multiple target s, which can be executed separately at each main() entry:

cmake_minimum_required(VERSION 3.17)
project(lc-cpp)

set(CMAKE_CXX_STANDARD 17)
add_definitions("-DKUN_DEBUG")

add_executable(training_p1 src/normal/cat0/cat00/cat000/p1.cpp)
add_executable(training_p15 src/normal/cat0/cat00/cat001/p15.cpp)
add_executable(biweekly_34_2 src/match/biweekly/biweekly34/p2.cpp)
add_executable(biweekly_34_3 src/match/biweekly/biweekly34/p3.cpp)
add_executable(biweekly_34_4 src/match/biweekly/biweekly34/p4.cpp)

Next, we deal with the problem of public class libraries. We only need to declare the utils directory under the search path of the compiler's header file, so that it can be referenced by other files.

Basic data structures such as LeetCode's treenode and listnode and their parsing and debug ging tools can be placed here:

include_directories("src/utils")

 

 

 

Let's solve the last problem. We create some at a time After cpp code, you need to go to cmakelists Txt file_ Executable code. We can automatically generate this part of work in the form of script, and attach Python 3 code:

import os

HEAD = '''cmake_minimum_required(VERSION 3.17)
project(lc-cpp)

set(CMAKE_CXX_STANDARD 17)
add_definitions("-DKUN_DEBUG")
include_directories("src/utils")

'''


def update_cmake():
    file_list = []
    for root, dirs, files in os.walk("src"):
        if len(files) == 0:
            continue
        for f in files:
            file_list.append(root + os.sep + f)
    res = HEAD
    for i in sorted(file_list):
        if 'utils' in i:
            continue
        split = i.split(os.sep)
        name_ids = filter(lambda x: x != 'src', split)
        name = "_".join(name_ids).replace(".cpp", "")
        path = "/".join(split)
        code = f'add_executable({name} {path})\n'
        res += code
    with open('CMakeLists.txt', "w") as f:
        f.write(res)


if __name__ == '__main__':
    update_cmake()

 

So far, by managing all topics according to classified folders, and then automatically generating executable file compilation configuration, a relatively complete project environment convenient for C + + topic brushing is created.

 

 

Finally, a basic class commonly used by LeetCode and its parsing and output tool (common_ds.hpp) are attached:

/**
 * LeetCode Common DataStruct.
 */
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

struct TreeNode {

    int val;
    TreeNode *left;
    TreeNode *right;

    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}

    TreeNode(int val, TreeNode *left, TreeNode *right) : val(val), left(left), right(right) {}
};


static TreeNode *parse_tree(string s) {
    const regex re(",");
    vector<string> v(sregex_token_iterator(++s.begin(), --s.end(), re, -1), sregex_token_iterator());
    if (v.empty()) return nullptr;
    vector<TreeNode *> ns;
    ns.push_back(new TreeNode(stoi(v.front())));
    for (int i = 1; i < v.size(); ++i) {
        TreeNode *cur = v[i].find("null") != string::npos ? nullptr : new TreeNode(stoi(v[i]));
        if (i % 2 == 1) ns[(i - 1) / 2]->left = cur;
        else ns[(i - 1) / 2]->right = cur;
        if (cur) ns.push_back(cur);
    }
    return ns.front();
}

static string to_string(TreeNode *root) {
    if (!root) return "null";
    if (!root->left && !root->right) return to_string(root->val);
    return "{" + to_string(root->val) + ", " + to_string(root->left) + ", " + to_string(root->right) + "}";
}

static void print(TreeNode *head, int len = 4, int height = 0, string to = "#") {
    if (!head) return;
    print(head->right, len, height + 1, "v");
    string val = to + to_string(head->val);
    int lenM = val.length(), lenL = (len - lenM) / 2, lenR = len - lenM - lenL;
    val = string(height * len, ' ') + string(lenL, ' ') + val + string(lenR, ' ');
    cout << val << endl;
    print(head->left, len, height + 1, "^");
}

/// =========================================================================

struct ListNode {

    int val;
    ListNode *next;

    ListNode(int x) : val(x), next(nullptr) {}
};

static ListNode *parse_list(string s) {
    const regex re("->");
    vector<string> v(sregex_token_iterator(s.begin(), s.end(), re, -1), sregex_token_iterator());
    ListNode *mock = new ListNode(-1), *p = mock;
    for (auto &i : v) {
        p->next = new ListNode(stoi(i));
        p = p->next;
    }
    return mock->next;
}

static string to_string(ListNode *node) {
    if (!node) return "";
    return to_string(node->val) + (node->next ? "->" + to_string(node->next) : "");
}

static void print(ListNode *node) {
    cout << to_string(node) << endl;
}

/// =========================================================================

struct Interval {

    int start, end;

    Interval() : start(0), end(0) {}

    Interval(int start, int anEnd) : start(start), end(anEnd) {}
};

/// =========================================================================

 

Tags: Python C++ cmake leetcode acm Configuration

Posted by DarkendSoul on Thu, 12 May 2022 18:47:09 +0300