Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Extensions #33

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
16fef18
Install libraries to lib instead of libs. Remove mo2_configure_uibase().
Holt59 Jul 8, 2024
44457dc
Import stuff from registry and update README.
Holt59 Jul 10, 2024
8b2c068
Remove find_package(Qt6) in root to avoid needing Qt6 in Python plugin.
Holt59 Jul 10, 2024
6eaa1e0
Add extra options to mo2_python_pip_install.
Holt59 Jul 11, 2024
46170ad
Bring config file from the VCPKG registry.
Holt59 Jul 11, 2024
15edc01
Install PyQt6 automatically when needed.
Holt59 Jul 11, 2024
beb3234
Fix UI and translation file generation for Python.
Holt59 Jul 11, 2024
b9ce33e
Set imported config map.
Holt59 Jul 11, 2024
d5ee29c
Add specific files to store version-related stuff.
Holt59 Jul 13, 2024
18c4679
More flexibility to define sources of a target.
Holt59 Jul 13, 2024
45b3d8a
More flexibility Python pip install and ability to customize default …
Holt59 Jul 13, 2024
87caedb
Remove message.
Holt59 Jul 13, 2024
b2c7511
Move PyQt6 target in autogen folder.
Holt59 Jul 13, 2024
717968f
Prevent Python from using virtualenv and fix typo in mo2_python_pip_i…
Holt59 Jul 13, 2024
5705555
Allow specifying deploy directory in mo2_deploy_qt.
Holt59 Jul 14, 2024
c8ecc87
Allow specifying installation directory when adding translations.
Holt59 Jul 14, 2024
d5bf19e
Add MO2_INSTALL_IS_BIN option.
Holt59 Jul 14, 2024
19d7ca6
Bump Qt version to 6.7.1 and sip to 6.8.6.
mikael-capelle Aug 5, 2024
0185ac7
Add comments and update README.
Holt59 Aug 5, 2024
434f71f
Set working directory for tests and allow not linking to mock and mai…
Holt59 Aug 9, 2024
d3fe015
Install plugins under extensions.
Holt59 Jul 14, 2023
dfc8964
Add mo2_configure_extension().
Holt59 Jul 22, 2023
2cdf7fd
Extract and install icon from metadata.
Holt59 Jun 29, 2024
b104ea1
Do not install translations.
Holt59 Aug 10, 2024
fe13b5a
Fix installation of Python plugins.
Holt59 Aug 11, 2024
c4b01b3
Fix check for icons.
Holt59 Oct 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 98 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,94 +1,109 @@
# MO2 CMake Common

