Q:

cmake - weird side effects when find_package is called from function as opposed to global scope

I have a very simple cmake project here which builds a single Qt application.
Works:
find_package called from global scope in CMakeLists.txt
CMakeLists.txt:
cmake_minimum_required(VERSION 3.2.2)
project(gui CXX)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")

find_package(Qt5Widgets REQUIRED)

qt5_wrap_cpp         (moc_output message.h)
add_executable       (gui main.cpp ${moc_output})
target_link_libraries(gui Qt5::Widgets)

As listed above, the code builds successfully.
$ make

[ 25%] Generating moc_message.cpp
Scanning dependencies of target gui
[ 50%] Building CXX object CMakeFiles/gui.dir/main.cpp.o
[ 75%] Building CXX object CMakeFiles/gui.dir/moc_message.cpp.o
[100%] Linking CXX executable gui
[100%] Built target gui

Does not work:
find_package called from function scope in CMakeLists.txt
However, if I change the call to find_package to be within a function:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.2.2)
project(gui CXX)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")

function(load_qt)
    find_package(Qt5Widgets REQUIRED)
endfunction()

load_qt() # this is the only change - find_package called from function load_qt

qt5_wrap_cpp         (moc_output message.h)
add_executable       (gui main.cpp ${moc_output})
target_link_libraries(gui Qt5::Widgets)

The code no longer compiles.
$ make

 [ 25%] Generating moc_message.cpp
 make[2]: execvp: /.../build/moc_message.cpp_parameters: Permission denied
 make[2]: *** [moc_message.cpp] Error 127
 make[1]: *** [CMakeFiles/gui.dir/all] Error 2
 make: *** [all] Error 2

Questions:

Why does this happen?
Is there any way to conditionally call find_package, eg: only when a user calls my function?

Full source code:
main.cpp:
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QPushButton>
#include "message.h"

class App
{
public:
    App(int& argc, char** argv)
        : app(argc, argv)
    { }

    int exec()
    {
        QMainWindow* window = new QMainWindow;
        QWidget*     widget = new QWidget;
        QVBoxLayout* layout = new QVBoxLayout;
        QPushButton* button = new QPushButton("go");
        Message*     msg    = new Message;

        window->setCentralWidget(widget);
        widget->setLayout(layout);
        layout->addWidget(button);

        QObject::connect(button, &QPushButton::clicked, msg, &Message::onGo);

        window->show();
        return app.exec();
    }

    QApplication app;
};

int main(int argc, char** argv)
{
    return App(argc, argv).exec();
}

message.h:
#include <QMessageBox>
#include <QObject>

class Message : public QObject
{
    Q_OBJECT
public slots:
    void onGo()
    {
        QMessageBox(
            QMessageBox::Icon::Information,
            "Hello",
            "World",
            QMessageBox::StandardButton::NoButton,
            nullptr).exec();
    }
};

CMakeLists.txt:
cmake_minimum_required (VERSION 3.2.2)
project (gui CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")

function(load_qt)
    find_package(Qt5Widgets REQUIRED)
endfunction()

# this doesn't work
# load_qt()

# this does work
find_package(Qt5Widgets REQUIRED)

qt5_wrap_cpp         (moc_output message.h)
add_executable       (gui main.cpp ${moc_output})
target_link_libraries(gui Qt5::Widgets)

A:

The root cause of the problem here is that functions create a new scope 
From the documentation:

A function opens a new scope: see set(var PARENT_SCOPE) for details.

Macros, on the other hand, operate at parent scope.
Therefore, to fix the problem, change load_qt() to a macro:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.2.2)
project(gui CXX)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")

# note here, load_qt is now a macro rather than a function
macro(load_qt)
    find_package(Qt5Widgets REQUIRED)
endmacro()

load_qt()

qt5_wrap_cpp         (moc_output message.h)
add_executable       (gui main.cpp ${moc_output})
target_link_libraries(gui Qt5::Widgets)

