diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 44afcbf..b731293 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,6 +51,7 @@ jobs: shell: bash run: | brew install ninja + pip3 install setuptools ninja --version cmake --version clang --version @@ -58,7 +59,7 @@ jobs: if: startsWith(matrix.os, 'ubuntu') run: | sudo apt-get update - sudo apt-get install ninja-build + sudo apt-get install ninja-build clang libcurl4-openssl-dev ninja --version cmake --version gcc --version @@ -83,11 +84,12 @@ jobs: ${{ runner.os }}- save-always: true - - name: Enable Developer Command Prompt + - name: Configure msvc for amd64 if: startsWith(matrix.os, 'windows') - uses: ilammy/msvc-dev-cmd@v1.12.1 + uses: ilammy/msvc-dev-cmd@v1 with: arch: amd64 + - name: Configure windows if: startsWith(matrix.os, 'windows') shell: bash @@ -99,7 +101,7 @@ jobs: -DCMAKE_CXX_COMPILER=cl \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ -G "${{ matrix.generators }}" \ - -DCMAKE_INSTALL_PREFIX:PATH=instdir + || (cat ./build/vcpkg_installed/vcpkg/issue_body.md && exit 1) - name: Configure macos or ubuntu if: startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'ubuntu') shell: bash @@ -109,7 +111,7 @@ jobs: -B ./build \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ -G "${{ matrix.generators }}" \ - -DCMAKE_INSTALL_PREFIX:PATH=instdir + || (cat ./build/vcpkg_installed/vcpkg/issue_body.md && exit 1) - name: Build shell: bash run: | diff --git a/AtomicQueue/CMakeLists.txt b/AtomicQueue/CMakeLists.txt deleted file mode 100644 index aeac68f..0000000 --- a/AtomicQueue/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_executable(atomicqueue_unittest atomicqueue.hpp atomicqueue_unittest.cc) -target_link_libraries( - atomicqueue_unittest PRIVATE GTest::gtest GTest::gtest_main GTest::gmock - GTest::gmock_main) -add_test(NAME atomicqueue_unittest COMMAND atomicqueue_unittest) diff --git a/AtomicQueue/atomicqueue.hpp b/AtomicQueue/atomicqueue.hpp deleted file mode 100644 index 509528f..0000000 --- a/AtomicQueue/atomicqueue.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -template -class AtomicQueue -{ -public: - AtomicQueue() - : head_(new Node) - , tail_(head_.load(std::memory_order_relaxed)) - {} - ~AtomicQueue() - { - while (Node *const old_head = head_.load()) { - head_.store(old_head->next); - delete old_head; - } - } - - void push(const T &data) - { - Node *const new_node = new Node(data); // 创建新节点 - Node *const old_tail = tail_.exchange(new_node); // 交换尾节点 - old_tail->next = new_node; // 原尾节点指向新尾节点 - } - - void pop() - { - Node *const old_head = head_.load(); // 获取头节点 - head_.store(old_head->next); // 交换头节点 - delete old_head; // 删除原头节点 - } - - T &front() { return head_.load()->next->data; } - - T &back() { return tail_.load()->data; } - - bool empty() { return head_.load() == tail_.load(); } - - size_t size() - { - size_t size = 0; - Node *node = head_.load(); - while (node != tail_.load()) { - ++size; - node = node->next; - } - return size; - } - -private: - struct Node - { - Node() - : next(nullptr) - {} - Node(const T &data) - : data(data) - , next(nullptr) - {} - T data; - Node *next; - }; - - std::atomic head_; - std::atomic tail_; -}; \ No newline at end of file diff --git a/AtomicQueue/atomicqueue_unittest.cc b/AtomicQueue/atomicqueue_unittest.cc deleted file mode 100644 index f470d55..0000000 --- a/AtomicQueue/atomicqueue_unittest.cc +++ /dev/null @@ -1,101 +0,0 @@ -#include "atomicqueue.hpp" - -#include - -TEST(AtomicQueue, PushPop) -{ - AtomicQueue queue; - queue.push(1); - queue.push(2); - queue.push(3); - EXPECT_EQ(1, queue.front()); - EXPECT_EQ(3, queue.back()); - EXPECT_EQ(3, queue.size()); - queue.pop(); - EXPECT_EQ(2, queue.front()); - EXPECT_EQ(3, queue.back()); - EXPECT_EQ(2, queue.size()); - queue.pop(); - EXPECT_EQ(3, queue.front()); - EXPECT_EQ(3, queue.back()); - EXPECT_EQ(1, queue.size()); - queue.pop(); - EXPECT_TRUE(queue.empty()); - EXPECT_EQ(0, queue.size()); -} - -TEST(AtomicQueue, PushPopMany) -{ - AtomicQueue queue; - for (int i = 0; i < 1000; ++i) { - queue.push(i); - } - EXPECT_EQ(0, queue.front()); - EXPECT_EQ(999, queue.back()); - EXPECT_EQ(1000, queue.size()); - for (int i = 0; i < 1000; ++i) { - queue.pop(); - } - EXPECT_TRUE(queue.empty()); - EXPECT_EQ(0, queue.size()); -} - -TEST(AtomicQueue, PushPopManyThreads) -{ - AtomicQueue queue; - std::vector threads; - for (int i = 0; i < 100; ++i) { - threads.emplace_back([&queue, i] { queue.push(i); }); - } - for (auto &thread : threads) { - thread.join(); - } - EXPECT_EQ(100, queue.size()); - for (int i = 0; i < 100; ++i) { - queue.pop(); - } - EXPECT_TRUE(queue.empty()); - EXPECT_EQ(0, queue.size()); -} - -TEST(AtomicQueue, PushPopManyThreads2) -{ - AtomicQueue queue; - std::vector threads; - for (int i = 0; i < 100; ++i) { - threads.emplace_back([&queue, i] { - queue.push(i); - queue.pop(); - }); - } - for (auto &thread : threads) { - thread.join(); - } - EXPECT_TRUE(queue.empty()); - EXPECT_EQ(0, queue.size()); -} - -TEST(AtomicQueue, PushPopManyThreads3) -{ - AtomicQueue queue; - std::vector threads; - for (int i = 0; i < 100; ++i) { - threads.emplace_back([&queue, i] { - queue.push(i); - queue.push(i); - queue.pop(); - queue.pop(); - }); - } - for (auto &thread : threads) { - thread.join(); - } - EXPECT_TRUE(queue.empty()); - EXPECT_EQ(0, queue.size()); -} - -auto main(int argc, char **argv) -> int -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/Breakpad/breakpad.hpp b/Breakpad/breakpad.hpp index e8b9f7c..be45dc0 100644 --- a/Breakpad/breakpad.hpp +++ b/Breakpad/breakpad.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -7,10 +9,10 @@ namespace google_breakpad { class ExceptionHandler; } -class Breakpad +class Breakpad : noncopyable { public: - Breakpad(const std::string &dump_path); + explicit Breakpad(const std::string &dump_path); ~Breakpad(); private: diff --git a/Breakpad/main.cc b/Breakpad/main.cc index 1f672c7..b88ab45 100644 --- a/Breakpad/main.cc +++ b/Breakpad/main.cc @@ -1,10 +1,16 @@ #include "breakpad.hpp" -auto main(int argc, char *argv[]) -> int +void crash() { - Breakpad breakpad("./"); int *p = nullptr; *p = 1; +} + +auto main(int argc, char *argv[]) -> int +{ + Breakpad breakpad("./"); + + crash(); return 0; } diff --git a/CMakeLists.txt b/CMakeLists.txt index 23da6d3..36280fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,74 +1,16 @@ -# 设定版本号 -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.25.1) -if(CMAKE_HOST_WIN32) - set(CMAKE_TOOLCHAIN_FILE - "C:/vcpkg/scripts/buildsystems/vcpkg.cmake" - CACHE STRING "Vcpkg toolchain file") -elseif(CMAKE_HOST_APPLE) - set(CMAKE_TOOLCHAIN_FILE - "/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake" - CACHE STRING "Vcpkg toolchain file") -elseif(CMAKE_HOST_UNIX) - set(CMAKE_TOOLCHAIN_FILE - "/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake" - CACHE STRING "Vcpkg toolchain file") -endif() +include(cmake/vcpkg.cmake) # 设定工程名 project( Cpp-Examples - VERSION 0.1 + VERSION 0.0.1 + DESCRIPTION "This is Cpp-Examples" + HOMEPAGE_URL "https://github.com/RealChuan/Cpp-Examples" LANGUAGES C CXX) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(CMAKE_CURRENT_SOURCE_DIR ON) - -# set(CMAKE_CXX_FLAGS_DEBUG "-O0") set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_DEBUG_POSTFIX d) - -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message("Setting build type to 'RelWithDebInfo' as none was specified.") - set(CMAKE_BUILD_TYPE - RelWithDebInfo - CACHE STRING "Choose the type of build." FORCE) - # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" - "MinSizeRel" "RelWithDebInfo") -endif() - -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(CURRENT_PLATFORM "-64") -else() - set(CURRENT_PLATFORM "-32") -endif() - -message(STATUS "Current Platform is ${CURRENT_PLATFORM}") - -# 设定可执行二进制文件的目录 -set(EXECUTABLE_OUTPUT_PATH - ${PROJECT_SOURCE_DIR}/bin${CURRENT_PLATFORM}/${CMAKE_BUILD_TYPE}) # 源文件目录 -# 设定存放编译出来的库文件的目录 -set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin${CURRENT_PLATFORM}/libs) -# 并且把该目录设为连接目录 -link_directories(${LIBRARY_OUTPUT_PATH}) - -include_directories(${PROJECT_SOURCE_DIR}) - -message("CMAKE_MAJOR_VERSION: ${CMAKE_MAJOR_VERSION}") -message("CMAKE_MINOR_VERSION: ${CMAKE_MINOR_VERSION}") -message("CMAKE_PATCH_VERSION: ${CMAKE_PATCH_VERSION}") -message("CMAKE_TWEAK_VERSION: ${CMAKE_TWEAK_VERSION}") -message("CMAKE_VERSION: ${CMAKE_VERSION}") -message("CMAKE_GENERATOR: ${CMAKE_GENERATOR}") -message("CMAKE_C_COMPILER_ID: ${CMAKE_C_COMPILER_ID}") -message("CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}") +include(cmake/common.cmake) find_package(unofficial-breakpad CONFIG REQUIRED) if(unofficial-breakpad_FOUND) @@ -94,15 +36,23 @@ find_package(CURL CONFIG REQUIRED) if(CURL_FOUND) message(STATUS "found CURL") endif() +find_package(crashpad) +# vcpkg install crashpad, it is not good for linux +if(crashpad_FOUND) + message(STATUS "found crashpad") +endif() +include(CTest) enable_testing() add_subdirectory(Algorithm) -add_subdirectory(AtomicQueue) add_subdirectory(BinaryTree) add_subdirectory(Breakpad) add_subdirectory(ByteOrder) add_subdirectory(CountDownLatch) +if(crashpad_FOUND) + add_subdirectory(Crashpad) +endif() add_subdirectory(Curl) add_subdirectory(DesignPattern) add_subdirectory(Glog) @@ -113,12 +63,10 @@ add_subdirectory(Mutex) add_subdirectory(OpenSSL) add_subdirectory(Thread) -if(CMAKE_HOST_WIN32) - -elseif(CMAKE_HOST_APPLE) - -elseif(CMAKE_HOST_UNIX) +if(CMAKE_HOST_LINUX) add_subdirectory(Client) add_subdirectory(Icmp) add_subdirectory(Server) endif() + +include(cmake/build_info.cmake) diff --git a/CountDownLatch/countdownlatch.hpp b/CountDownLatch/countdownlatch.hpp index 1584751..c6b17b3 100644 --- a/CountDownLatch/countdownlatch.hpp +++ b/CountDownLatch/countdownlatch.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/Crashpad/CMakeLists.txt b/Crashpad/CMakeLists.txt new file mode 100644 index 0000000..371539b --- /dev/null +++ b/Crashpad/CMakeLists.txt @@ -0,0 +1,13 @@ +add_executable(CrashpadTest crashpad.cc crashpad.hpp main.cc) +target_link_libraries(CrashpadTest PRIVATE crashpad::crashpad) + +string(REPLACE "share" "tools" crash_handler_path ${crashpad_DIR}) +message(STATUS "crashpad tools directory: ${crash_handler_path}") + +add_custom_command( + TARGET CrashpadTest + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory + "$/crashpad/" + COMMAND ${CMAKE_COMMAND} -E copy_directory ${crash_handler_path}/ + "$/crashpad") diff --git a/Crashpad/crashpad.cc b/Crashpad/crashpad.cc new file mode 100644 index 0000000..5882f25 --- /dev/null +++ b/Crashpad/crashpad.cc @@ -0,0 +1,59 @@ +#include "crashpad.hpp" + +#include +#include +#include + +#ifdef _WIN32 +auto convertStringToWideString(const std::string &str) -> std::wstring +{ + if (str.empty()) { + return {}; + } + + // 首先,获取转换后的字符串长度(不包括空终止符) + int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0); + + // 如果转换失败,返回空字符串 + if (len == 0) { + return {}; + } + + // 分配足够的空间来存储转换后的字符串 + std::wstring wstr(len, 0); + + // 执行转换 + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &wstr[0], len); + + // 去除末尾的空字符 + wstr.resize(len - 1); + return wstr; +} +#endif + +Crashpad::Crashpad(const std::string &dumpPath, + const std::string &libexecPath, + const std::string &reportUrl, + bool crashReportingEnabled) +{ + auto handlerPath = libexecPath + "/crashpad_handler"; +#ifdef _WIN32 + handlerPath += ".exe"; + base::FilePath database(convertStringToWideString(dumpPath)); + base::FilePath handler(convertStringToWideString(handlerPath)); +#else + base::FilePath database(dumpPath); + base::FilePath handler(handlerPath); +#endif + + auto dbPtr = crashpad::CrashReportDatabase::Initialize(database); + if (dbPtr && (dbPtr->GetSettings() != nullptr)) { + dbPtr->GetSettings()->SetUploadsEnabled(crashReportingEnabled); + } + + m_crashpadClientPtr = std::make_unique(); + m_crashpadClientPtr + ->StartHandler(handler, database, database, reportUrl, {}, {"--no-rate-limit"}, true, true); +} + +Crashpad::~Crashpad() = default; diff --git a/Crashpad/crashpad.hpp b/Crashpad/crashpad.hpp new file mode 100644 index 0000000..cd63fe9 --- /dev/null +++ b/Crashpad/crashpad.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include +#include + +namespace crashpad { +class CrashpadClient; +} // namespace crashpad + +class Crashpad : noncopyable +{ +public: + explicit Crashpad(const std::string &dumpPath, + const std::string &libexecPath, + const std::string &reportUrl, + bool crashReportingEnabled); + ~Crashpad(); + +private: + std::unique_ptr m_crashpadClientPtr; +}; diff --git a/Crashpad/main.cc b/Crashpad/main.cc new file mode 100644 index 0000000..548c24b --- /dev/null +++ b/Crashpad/main.cc @@ -0,0 +1,23 @@ +#include "crashpad.hpp" + +#include + +void crash() +{ + int *p = nullptr; + *p = 1; +} + +auto main() -> int +{ + auto dumpPath = std::filesystem::current_path() / "crashpad"; + if (!std::filesystem::exists(dumpPath)) { + std::filesystem::create_directory(dumpPath); + } + + Crashpad crashpad(dumpPath.string(), dumpPath.string(), "http://127.0.0.1:8080", true); + + crash(); + + return 0; +} diff --git a/Curl/httpclient.hpp b/Curl/httpclient.hpp index e2a9bf0..aa52a76 100644 --- a/Curl/httpclient.hpp +++ b/Curl/httpclient.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include diff --git a/Curl/httpclient_async.hpp b/Curl/httpclient_async.hpp index f939b56..e3fff2f 100644 --- a/Curl/httpclient_async.hpp +++ b/Curl/httpclient_async.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -136,7 +136,7 @@ class HttpClientAsync : noncopyable { CURLMsg *message = nullptr; int pending = 0; - while ((message = curl_multi_info_read(m_multi, &pending))) { + while ((message = curl_multi_info_read(m_multi, &pending)) != nullptr) { switch (message->msg) { case CURLMSG_DONE: { CURL *handle = message->easy_handle; diff --git a/Curl/tcpclient.cc b/Curl/tcpclient.cc index 57b749c..3d2be5e 100644 --- a/Curl/tcpclient.cc +++ b/Curl/tcpclient.cc @@ -28,7 +28,7 @@ auto TcpClient::connect() -> bool } m_curl = curl_easy_init(); - if (!m_curl) { + if (m_curl == nullptr) { return false; } diff --git a/Curl/tcpclient.hpp b/Curl/tcpclient.hpp index 7d8bacf..b180056 100644 --- a/Curl/tcpclient.hpp +++ b/Curl/tcpclient.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include diff --git a/DesignPattern/Singleton/singleton.hpp b/DesignPattern/Singleton/singleton.hpp index 6846ced..b3e845e 100644 --- a/DesignPattern/Singleton/singleton.hpp +++ b/DesignPattern/Singleton/singleton.hpp @@ -1,7 +1,7 @@ #ifndef SINGLETON_HPP #define SINGLETON_HPP -#include +#include #include #include diff --git a/Glog/main.cc b/Glog/main.cc index 4313109..2762e79 100644 --- a/Glog/main.cc +++ b/Glog/main.cc @@ -6,18 +6,18 @@ auto main(int argc, char **argv) -> int { (void) argc; - const auto *log_dir = "./glog_demo"; + const auto log_dir = std::filesystem::current_path() / "glog"; // Initialize Google’s logging library. google::InitGoogleLogging(argv[0]); google::InstallFailureSignalHandler(); google::SetLogFilenameExtension(".log"); - google::EnableLogCleaner(7); + google::EnableLogCleaner(std::chrono::hours(24 * 7)); //google::DisableLogCleaner(); FLAGS_alsologtostderr = true; // 是否将日志输出到文件和stderr FLAGS_colorlogtostderr = true; // 是否启用不同颜色显示 FLAGS_max_log_size = 1000; // 最大日志文件大小 - fLS::FLAGS_log_dir = log_dir; + fLS::FLAGS_log_dir = log_dir.string(); std::filesystem::create_directories(log_dir); diff --git a/Icmp/icmp.hpp b/Icmp/icmp.hpp index 58faaa2..87cfb4a 100644 --- a/Icmp/icmp.hpp +++ b/Icmp/icmp.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/MonitorDir/CMakeLists.txt b/MonitorDir/CMakeLists.txt index 737efbb..bb87097 100644 --- a/MonitorDir/CMakeLists.txt +++ b/MonitorDir/CMakeLists.txt @@ -5,7 +5,7 @@ elseif(CMAKE_HOST_APPLE) add_executable(MonitorDir main.cc monitordir_mac.cc monitordir.cc monitordir.hpp) target_link_libraries(MonitorDir "-framework CoreServices") -elseif(CMAKE_HOST_UNIX) +elseif(CMAKE_HOST_LINUX) add_executable(MonitorDir main.cc monitordir_linux.cc monitordir.cc monitordir.hpp) endif() diff --git a/MonitorDir/monitordir.hpp b/MonitorDir/monitordir.hpp index 51a66eb..36fe05b 100644 --- a/MonitorDir/monitordir.hpp +++ b/MonitorDir/monitordir.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include diff --git a/Mutex/mutex.hpp b/Mutex/mutex.hpp index 3e367c8..5bf32d1 100644 --- a/Mutex/mutex.hpp +++ b/Mutex/mutex.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/OpenSSL/openssl_rsa.cc b/OpenSSL/openssl_rsa.cc index dc55489..a5c2463 100644 --- a/OpenSSL/openssl_rsa.cc +++ b/OpenSSL/openssl_rsa.cc @@ -1,6 +1,6 @@ #include "openssl_utils.hpp" -#include +#include #include #include diff --git a/README.md b/README.md index 318b64c..f2a47f4 100644 --- a/README.md +++ b/README.md @@ -10,28 +10,29 @@ 1. [std_search_examples](/Algorithm/Search/std_search_examples.cc)——stl中查找算法的例子; 2. [Sort](/Algorithm/Sort/sort.hpp)——各种排序算法的实现,以及单元测试和基于google benchmark的性能测试; 1. [std_sort_examples](/Algorithm/Sort/std_sort_examples.cc)——stl中排序算法的例子; -2. [AtomicQueue](/AtomicQueue/atomicqueue.hpp)——使用std::atomic实现的线程安全的队列; -3. [BinaryTree](/BinaryTree/binarytree.hpp)——二叉树的相关操作,插入、移除、查找、打印; -4. [Breakpad](/Breakpad/breakpad.hpp)——google breakpad的简单封装; -5. [ByteOrder](/ByteOrder/byteorder.hpp)——判断系统的字节序; -6. [Client](/Client/client.cpp)——一个简单的Linux select socket客户端; -7. [CountDownLatch](/CountDownLatch/countdownlatch.hpp)——使用std::mutex和std::condition_variable实现的简单倒计时门闩(std::latch c++20); +2. [BinaryTree](/BinaryTree/binarytree.hpp)——二叉树的相关操作,插入、移除、查找、打印; +3. [Breakpad](/Breakpad/breakpad.hpp)——google breakpad的简单封装; +4. [ByteOrder](/ByteOrder/byteorder.hpp)——判断系统的字节序; +5. [Client](/Client/client.cpp)——一个简单的Linux select socket客户端; +6. [CountDownLatch](/CountDownLatch/countdownlatch.hpp)——使用std::mutex和std::condition_variable实现的简单倒计时门闩(std::latch c++20); +7. [Crashpad](/Crashpad/crashpad.hpp)——crashpad的简单封装; + 1. vcpkg对google crashpad在macos和linux上的支持并不好; 8. [Curl](/Curl/)——curl的简单使用; - 1. [TcpClient](/Curl/tcpclient.hpp)——使用curl实现的简单tcp客户端; - 2. [HttpClient](/Curl/httpclient.hpp)——使用curl实现的简单http同步客户端; - 3. [HttpClientAsync](/Curl/httpclient_async.hpp)——使用curl实现的简单http异步客户端; -9. [DesignPattern](/DesignPattern)——设计模式的一些例子; - 1. [Factory](/DesignPattern/Factory/factory.hpp)——工厂模式; - 2. [MVC](/DesignPattern/MVC/model.hpp)——mvc模式; - 3. [Observer](/DesignPattern/Observer/observer.hpp)——观察者模式; - 4. [Singleton](/DesignPattern/Singleton/singleton.hpp)——单例模式; -10. [Glog](/Glog/main.cc)——google glog的例子; -11. [Icmp](/Icmp/icmp.hpp)——linux icmp协议的简单封装; -12. [LinkedList](/LinkedList/linkedlist.hpp)——链表的相关操作,插入、移除、反转、打印; -13. [Memcpy](/Memcpy/memcpy.hpp)——`memcpy`函数实现; -14. [MonitorDir](/MonitorDir/monitordir.hpp)——windows(`ReadDirectoryChangesW`),macos(`FSEvents`)和linux(`inotify`)目录监控的简单例子; -15. [Mutex](/Mutex/mutex.hpp)——使用std::atomic_flag实现的简单互斥锁和自旋锁; -16. [OpenSSL](/OpenSSL)——openssl的一些例子; +9. [TcpClient](/Curl/tcpclient.hpp)——使用curl实现的简单tcp客户端; +10. [HttpClient](/Curl/httpclient.hpp)——使用curl实现的简单http同步客户端; +11. [HttpClientAsync](/Curl/httpclient_async.hpp)——使用curl实现的简单http异步客户端; +12. [DesignPattern](/DesignPattern)——设计模式的一些例子; +13. [Factory](/DesignPattern/Factory/factory.hpp)——工厂模式; +14. [MVC](/DesignPattern/MVC/model.hpp)——mvc模式; +15. [Observer](/DesignPattern/Observer/observer.hpp)——观察者模式; +16. [Singleton](/DesignPattern/Singleton/singleton.hpp)——单例模式; +17. [Glog](/Glog/main.cc)——google glog的例子; +18. [Icmp](/Icmp/icmp.hpp)——linux icmp协议的简单封装; +19. [LinkedList](/LinkedList/linkedlist.hpp)——链表的相关操作,插入、移除、反转、打印; +20. [Memcpy](/Memcpy/memcpy.hpp)——`memcpy`函数实现; +21. [MonitorDir](/MonitorDir/monitordir.hpp)——windows(`ReadDirectoryChangesW`),macos(`FSEvents`)和linux(`inotify`)目录监控的简单例子; +22. [Mutex](/Mutex/mutex.hpp)——使用std::atomic_flag实现的简单互斥锁和自旋锁; +23. [OpenSSL](/OpenSSL)——openssl的一些例子; 1. [aes](/OpenSSL/openssl_aes.cc)——aes加解密的例子; 2. [base64](/OpenSSL/openssl_base64.cc)——base64编解码的例子; 3. [hash](/OpenSSL/openssl_hash.cc)——sha256的例子; @@ -41,10 +42,10 @@ 7. [sm4](/OpenSSL/openssl_sm4.cc)——sm4加解密的例子; 8. [x509](/OpenSSL/openssl_x509.cc)——x509证书的例子; 9. [bash](/OpenSSL/openssl_bash.sh)——openssl命令行的例子; -17. [Server](/Server)——linux server的一些例子; +24. [Server](/Server)——linux server的一些例子; 1. [server_epoll](/Server/server_epoll.cc)——epoll的例子; 2. [server_poll](/Server/server_poll.cc)——poll的例子; 3. [server_select](/Server/server_select.cc)——select的例子; -18. [Thread](/Thread/)——基于std::thread实现的线程类,包括线程池; +25. [Thread](/Thread/)——基于std::thread实现的线程类,包括线程池; 1. [Thread](/Thread/thread.hpp)——线程类; 2. [ThreadPool](/Thread/threadpool.hpp)——线程池; diff --git a/Thread/thread.hpp b/Thread/thread.hpp index a53d5d2..2a75916 100644 --- a/Thread/thread.hpp +++ b/Thread/thread.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -16,7 +16,7 @@ class Thread : noncopyable using Task = std::function; Thread() = default; - Thread(Task task) { setTask(task); } + explicit Thread(Task task) { setTask(task); } ~Thread() { stop(); } void setTask(Task task) { m_task = std::move(task); } @@ -46,9 +46,9 @@ class Thread : noncopyable m_condition.wait(lock, [this]() { return m_running.load(); }); } - bool isRunning() const { return m_running; } + auto isRunning() const -> bool { return m_running; } - std::thread::id getThreadId() const { return m_thread.get_id(); } + auto getThreadId() const -> std::thread::id { return m_thread.get_id(); } static void yield() { std::this_thread::yield(); } @@ -62,7 +62,7 @@ class Thread : noncopyable std::this_thread::sleep_until(timePoint); } - static unsigned int hardwareConcurrency() + static auto hardwareConcurrency() -> unsigned int { unsigned int n = std::thread::hardware_concurrency(); // 如果不支持,返回0 assert(n > 0); diff --git a/cmake/build_info.cmake b/cmake/build_info.cmake new file mode 100644 index 0000000..917befe --- /dev/null +++ b/cmake/build_info.cmake @@ -0,0 +1,22 @@ +# 输出 CMake 版本和构建系统类型 +message("CMake Version: ${CMAKE_VERSION}") +message("Generator: ${CMAKE_GENERATOR}") + +# 输出编译器信息 +message("C Compiler ID: ${CMAKE_C_COMPILER_ID}") +message("C++ Compiler ID: ${CMAKE_CXX_COMPILER_ID}") +message("C++ Compiler Version: ${CMAKE_CXX_COMPILER_VERSION}") + +# 输出构建类型和编译选项 +message("Build Type: ${CMAKE_BUILD_TYPE}") +message("C++ Compiler Flags: ${CMAKE_CXX_FLAGS}") + +# 输出链接选项 +message("Executable Linker Flags: ${CMAKE_EXE_LINKER_FLAGS}") + +# 输出构建和源代码目录 +message("Build Directory: ${CMAKE_BINARY_DIR}") +message("Source Directory: ${CMAKE_SOURCE_DIR}") + +# 输出目标架构 +message("Target Processor: ${CMAKE_SYSTEM_PROCESSOR}") diff --git a/cmake/common.cmake b/cmake/common.cmake new file mode 100644 index 0000000..ccfb15a --- /dev/null +++ b/cmake/common.cmake @@ -0,0 +1,37 @@ +if(CMAKE_HOST_APPLE) + set(CMAKE_OSX_DEPLOYMENT_TARGET + "11.0" + CACHE STRING "Minimum OS X version") +endif() + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_DEBUG_POSTFIX d) + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message("Setting build type to 'RelWithDebInfo' as none was specified.") + set(CMAKE_BUILD_TYPE + RelWithDebInfo + CACHE STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" + "MinSizeRel" "RelWithDebInfo") +endif() + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(BITS "64") +else() + set(BITS "32") +endif() + +message(STATUS "Current Platform is ${BITS} bits.") + +set(EXECUTABLE_OUTPUT_PATH + ${PROJECT_SOURCE_DIR}/bin-${BITS}/${CMAKE_BUILD_TYPE}) +set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin-${BITS}/libs) +link_directories(${LIBRARY_OUTPUT_PATH}) + +include_directories(${PROJECT_SOURCE_DIR}) diff --git a/cmake/vcpkg.cmake b/cmake/vcpkg.cmake new file mode 100644 index 0000000..328f00f --- /dev/null +++ b/cmake/vcpkg.cmake @@ -0,0 +1,13 @@ +if(CMAKE_HOST_WIN32) + set(CMAKE_TOOLCHAIN_FILE + "C:/vcpkg/scripts/buildsystems/vcpkg.cmake" + CACHE STRING "Vcpkg toolchain file") +elseif(CMAKE_HOST_APPLE) + set(CMAKE_TOOLCHAIN_FILE + "/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake" + CACHE STRING "Vcpkg toolchain file") +elseif(CMAKE_HOST_LINUX) + set(CMAKE_TOOLCHAIN_FILE + "/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake" + CACHE STRING "Vcpkg toolchain file") +endif() diff --git a/object.hpp b/utils/object.hpp similarity index 100% rename from object.hpp rename to utils/object.hpp diff --git a/scopeguard.hpp b/utils/scopeguard.hpp similarity index 100% rename from scopeguard.hpp rename to utils/scopeguard.hpp diff --git a/vcpkg.json b/vcpkg.json index 4900b9e..0ca7226 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -23,7 +23,11 @@ "http2", "tool" ] + }, + { + "name": "crashpad", + "platform": "windows | osx" } ], - "builtin-baseline": "3c76dc55f8bd2b7f4824bcd860055094bfbbb9ea" + "builtin-baseline": "ad3bae57455a3c3ce528fcd47d8e8027d0498add" } \ No newline at end of file