This repository contains CMake macro and functions that are used in most MO2
repository to build uibase, modorganizer itself and plugins (C++/Python).
This repository contains useful CMake macro and functions that are used to ease creating
CMake configuration for most of MO2 repositories (e.g.,
[uibase](https://github.com/ModOrganizer2/modorganizer-uibase),
[plugin_python](https://github.com/ModOrganizer2/modorganizer-plugin_python) or
[ModOrganizer2](https://github.com/ModOrganizer2/modorganizer) itself).

## Getting Started

To get started, simply include the `mo2.cmake` file in your project:

```cmake
# this can safely be included multiple time
include(path_to_cmake_common/mo2.cmake)
### 1. With VCPKG

Add [MO2 VCPKG registry](https://github.com/ModOrganizer2/vcpkg-registry) to your
`vcpkg-configuration.json`:

```json
{
"default-registry": {
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "f61a294e765b257926ae9e9d85f96468a0af74e7"
},
"registries": [
{
"kind": "git",
"repository": "https://github.com/ModOrganizer2/vcpkg-registry",
"baseline": "27d8adbfe9e4ce88a875be3a45fadab69869eb60",
"packages": ["mo2-cmake"]
}
]
}
```

This will set some (not too intrusive) variables and define many useful functions,
all prefixed with `mo2_`.

The basic MO2 plugin/executable CMake will then look like this:
Add `mo2-cmake` to your VCPKG dependencies (`vcpkg.json`) and then import the utilities
with `find_package` in your CMake configuration:

```cmake
# this is for a C++ plugin
add_library(my_plugin SHARED)

# configure the plugin - this will also set the sources of the plugin
# based on the file in the current directory (and subdirectory)
mo2_configure_plugin(my_plugin)

# install the target to MO2 installation path, typically in the
# plugins/ folder
mo2_install_target(my_plugin)
find_package(mo2-cmake CONFIG REQUIRED)
```

## Configuring

The main entry-points are the the configure functions:

- C++
- `mo2_configure_target` - this is the "base" configuration,
which should not be used most of the time (this one is called by
other functions),
- `mo2_configure_uibase` - specific for uibase, should not be used
elsewhere,
- `mo2_configure_plugin` - configuration for a C++ plugin,
- `mo2_configure_library` - configuration for static or shared libraries,
- `mo2_configure_executable` - configuration for executables, including the main
MO2 executable,
- `mo2_configure_tests` - configuration for tests.
- Python
- `mo2_configure_python`.

The function are documented so you can look at the documentation to see what arguments
are available.

### Dependencies

You can add dependencies to the target by using the standard `target_link_libraries`,
but this might be difficult when looking for MO2 dependencies, such as other libraries
or Qt.

The `mo2_configure_XXX` accept `PRIVATE_DEPENDS` and `PUBLIC_DEPENDS` parameters that
can be used to add dependencies to the target in an easier way.
These parameters accept 3 types of dependencies:

- Qt dependencies, that should be specified as `Qt::COMPONENTS`, e.g., `Qt::Core` or
`Qt::Widgets`. Note that the `Qt::` is version-independent, MO2 will add the proper
version for you.
- Boost dependencies - For header only libraries, you can simply pass `boost`, for
non-header only libraries, you can pass `boost::COMPONENT`, e.g., `boost::threads`.
- MO2 dependencies - Those are either components available via the MO2 build system,
such as `zlib` or `libbsarch`, or other MO2 components such as `game_gamebryo`.

## Installing

For C++ plugin, you need to call `mo2_install_target` to install the plugins or
executable in MO2 installation directory.
Where the target should be installed is defined in the `mo2_configure_XXX` function
(which should be called before `mo2_install_target`).

Installing Python plugins does not require extra call apart from `mo2_configure_python`.

## Examples

All MO2 repositories use these functions, so you can look at any repository to get
details on how to use them.
Here are entry points for the various type of plugins:

- [`game_skyrimse`](https://github.com/ModOrganizer2/modorganizer-game_skyrimSE/)
for a plugin that depends on a static library built by MO2.
- [`game_gamebryo`](https://github.com/ModOrganizer2/modorganizer-game_gamebryo/)
for a static library example.
- [`installer_wizard`](https://github.com/ModOrganizer2/modorganizer-installer_wizard)
for a Python plugin (module).
- [`fnistool`](https://github.com/ModOrganizer2/modorganizer-fnistool/) for a Python
plugin (simple file).
### 2. Manually

Clone this repository somewhere and then `include(mo2.cmake)` in your CMake
configuration files.

## Usage

Be aware that using these utilities will automatically set some (not too intrusive)
global variable on your project.

In order to properly use this package, you should set `CMAKE_INSTALL_PREFIX` to a valid
location.
There are two possible way of using this package controlled by the `MO2_INSTALL_IS_BIN`
option:

- if `MO2_INSTALL_IS_BIN` is `OFF` (default), this assumes a layout with a `bin`,
`lib`, `include` and `pdb` folder under `CMAKE_INSTALL_PREFIX`,
- if `MO2_INSTALL_IS_BIN` is `ON` (default when building standalone), this assumes
that `CMAKE_INSTALL_PREFIX` point directly to the equivalent `bin` folder.

Importing the utilities will make the following variables available:

- `MO2_QT_VERSION` - The Qt version used by MO2, as `major.minor.patch`.
- `MO2_QT_MAJOR_VERSION`, `MO2_QT_MINOR_VERSION` and `MO2_QT_PATCH_VERSION` -
Respectively the major, minor and patch version of Qt used by MO2.
- `MO2_PYTHON_VERSION` - The Python version used by MO2 as `major.minor` (patch version
should not be relevant).

All functions are prefixed by `mo2_` and should not conflict with other existing
functions.

### Generic Utilities

- `mo2_set_if_not_defined` - Set a variable to a given value if the variable is not
defined.
- `mo2_add_subdirectories` -
- `mo2_find_python_executable` - Find Python executable.
- `mo2_find_git_hash` - Find the hash of the current git HEAD.
- `mo2_find_qt_executable` - Find a given Qt executable.
- `mo2_set_project_to_run_from_install` - Configure the debug executable for a VS project.
- `mo2_add_filter` - Add a source group filter.
- `mo2_deploy_qt_for_tests` - Deploy Qt DLLs, etc., for tests.
- `mo2_deploy_qt` - Deploy Qt DLLs for ModOrganizer2.
- `mo2_add_lupdate` - Create a target to run Qt `lupdate`.
- `mo2_add_lrelease` - Create a target to Qt `lrelease`.
- `mo2_add_translations` - Add targets to generate translations for the given target.

### C++ Utilities

TODO:

- `mo2_configure_warnings` - Utility function configure warnings for a target.
- `mo2_configure_sources` - Glob and configure sources, including Qt-related files
(.ui, etc.) for a target.
- `mo2_configure_msvc` - Set some MSVC-specific flag for a target.
- (Deprecated) `mo2_configure_target` - Combine the above function + Extra stuff.
- (Deprecated) `mo2_configure_plugin`
- `mo2_configure_tests` - TO BE CHANGED
- `mo2_install_plugin` - Install a plugin.

### Python Utilities

- `mo2_python_uifiles` - Add a target to generate `.py` files from `.ui` files.
- `mo2_python_pip_install` - Install Python packages.
- `mo2_python_requirements` - Install plugin requirements from a `plugin-requirements.txt`
file, ready to ship.
- `mo2_configure_python_module` - Configure a Python module plugin.
- (Deprecated) `mo2_configure_python_simple` - Configure a Python single file plugin.
- `mo2_configure_python` - Wrapper for the two above functions.
3 changes: 3 additions & 0 deletions mo2-cmake-config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.22)

include(${CMAKE_CURRENT_LIST_DIR}/mo2.cmake)
63 changes: 28 additions & 35 deletions mo2.cmake
Original file line number Diff line number Diff line change
@@ -1,54 +1,47 @@
cmake_minimum_required(VERSION 3.22)

if (DEFINED MO2_INCLUDED)
if (DEFINED MO2_DEFINED)
return()
endif()

option(MO2_INSTALL_IS_BIN
"if set, CMAKE_INSTALL_PREFIX is assumed to point to bin rather than one level below")

if (MO2_INSTALL_IS_BIN)
set(MO2_INSTALL_BIN ".")
else()
set(MO2_INSTALL_BIN "bin")
endif()

include(${CMAKE_CURRENT_LIST_DIR}/mo2_versions.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/mo2_utils.cmake)

# setup path for find_package(), etc.
mo2_required_variable(NAME BOOST_ROOT TYPE PATH)
mo2_required_variable(NAME QT_ROOT TYPE PATH)
mo2_required_variable(NAME PYTHON_ROOT TYPE PATH)
mo2_required_variable(NAME CMAKE_INSTALL_PREFIX TYPE PATH)

get_filename_component(MO2_BUILD_PATH "${CMAKE_CURRENT_LIST_DIR}/../.." REALPATH)
get_filename_component(MO2_SUPER_PATH "${MO2_BUILD_PATH}/modorganizer_super" REALPATH)
get_filename_component(MO2_UIBASE_PATH "${MO2_SUPER_PATH}/uibase" REALPATH)
get_filename_component(MO2_INSTALL_PATH "${MO2_SUPER_PATH}/../../install" REALPATH)
get_filename_component(MO2_INSTALL_LIBS_PATH "${MO2_INSTALL_PATH}/libs" REALPATH)

list(APPEND CMAKE_PREFIX_PATH
${QT_ROOT}/lib/cmake
${BOOST_ROOT}/build
${MO2_BUILD_PATH}/googletest/build/lib/cmake/GTest)

# find Qt major version and set QT_DEFAULT_MAJOR_VERSION to avoid issues
# when including LinguistTools without a QtCore
mo2_find_qt_version(QT_VERSION)
string(REPLACE "." ";" QT_VERSION_LIST ${QT_VERSION})
list(GET QT_VERSION_LIST 0 QT_MAJOR_VERSION)

# we add the Qt DLL to the paths for some tools
set(ENV{PATH} "${QT_ROOT}/bin;$ENV{PATH}")

# custom property, used to keep track of the type of target
define_property(
TARGET PROPERTY MO2_TARGET_TYPE INHERITED
BRIEF_DOCS "Target type for MO2 C++ target."
FULL_DOCS "Automatically set when using mo2_configure_XXX functions.")

set(Boost_USE_STATIC_RUNTIME OFF)
set(Boost_USE_STATIC_LIBS ON)
# this makes VS install everything when building solution
set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)

# this find Python globally rather than virtual environments, even when one is active
set(Python_FIND_VIRTUALENV STANDARD)

# this set the imported location of targets for missing configurations - this silents
# many CMP0111 warnings from CMake
set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL MinSizeRel RelWithDebInfo Release None)
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO RelWithDebInfo Release MinSizeRel None)
set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE Release RelWithDebInfo MinSizeRel None)

# allow setting folder property on targets for better organization in VS
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# put code generated by Qt in a autogen group in VS
set_property(GLOBAL PROPERTY AUTOGEN_SOURCE_GROUP autogen)
set_property(GLOBAL PROPERTY AUTOMOC_SOURCE_GROUP autogen)
set_property(GLOBAL PROPERTY AUTORCC_SOURCE_GROUP autogen)

# put targets generated by Qt into a autogen folder (this is not the same as the above)
set(QT_TARGETS_FOLDER autogen)

include(${CMAKE_CURRENT_LIST_DIR}/mo2_cpp.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/mo2_python.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/mo2_extension.cmake)

# mark as included
set(MO2_DEFINED true)
Loading