CMake Overview                         {#overview_cmake}
==============
[TOC]

CMake allows building wxWidgets on various platforms with your preferred build
system.

Most linux distributions contain CMake as a package on Windows and macOS you can
download an installer at the [CMake Page](https://cmake.org).

Using the CMake GUI                    {#cmake_gui}
===================
1. Start the CMake GUI
2. Specify the wxWidgets root as your source folder
3. Specify a path where the build files should be created. It's recommended to
   use a path outside the wxWidgets root folder.
4. Press the *Configure* button and you will be asked which IDE or build system
   you wish to use
5. *Optionally*: Customize any of the options
6. Press the *Generate* button
7. Open the wxWidgets project with your preferred IDE

Using the CMake Command Line           {#cmake_cli}
============================
1. Create a folder where the build/project files should be created
2. Change into the created folder
3. Run `cmake -G "Unix Makefiles" path_to_wxWidgets_root`
4. After that you can run `cmake --build .` to start the build process or
   directly use your chosen build system.

Run `cmake --help` to see a list of available generators on your platform.
These can than be specified using the -G command line option. On Windows it
is recommended to use Visual Studio and on macOS Xcode is recommended.
Various build options can be specified using -D see
[available options](#cmake_options).

Command Line Examples                  {#cmake_cli_samples}
---------------------
Building with tests using [Ninja](https://ninja-build.org/):
~~~{.sh}
  cmake -G "Ninja" ~/Downloads/wxWidgets_3.1 -DwxBUILD_TESTS=ALL
  cmake --build .
~~~

Building the minimal sample:
~~~{.sh}
    cmake ~/Downloads/wxWidgets_3.1 -DwxBUILD_SAMPLES=SOME
    cmake --build . --target minimal
~~~

Installing static libraries to some path:
~~~{.sh}
    cmake ~/Downloads/wxWidgets_3.1 \
      -DCMAKE_INSTALL_PREFIX=~/wx_install \
      -DwxBUILD_SHARED=OFF
    cmake --build . --target install
~~~


Build options                          {#cmake_options}
=======================
The following list of build options can either be configured in the CMake UI
or specified via the -D command line option when running the cmake command.

Option Name               | Type   | Default | Description
------------------------- | -----  | ------- | ----------------------------
wxBUILD_SHARED            | BOOL   | ON      | Build shared or static libraries
wxBUILD_TESTS             | STRING | OFF     | CONSOLE_ONLY, ALL or OFF
wxBUILD_SAMPLES           | STRING | OFF     | SOME, ALL or OFF
wxBUILD_DEMOS             | BOOL   | OFF     | Build demo applications
wxUSE_GUI                 | BOOL   | ON      | Build the UI libraries
wxBUILD_COMPATIBILITY     | STRING | 3.2     | Enable API compatibility with 3.0, 3.2 or neither ("NONE")
wxBUILD_PRECOMP           | BOOL   | ON      | Use precompiled headers
wxBUILD_MONOLITHIC        | BOOL   | OFF     | Build a single library

Note that on macOS, the option `CMAKE_OSX_ARCHITECTURES` is used to specify which architecture(s) to build.
For example, the following will build a "universal binary 2" (i.e., ARM64 and Intel x86_64) library.
~~~{.sh}
    cmake ~/Downloads/wxWidgets_3.1 \
      -DCMAKE_INSTALL_PREFIX=~/wx_install \
      -DwxBUILD_SHARED=OFF \
      -D"CMAKE_OSX_ARCHITECTURES:STRING=arm64;x86_64"
    cmake --build . --target install
~~~

A complete list of options and advanced options can be found when using the
CMake GUI.

Recommendations                       {#cmake_recommendations}
=======================
While CMake in wxWidgets aims to support most generators available
in CMake, the following generators are recommended:
* Windows: Visual Studio (any supported version)
* macOS: Xcode
* Linux: Ninja or Makefiles

CMake 3.10 or newer is recommended. The minimum tested version is 3.5.

Using CMake with your applications     {#cmake_apps}
==================================
If you are using CMake with your own application, there are various ways to use
wxWidgets:
* Using an installed, binary or compiled version of wxWidgets
using `find_package()`
* wxWidgets as a sub directory.
* CMake's [ExternalProject module](https://cmake.org/cmake/help/latest/module/ExternalProject.html).

Using find_package                     {#cmake_find_package}
------------------
You can use `find_package(wxWidgets)` to use a compiled version of wxWidgets.
Have a look at the [CMake Documentation](https://cmake.org/cmake/help/latest/module/FindwxWidgets.html)
for detailed instructions. wxWidgets also provides an example CMake file in the minimal sample folder.

*WARNING*: Please note that CMake `findwxWidgets` module unfortunately doesn't
detect wxWidgets 3.2.0 in versions of CMake older than 3.24. You may copy the
latest version of `FindwxWidgets.cmake` from [CMake sources][1] to your system
to fix this or, if you build wxWidgets itself using CMake, use `CONFIG` mode of
`find_package()` which works even with older CMake versions.

[1]: https://gitlab.kitware.com/cmake/cmake/-/blob/master/Modules/FindwxWidgets.cmake

Your *CMakeLists.txt* would look like this:
~~~
...

find_package(wxWidgets REQUIRED COMPONENTS net core base)
if(wxWidgets_USE_FILE) # not defined in CONFIG mode
    include(${wxWidgets_USE_FILE})
endif()
add_executable(myapp myapp.cpp)
target_link_libraries(myapp ${wxWidgets_LIBRARIES})
~~~

Using a sub directory                  {#cmake_subdir}
---------------------
You can use wxWidgets as a subdirectory in your application's build tree
(e.g., as a git submodule). This way the wxWidgets libraries will be part
of your application's build process.

Your *CMakeLists.txt* would look like this:
~~~
...
add_subdirectory(libs/wxWidgets)
add_executable(myapp myapp.cpp)
target_link_libraries(myapp wx::net wx::core wx::base)
~~~

Note that you can predefine the build options before using `add_subdirectory()`
by either defining them on command line with e.g. `-DwxBUILD_SHARED=OFF`, or by
adding
~~~~
set(wxBUILD_SHARED OFF)
~~~~
to your *CMakeLists.txt* if you want to always use static wxWidgets libraries.

Using an out-of-tree directory         {#cmake_outerdir}
---------------------
Likewise, wxWidgets can also be outside of your project, but still be part
of your application's build process. To do this, you will need to provide a
build directory argument to `add_subdirectory()`.
This will tell CMake where to place wxWidget's build files.

For example, if wxWidgets is one folder up from your project:
~~~
...
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../wxWidgets"
                 "${CMAKE_CURRENT_SOURCE_DIR}/wxWidgets_lib")
add_executable(myapp myapp.cpp)
target_link_libraries(myapp wx::net wx::core wx::base)
~~~

This can be useful if you have multiple projects using wxWidgets.
This way, you can place wxWidgets side-by-side with your other projects and
have their CMake scripts all point to the same wxWidgets folder.

Cached CMake variables
----------------------

If building wxWidgets statically into your program, these values will
be available:

Name               | Description
------------------ | -----------  |
wxVERSION          | wxWidgets's version number
wxCOPYRIGHT        | The copyright string

Using XRC
---------

To embed XRC resources into your application, you need to define a custom
command to generate a source file using `wxrc`. When using an installed version
of wxWidgets you can just use `wxrc` directly, but when using wxWidgets from a
subdirectory you need to ensure that it is built first and use the correct path
to it, e.g.:

~~~~{.cmake}
# One or more XRC files containing your resources.
set(xrc_files ${CMAKE_CURRENT_SOURCE_DIR}/resource.xrc)

# Generate this file somewhere under the build directory.
set(resource_cpp ${CMAKE_CURRENT_BINARY_DIR}/resource.cpp)

# Not needed with the installed version, just use "wxrc".
set(wxrc $<TARGET_FILE:wxrc>)

add_custom_command(
    OUTPUT ${resource_cpp}
    COMMAND ${wxrc} -c -o ${resource_cpp} ${xrc_files}
    DEPENDS ${xrc_files}
    DEPENDS wxrc                        # Not needed with the installed version.
    COMMENT "Compiling XRC resources"
)

target_sources(myapp PRIVATE ${resource_cpp})
~~~~
