Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Creating a python framework in system/library/frameworks

Currently when I'm installing Python from either the Python installer or brew the framework appears in library/frameworks. At the same time the system/library/frameworks/python.framework folder doesn't exist.


The problem is in order to use for example the Python.h file from the framework it has to be in system/library/frameworks.


What can I do to install the framework in the right directory? From where should I download Python or what command is required?

MacBook Air 13″, macOS 12.3

Posted on May 8, 2022 12:22 PM

Reply
Question marked as Best reply

Posted on May 11, 2022 3:52 AM

I suggest you look closer at the POSIX popen(3) approach in C++ to avoid the system() call. Python can write to sys.stdout with its print statement, provided you import sys:



Here is how you access the output of a Python3 program from within C++ (c++11). In this example, the ntp_time.py script is in the same location as the compiled C++ code.


C++ compiles on macOS 12.3.1 with current clang++ 13.1.6:


// clang++ -Oz -o py_out py_out.C -std=c++11
// Reference: https://stackoverflow.com/questions/44610978/popen-writes-output-of-command-executed-to-cout

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <array>

int main()
{
    std::string command("ntp_time.py 2>&1");

    std::array<char, 128> buffer;
    std::string result;

    std::cout << "Opening reading pipe" << std::endl;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe)
    {
        std::cerr << "Couldn't start command." << std::endl;
        return 0;
    }
    while (fgets(buffer.data(), 128, pipe) != NULL) {
        std::cout << "Reading..." << std::endl;
        result += buffer.data();
    }
    auto returnCode = pclose(pipe);

    std::cout << result;
    std::cout << returnCode << std::endl;

    return 0;
}


and the ntp_time.py source tested in macOS 12.3.1 with Python.org's Python 3.10.4:


#!/usr/bin/env python3

from socket import AF_INET, SOCK_DGRAM
import socket
import struct
import time


# def getNTPTime(host="pool.ntp.org"):
def getNTPTime(host="time.nist.gov"):
        port = 123
        buf = 1024
        address = (host, port)
        msg = '\x1b' + 47 * '\0'

        # reference time (in seconds since 1900-01-01 00:00:00)
        TIME1970 = 2208988800  # 1970-01-01 00:00:00

        # connect to server
        client = socket.socket(AF_INET, SOCK_DGRAM)
        client.sendto(bytes(msg.encode('utf-8')), address)
        msg, address = client.recvfrom(buf)
        t = struct.unpack("!12I", msg)[10]
        t -= TIME1970
        s = time.localtime(t)
        # s = time.gmtime(t)
        # s = time.ctime(t).replace("  ", " ")
        return time.strftime('%FT%X %Z', s)


if __name__ == "__main__":
    print("{}".format(getNTPTime()))


Result:


6 replies
Question marked as Best reply

May 11, 2022 3:52 AM in response to StephanF1403

I suggest you look closer at the POSIX popen(3) approach in C++ to avoid the system() call. Python can write to sys.stdout with its print statement, provided you import sys:



Here is how you access the output of a Python3 program from within C++ (c++11). In this example, the ntp_time.py script is in the same location as the compiled C++ code.


C++ compiles on macOS 12.3.1 with current clang++ 13.1.6:


// clang++ -Oz -o py_out py_out.C -std=c++11
// Reference: https://stackoverflow.com/questions/44610978/popen-writes-output-of-command-executed-to-cout

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <array>

int main()
{
    std::string command("ntp_time.py 2>&1");

    std::array<char, 128> buffer;
    std::string result;

    std::cout << "Opening reading pipe" << std::endl;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe)
    {
        std::cerr << "Couldn't start command." << std::endl;
        return 0;
    }
    while (fgets(buffer.data(), 128, pipe) != NULL) {
        std::cout << "Reading..." << std::endl;
        result += buffer.data();
    }
    auto returnCode = pclose(pipe);

    std::cout << result;
    std::cout << returnCode << std::endl;

    return 0;
}


