CMakeLists.txtの練習として、wxWidgetsを使うCMakeLists.txtを書いてみる。
気になっているのがライブラリのリンクの設定。CMakeLists.txtでは、ライブラリディレクトリを指定する(-L相当)のではなく、ライブラリをひとつずつフルパスを指定する(-l相当)ような設定にするらしい。それはいいのだが、find_directoryで変数にひとつずつライブラリを指定し、後でまとめてtarget_link_librariesに指定する方法しか探せなかった。
# CMakeのバージョンを設定 今自分が使っているものを指定している # 必須要件なので、数字は小さい方がいい。 cmake_minimum_required(VERSION 3.25) ############################################# ############################################# # ソリューション名を設定 set(MY_SOLUTION_NAME "MySolution") #プロジェクト名を設定 set(MY_PROJECT_NAME "MyProject") # 出力ファイル名を設定 set(MY_OUTPUT_NAME "myout") ############################################# ############################################# # ソリューションを作成 # プロジェクト名と使用する言語を設定 project(${MY_SOLUTION_NAME} CXX) ############################################# ############################################# # main.cpp function.cppからプロジェクト作成 add_executable(${MY_PROJECT_NAME} main.cpp) ############################################# ############################################# # 出力名を"myout.exe"に設定 set_target_properties(${MY_PROJECT_NAME} PROPERTIES OUTPUT_NAME ${MY_OUTPUT_NAME}) ############################################# ############################################# # wxWidgetsを使うオプションを作成。 # デフォルトで ON にしておく。 option(USE_WXWIDGETS "Use wxWidgets library" ON)
# USE_WXWIDGETSが有効化されている時だけ以下の設定がなされる。 if(USE_WXWIDGETS) # includeディレクトリを指定 include_directories(C:/libraries/wxWidgets/include/) include_directories(C:/libraries/wxWidgets/release/lib/vc_x64_dll/mswu) set( WXWIDGETS_LIB_PATH C:/libraries/wxWidgets/release/lib/vc_x64_dll) # 使用するライブラリをLib1,Lib2,...という変数にフルパスで格納 find_library( Lib1 NAMES wxbase32u.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib2 NAMES wxbase32u_net.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib3 NAMES wxbase32u_xml.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib4 NAMES wxmsw32u_adv.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib5 NAMES wxmsw32u_aui.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib6 NAMES wxmsw32u_core.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib7 NAMES wxmsw32u_gl.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib8 NAMES wxmsw32u_html.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib9 NAMES wxmsw32u_media.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib10 NAMES wxmsw32u_propgrid.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib11 NAMES wxmsw32u_qa.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib12 NAMES wxmsw32u_ribbon.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib13 NAMES wxmsw32u_richtext.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib14 NAMES wxmsw32u_stc.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib15 NAMES wxmsw32u_webview.lib PATHS ${WXWIDGETS_LIB_PATH}) find_library( Lib16 NAMES wxmsw32u_xrc.lib PATHS ${WXWIDGETS_LIB_PATH}) set(Libs ${Lib1} ${Lib2} ${Lib3} ${Lib4} ${Lib5} ${Lib6} ${Lib7} ${Lib8} ${Lib9} ${Lib10} ${Lib11} ${Lib12} ${Lib13} ${Lib14} ${Lib15} ${Lib16}) # MyProject に、上で検索して見つかったライブラリをリンク # CMakeLists.txtでは、ライブラリディレクトリ(-Lに該当)を指定するのではなく、各ライブラリファイルをフルパスで指定することが推奨されているらしい。 target_link_libraries(${MY_PROJECT_NAME} PRIVATE ${Libs} ) # プリプロセッサの定義 target_compile_definitions(${MY_PROJECT_NAME} PRIVATE -D__WXMSW__) target_compile_definitions(${MY_PROJECT_NAME} PRIVATE -DWXUSINGDLL) endif()
# エントリポイントをWinMainにするオプションを追加。 option(USE_WINMAIN "Use WinMain" ON)
# USE_WINMAINが有効化されている時だけ以下の設定がなされる。 if(USE_WINMAIN) # エントリポイントをWinMainにするためにサブシステム変更 if (WIN32) set_target_properties(${MY_PROJECT_NAME} PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS") endif() endif()
wxwidgets_cmake\ ├─solution\ │ └─src\ CMakeLists.txt main.cpp
CMake guiで、チェック項目が追加されていることを確認できる。
#ifndef WX_PRECOMP #include <wx/wx.h> #endif #include <wx/gdicmn.h> // wxPointに必要 #include <wx/frame.h> // wxFrameに必要 ///////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// // ウィンドウ作成 class MyFrame : public wxFrame { // ボタン wxButton* m_button; public: void PostCreate() { m_button = new wxButton(this, wxID_ANY, wxT("クリックしてください"));// ボタン作成 m_button->Show(); } MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) { // CallAfter : 現在処理中のイベントが終わったらPostCreateを実行 // コンストラクタはウィンドウ生成イベント扱い CallAfter(&MyFrame::PostCreate); // ウィンドウ生成中にnew wxButtonするとボタンが一画面いっぱいに広がってしまう。 // ウィンドウ生成処理が終わってからボタンを生成しなければいけない } }; ///////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// // wxWidgetsのアプリケーション作成 class MyApp : public wxApp { public: virtual bool OnInit() { MyFrame* frame = new MyFrame("Hello World", wxPoint(50, 50), wxSize(450, 340)); frame->Show(true); return true; } }; ///////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// // WinMainをマクロで定義 wxIMPLEMENT_APP(MyApp);