VSCODE調(diào)試RDKit內(nèi)核的方法步驟(C++)
在研究 RDKit 的一些算法的時(shí)候,總希望能夠“進(jìn)入到代碼中”看這些變量到底是什么,哪些代碼塊會(huì)被執(zhí)行???RDKit 的編譯比較復(fù)雜,如果是 Python 的部分,那么可以直接在 VSCode 中進(jìn)行調(diào)試,記得在 launch 中設(shè)置 “justMyCode: false",詳見(jiàn)該問(wèn)題。但如果想要調(diào)試 C++ 的部分,則就復(fù)雜很多,需要是用調(diào)試模式重新編譯 RDKit 的源碼。對(duì)于沒(méi)有用過(guò)VSCode 編譯 C++ 項(xiàng)目的小伙伴來(lái)說(shuō),這里有很多坑需要踩。
這個(gè)過(guò)程可以分為三個(gè)部分:安裝 RDKit 所需環(huán)境,安裝 VSCode 相應(yīng)插件, 寫(xiě)調(diào)試代碼編譯
安裝 RDKit 所需環(huán)境
源碼安裝 RDKit 一直是一件麻煩事,在過(guò)去我們不得不自己安裝所需依賴,包括 Numpy,Boost,CMake 好在現(xiàn)在有了 Anaconda,讓安裝依賴變得省心很多。不過(guò) Anaconda 也是把雙刃劍,筆者遇到由于不同環(huán)境被 CMake 混亂使用導(dǎo)致一些潛在的問(wèn)題,這個(gè)在最后提到。
我們可以參考 RDKit 官方文檔進(jìn)行環(huán)境安裝 https://www.rdkit.org/docs/Install.html#how-to-build-from-source-with-conda
筆者使用 MacOS 測(cè)試,而且已經(jīng)安裝上了 Anaconda,于是想要?jiǎng)?chuàng)建一個(gè)新環(huán)境
conda create -n rdkit-dev conda activate rdkit-dev conda install numpy matplotlib conda install cmake cairo pillow eigen pkg-config conda install boost-cpp boost py-boost
筆者的 Anazonda 裝在 /Users/zealseeker/opt/anaconda 中,所以該環(huán)境對(duì)應(yīng)的是:
export PYROOT=/Users/zealseeker/opt/anaconda/env/rdkit-dev
另外注意到新建的環(huán)境用的是 python3.9,下面會(huì)用到。
然后下載源碼到一個(gè)目錄,筆者一般將所有用 git 下載的項(xiàng)目都放到 Documents/git 這個(gè)目錄下。
cd /Users/zealseeker/Documents/git git clone https://github.com/rdkit/rdkit.git cd rdkit
到這一步已經(jīng)可以了,但為了確保 RDKit 的安裝一切會(huì)順利,不妨先嘗試編譯一把。下面寫(xiě) 3.9 就是因?yàn)槲覀冄b的是 Python 3.9。與官方介紹不同的是,由于我們只需要調(diào)試?yán)锩娴脑创a,一些可有可無(wú)的功能就不需要激活了。按道理這這樣配置編譯會(huì)順利通過(guò)(如果不并行,可能會(huì)編譯一個(gè)小時(shí)…)
mkdir build cd build cmake -DPYTHON_INCLUDE_DIR=$PYROOT/include/python3.9 \ -DRDK_BUILD_AVALON_SUPPORT=OFF \ -DRDK_BUILD_CAIRO_SUPPORT=OFF \ -DRDK_BUILD_INCHI_SUPPORT=OFF \ .. make -j6 # 或著不并行,就用 make,但會(huì)慢很多
配置 VSCode 使其能 Debug
首先先要讓 VSCode 支持 C++ 和 CMake,需要安裝 C++ extension for VS Code 和 CMake Tools extension for VS Code 這兩個(gè)插件。裝完后需要進(jìn)行一下配置,非常關(guān)鍵:
配置 Intellisense
雖然說(shuō)這個(gè)不配置問(wèn)題應(yīng)該不大,但可能發(fā)現(xiàn)編輯器到處都是 problem 和波浪線,因?yàn)榫庉嬈鞑恢缿?yīng)該去哪里找頭文件,具體可參考這里。
以下是筆者的配置方法:在 .vscode 下創(chuàng)建 c_cpp_properties.json 文件,在里面添加:
{ "configurations": [ { "name": "Mac", "includePath": [ "${workspaceFolder}/Code", "/Users/zealseeker/opt/anaconda3/envs/rdkit-dev/include", "/Users/zealseeker/opt/anaconda3/envs/rdkit-dev/include/python3.9", "/Users/zealseeker/opt/anaconda3/envs/rdkit-dev/lib/python3.9/site-packages/numpy/core/include" ], "defines": [], "macFrameworkPath": [ "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks" ], "compilerPath": "/usr/bin/clang", "cStandard": "c17", "cppStandard": "c++17", "intelliSenseMode": "macos-clang-x64" } ], "version": 4 }
主要配置的就是 includePath,這里需要加入 RDKit 源代碼目錄 (Code),Anaconda 的 include,Anaconda 的 Python 以及 Anaconda 的 Numpy。按理配置完后就能看到所有的錯(cuò)誤和波浪號(hào)都消失了(可以隨便打開(kāi)個(gè) cpp 文件看下是否有錯(cuò)誤),如果還有錯(cuò)誤,則需要具體看是什么。(Windows 貌似會(huì)復(fù)雜點(diǎn),具體參考官方文檔。)
配置 CMake
打開(kāi) CMake Tools extension for VS Code 這個(gè)插件的配置,點(diǎn)擊設(shè)置按鈕 - 擴(kuò)展設(shè)置,就會(huì)進(jìn)入到 VSCode 的設(shè)置界面并已經(jīng)用 @ext:ms-vscode.cmake-tools 進(jìn)行篩選了。然后看到有 User 和 Workspace 兩個(gè)選擇,前者可以認(rèn)為是全局設(shè)置,后者為項(xiàng)目設(shè)置,我們選擇后者。需要修改如下幾個(gè)選項(xiàng):
- Cmake: Cmake Path
由于我們用的是 Anaconda 環(huán)境下的 CMake,尤其如果像筆者這樣通過(guò)新增環(huán)境得到的,可能 CMake 沒(méi)有被加入到 Path 環(huán)境變量。檢查的方法是在 terminal 里輸入 which cmake,如果出現(xiàn) cmake not found,則說(shuō)明未加入到環(huán)境變量,需要手動(dòng)配置,筆者的 CMake 在:/Users/zealseeker/opt/anaconda3/envs/rdkit-dev/bin/cmake,所以將該路徑加入到配置中即可。而如果用的是 base 環(huán)境,則可能不需要配置,因?yàn)?CMake 已被加入到環(huán)境變量。如果發(fā)現(xiàn)該 CMake 并非之前在 Anaconda 裝的那個(gè),則仍然需要配置,否則可能會(huì)出現(xiàn)尋找錯(cuò)誤的庫(kù)的問(wèn)題,詳見(jiàn)最后一節(jié)。
- Cmake: Configure Args
這個(gè)對(duì)應(yīng)執(zhí)行 CMake 時(shí)的參數(shù),即那些 -DXXXX=xxx 的內(nèi)容,筆者為了圖方便,僅配置了 Python
-DPYTHON_INCLUDE_DIR=/Users/zealseeker/opt/anaconda3/envs/rdkit-dev/include/python3.9
也可以根據(jù)需要將諸如 -DRDK_BUILD_CAIRO_SUPPORT=OFF 也加進(jìn)去,尤其是如果后續(xù)發(fā)現(xiàn)編譯時(shí)在 CAIRO 的地方出錯(cuò)了,則可以考慮禁用它。
小貼士,我們可以查看 .vscode 下是否有 settings.json 文件,并且該文件中是否有下面兩個(gè)配置以判斷是否配置成功。
{ "cmake.cmakePath": "/Users/zealseeker/opt/anaconda3/envs/rdkit-dev/bin/cmake", "cmake.configureArgs": [ "-DPYTHON_INCLUDE_DIR=/Users/zealseeker/opt/anaconda3/envs/rdkit-dev/include/python3.9" ] }
- 編譯(可選)
全都配置完全,可以考慮先 Build 一下,看看有沒(méi)有問(wèn)題,按一下底部狀態(tài)欄的 Build 按鈕則會(huì)自動(dòng)開(kāi)始編譯(需要不少時(shí)間)。如果未能編譯完成,則需要檢查其錯(cuò)誤,看是哪里出了問(wèn)題。
新建調(diào)試文件進(jìn)行調(diào)試
筆者在根目錄下創(chuàng)建了個(gè) debug 文件夾,并在里面創(chuàng)建了 test.cpp 和 CMakeLists.txt 兩個(gè)文件。test.cpp 自然是用于調(diào)試的文件,新建 main 函數(shù),傳入苯的 SMILES,將其轉(zhuǎn)化成 RWMol 對(duì)象。非常簡(jiǎn)單的操作,僅僅是用于證明可以進(jìn)入調(diào)試狀態(tài)。
#include <GraphMol/SmilesParse/SmilesParse.h> #include <GraphMol/Depictor/RDDepictor.h> using namespace RDKit; int main( int argc , char **argv ){ std::cout << "Importing benezene"; std::string smi = "c1ccccc1"; RWMol *newM; newM = SmilesToMol(smi, 0, true); return 0 }
CMakeLists 筆者是參考了 RDKit 的例子,個(gè)人感覺(jué)不是最好,畢竟原例子并不需要我們同時(shí)編譯 RDKit 源碼和測(cè)試代碼,而是作為“已安裝 RDKit 該如何調(diào)用其 C++ 接口”的例子,但筆者能力有限,只能很僵硬地照搬。路徑基本寫(xiě)死,比如 library 在 $RDBASE/build/lib 里(因?yàn)橹痪幾g未安裝,所以庫(kù)都會(huì)在 build 文件夾下)
cmake_minimum_required( VERSION 3.5 ) project(RDKitSV) set(RDBASE "/Users/zealseeker/Documents/git/rdkit") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${RDBASE}/Code/cmake/Modules") set(CMAKE_CXX_STANDARD 14) find_package( Boost COMPONENTS iostreams filesystem system) include_directories ( ${RDBASE}/Code) link_directories ( ${RDBASE}/build/lib ) set(RDKit_LIBS RDKitFileParsers RDKitSmilesParse RDKitDepictor RDKitRDGeometryLib RDKitRDGeneral RDKitSubstructMatch RDKitSubgraphs RDKitMolDraw2D RDKitGraphMol RDKitDistGeometry RDKitDistGeomHelpers RDKitMolAlign RDKitOptimizer RDKitForceField RDKitForceFieldHelpers RDKitAlignment RDKitForceField RDKitMolTransforms RDKitEigenSolvers ) find_package (Threads) set(RDKit_THREAD_LIBS Threads::Threads) set( LIBS ${RDKIT_LIBRARIES} Boost::iostreams ${RDKit_THREAD_LIBS} z ) include_directories(${RDKIT_INCLUDE_DIR}) add_executable( TestMol test.cpp ) target_link_libraries( TestMol ${LIBS} ${RDKit_LIBS})
然后在根目錄的 CMakeLists.txt 里的最后面增加一行,將 debug 文件夾加入到編譯內(nèi)容中。
add_subdirectory(debug)
此時(shí)萬(wàn)事俱備,再次點(diǎn)擊狀態(tài)欄的 Build 按鈕即可進(jìn)行最終的編譯,如果之前已經(jīng)在配置好
VSCode-Cmake 后編譯過(guò)一次,則這次會(huì)很快。編譯完后,我們就可以調(diào)試了,調(diào)試前確定調(diào)試目標(biāo)是否正確:在 Build 的右邊分別有 debug(一個(gè)蟲(chóng)子)和 run(運(yùn)行按鈕),再右邊是運(yùn)行目標(biāo)(launch target),要確定其為 TestMol,如果不是,則需要點(diǎn)擊選擇并輸入 TestMol,它應(yīng)該在 $rdkit/build/debug/TestMol。
最后點(diǎn)擊小蟲(chóng)子即可進(jìn)行調(diào)試,并記得加斷點(diǎn),確定可以正常調(diào)試。
Anaconda 環(huán)境問(wèn)題
由于筆者電腦里有多個(gè) Anaconda 環(huán)境導(dǎo)致 CMake 在尋找?guī)斓臅r(shí)候可能會(huì)找錯(cuò)地方,因此一定要檢查 CMake 是否找對(duì)了,盡管理論上找錯(cuò)了問(wèn)題也不大,但至少當(dāng)最后編譯或者運(yùn)行時(shí)報(bào)錯(cuò)時(shí)可以有據(jù)可循。
筆者在 Anaconda 的 base 環(huán)境和 rdkit-dev 環(huán)境中都有 Boost,而除了 rdkit-dev 中有 CMake 外,自己也下載了個(gè) CMake。筆者發(fā)現(xiàn)如果用自己下載的 CMake 編譯,會(huì)導(dǎo)致其尋找的是 base 環(huán)境下的 Boost (因?yàn)?VSCode 編譯時(shí)并不會(huì)激活 rdkit-dev 環(huán)境)。因此一定要使用 rdkit-dev 下的 CMake,即確保 Boost 所在 Anaconda 環(huán)境和 CMake 是同一個(gè)。
另外,筆者在編輯器中還看到下述問(wèn)題,盡管其不影響編譯與調(diào)試,但說(shuō)明 CMake 在尋找?guī)鞎r(shí)仍然選擇了錯(cuò)誤的地方。可惜筆者一直不知如何修復(fù),若有大神還請(qǐng)留言協(xié)助。該問(wèn)題說(shuō)明 CMake 在尋找 libcairo 時(shí)尋找的是 base 環(huán)境,而其他庫(kù)在 rdkit-dev 和 build 中,他們之間可能存在相互依賴關(guān)系。解決方法應(yīng)該是讓 libcairo 去 rdkit-dev 中找,而不是 base 環(huán)境,可并不知道如何設(shè)置這個(gè)尋找路徑優(yōu)先級(jí)。
CMake Warning at Code/cmake/Modules/RDKitUtils.cmake:49 (add_library):Cannot generate a safe runtime search path for target MolDraw2D because there is a cycle in the constraint graph: dir 0 is [/Users/zealseeker/Documents/git/rdkit/build/lib] dir 1 is [/Users/zealseeker/opt/anaconda3/envs/rdkit-dev/lib] dir 2 must precede it due to runtime library [libcairo.dylib] dir 2 is [/Users/zealseeker/opt/anaconda3/lib] dir 0 must precede it due to runtime library [libRDKitChemReactions.1.dylib] dir 1 must precede it due to runtime library [libboost_system.dylib] Some of these libraries may not be found correctly.
參考資料
https://code.visualstudio.com/docs/cpp/cmake-linux
到此這篇關(guān)于VSCODE調(diào)試RDKit內(nèi)核的方法步驟(C++)的文章就介紹到這了,更多相關(guān)VSCODE調(diào)試RDKit內(nèi)核內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言的語(yǔ)法風(fēng)格與代碼書(shū)寫(xiě)規(guī)范指南
這篇文章主要介紹了C語(yǔ)言的語(yǔ)法風(fēng)格與代碼書(shū)寫(xiě)規(guī)范指南,文中主張了一些諸如變量和結(jié)構(gòu)體的命名規(guī)范等細(xì)節(jié)方面的問(wèn)題,需要的朋友可以參考下2016-02-02QT實(shí)現(xiàn)QML側(cè)邊導(dǎo)航欄的最簡(jiǎn)方法
本文主要介紹了QT實(shí)現(xiàn)QML側(cè)邊導(dǎo)航欄的最簡(jiǎn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06Qt實(shí)現(xiàn)生成指定范圍內(nèi)隨機(jī)數(shù)與隨機(jī)字符串
這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)生成指定范圍內(nèi)隨機(jī)數(shù)與隨機(jī)字符串,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以自己動(dòng)手嘗試一下2023-07-07