and the ntp_time.py source tested in macOS 12.3.1 with Python.org's Python 3.10.4:


#!/usr/bin/env python3

from socket import AF_INET, SOCK_DGRAM
import socket
import struct
import time


# def getNTPTime(host="pool.ntp.org"):
def getNTPTime(host="time.nist.gov"):
        port = 123
        buf = 1024
        address = (host, port)
        msg = '\x1b' + 47 * '\0'

        # reference time (in seconds since 1900-01-01 00:00:00)
        TIME1970 = 2208988800  # 1970-01-01 00:00:00

        # connect to server
        client = socket.socket(AF_INET, SOCK_DGRAM)
        client.sendto(bytes(msg.encode('utf-8')), address)
        msg, address = client.recvfrom(buf)
        t = struct.unpack("!12I", msg)[10]
        t -= TIME1970
        s = time.localtime(t)
        # s = time.gmtime(t)
        # s = time.ctime(t).replace("  ", " ")
        return time.strftime('%FT%X %Z', s)


if __name__ == "__main__":
    print("{}".format(getNTPTime()))


Result:


May 11, 2022 12:41 AM in response to VikingOSX

Thanks especially for the 2nd idea. I got Pyinstaller working but couldn't find a way to call the script from C++. I've read that system() shouldn't be used due to security concerns.


2 Problems:

  • I don't know how to write my python script to get an output when running it. Where to put the return?
  • How to call the file and store it arguments in C++? Where can I find any docs?

May 8, 2022 1:48 PM in response to StephanF1403

That’s the system path, and not yours to modify.


Apple has removed Python from Monterey 12.3 and later, and Python 3 is still available albeit separately installed.


https://macmule.com/2022/01/29/macos-monterey-12-3-will-remove-python-2-7-usr-bin-python/


Most scripting languages are being removed from macOS.


As for your issue here, Python is quite willing to be installed all over the place, so whatever example you’re working with is either unusually hard-coded to the Apple framework path, or something missing from your login scripts, or maybe there’s another issue such as a bad PYTHONPATH setting. Do some debugging of your particular Python install and its environment.


https://docs.python.org/3/using/mac.html

May 8, 2022 2:47 PM in response to StephanF1403

You would add the path as a header include within the context of the compiler.


I might infer that this could be the first time you’ve made an external reference from C++ code, and which means this whole area can look, well, cryptic.


Here’s what the gcc command-line command looks like:


https://stackoverflow.com/a/10622742


Compiling with Clang will be very similar.


Basically, the -I switch sets the path to access the header files. Similar;y, ld needs a pointer to the Python framework.


If you’re using Xcode and not the command link, you’d add the path to Python into the compilation settings, as per usual. This goes into the build settings for the system header search path, and similarly he framework path for the linker.

May 9, 2022 7:02 AM in response to StephanF1403

What MrHoffman said.


I exclusively use the Python.org universal2 installer for Monterey and not brew. I currently have a reinstalled Python 2.7.18 and 3.10.4 installed in /Library/Frameworks/Python.frameworks using the appropriate Python.org installer on macOS 12.3.1. This places a python and python3 in /usr/local/bin for access to these respective versions. And there is a different Python.h in the following locations where the Python 2.7.18 Python.h is a different checksum:


/Library/Frameworks/Python.framework/Headers               # for Python 3.10.4
/Library/Frameworks/Python.framework/Versions/3.10/Headers # identical to previous
/Library/Frameworks/Python.framework/Versions/2.7/Headers  # Python 2.7.18 only


You can still use your #include <Python/Python.h> in the .cpp source, but you will need to add the include path (-I) to access the Python.h that you need from above during the compilation.


I don't build C++ applications referencing Python, preferring instead to compile (pyinstaller) the respective Python code into either a command-line executable, or .app.



Creating a python framework in system/library/frameworks

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.