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

C++ extension incompatibility with linux #212

Closed
DubbleClick opened this issue Sep 30, 2023 · 15 comments · Fixed by #231
Closed

C++ extension incompatibility with linux #212

DubbleClick opened this issue Sep 30, 2023 · 15 comments · Fixed by #231
Labels
kind/dependency Issues related to dependencies os/linux Things only for Linux OS question Further information is requested

Comments

@DubbleClick
Copy link
Contributor

What's the reason for C++ extensions not being compatible with linux, but working on alpine? Surely this is something we can fix? My C knowledge may be rather limited but I'm fairly familiar with C++ build systems.

@crazywhalecc
Copy link
Owner

Currently, we use musl-libc and musl-gcc in glibc-based Linux distributions to compile C programs. For the C++ part, we still use g++ and do not use musl because there is currently no suitable musl wrapper for c++.

@crazywhalecc crazywhalecc added question Further information is requested kind/dependency Issues related to dependencies os/linux Things only for Linux OS labels Sep 30, 2023
@DubbleClick
Copy link
Contributor Author

Is g++ targeting libstdc++ not able to produce statically linked binaries on glibc based systems? I'm trying to understand why it's possible on Alpine, but not on Debian.

@DubbleClick
Copy link
Contributor Author

DubbleClick commented Sep 30, 2023

It's also possible to compile both c and c++ with musl by building cross-compilers from source or using a prebuilt toolchain.

@crazywhalecc
Copy link
Owner

crazywhalecc commented Sep 30, 2023

Is g++ targeting libstdc++ not able to produce statically linked binaries on glibc based systems?

Exactly. And it also cannot be linked statically using glibc with dns things. Using musl-gcc is a compromise. If only the compilation of Alpine and Alpine Docker environments is supported like the old version, then we will have almost no trouble in this regard.

@DubbleClick
Copy link
Contributor Author

DubbleClick commented Sep 30, 2023

I see, I was aware that gcc glibc wasn't too happy with static linking, but didn't think that also translated into the C++ world. Things are simpler on Windows with vc.

I'll see if I can set up a cross compiler chain. We already have to compile musl from source for rpm based systems anyway, wouldn't hurt to have spc doctor produce a cross compiler that we can then use to compile c++ extensions targeting musl.

Or do you think it's simpler to just offer a alpine docker image to let users create php with the extensions they want? The libphp.a/php binary could still be used on all linux distros, I suppose?

@crazywhalecc
Copy link
Owner

BTW, I have an even weirder idea about compiling musl.

  1. Treat musl as a dependent library and write it in library/linux/musl.php.
  2. When downloading and compiling, the system environment can be detected. If the musl tool chain is required, compile it, otherwise skip it.
  3. If self-compiled musl is used, dynamically specify the cc of the current Builder as path/to/musl-gcc.

Doing so will result in a better user experience, but will greatly increase the complexity of the framework.

@crazywhalecc
Copy link
Owner

Or do you think it's simpler to just offer a alpine docker image to let users create php with the extensions they want?

I don't think it's appropriate to change this now. Because the upcoming official version will provide spc binaries for multiple platforms, and this binary theory can run on any supported distribution, or you can call --docker on unsupported distributions to build a Docker Mirror and run.

@crazywhalecc
Copy link
Owner

The libphp.a/php binary could still be used on all linux distros, I suppose?

I feel that if libphp wants to be used truly smoothly, it may be possible to treat spc itself as part of the compilation process rather than as an independent build program. In addition, currently we can rely on buildroot/bin/php-config to handle these parameters, but I also plan to add a command that can output the compilation parameters, such as ./spc export-embed-vars --libs etc. (Maybe this Do it better? I'm not very clear about the usage of libphp).

@DubbleClick
Copy link
Contributor Author

I feel that if libphp wants to be used truly smoothly, it may be possible to treat spc itself as part of the compilation process rather than as an independent build program.

I think that goes a bit too far. It's not too much to ask to spin up a VM and install php to run spc. The process is simple enough for the target audience this project has. I expect we would run into too many issues trying to make it a pre-compiled binary that does everything for the user.

In addition, currently we can rely on buildroot/bin/php-config to handle these parameters, but I also plan to add a command that can output the compilation parameters, such as ./spc export-embed-vars --libs etc. (Maybe this Do it better? I'm not very clear about the usage of libphp).

I'm not sure I understand. What is bin/php-config? Libphp.a can be used to statically link the php runtime into other programs (such as web servers like frankenphp).

@crazywhalecc
Copy link
Owner

I'm not sure I understand. What is bin/php-config? Libphp.a can be used to statically link the php runtime into other programs (such as web servers like frankenphp).

The first mention of it comes from here: #153 (comment)

But, it's also just an idea, it's not in my current plans, and maybe it might be implemented later than Windows support. There is still a lot of work to be done before the official binary release.

@crazywhalecc
Copy link
Owner

crazywhalecc commented Sep 30, 2023

I think that goes a bit too far. It's not too much to ask to spin up a VM and install php to run spc.

For automated build, I initially planned to build a GitHub Actions repository for self-configurable compilation in other systems and projects: https://github.com/crazywhalecc/setup-static-php

For local builds, everything will be based on spc binary, which will greatly simplify the installation environment of spc itself. You're right: programmers who are involved in compilation, or even programmers who are involved in libphp, may never be troubled by the compilation environment. But what we can do is to simplify this process as much as possible. Many people around me will give up using a project because the installation and deployment of it are too complicated.

@DubbleClick
Copy link
Contributor Author

I think that goes a bit too far. It's not too much to ask to spin up a VM and install php to run spc.

For automated build, I initially planned to build a GitHub Actions repository for self-configurable compilation in other systems and projects: https://github.com/crazywhalecc/setup-static-php

Yes, in my opinion this would be enough. It's reasonable to spin up an alpine image for development purposes on c++ extensions. If they can be built by a Github action that is simple to use in the end, I'm sure no user would object.

I will add the c++/alpine disclaimer in the readme, though, so new contributors can understand it better. Maybe I'll set up a cross-compiler chain for non-alpine when I'm bored, but it's not a priority then.

@DubbleClick
Copy link
Contributor Author

Good news, getting self compiled cross-musl running was very easy. I will create a pr with a full cross compile install.

[19:45:08] [INFO] Deploying cli file
[19:45:08] [INFO] [EXEC] cp '/opt/static-php-cli/source/php-src/sapi/cli/php' '/opt/static-php-cli/buildroot/bin/'
[19:45:08] [DEBU] Running command with direct output: cp '/opt/static-php-cli/source/php-src/sapi/cli/php' '/opt/static-php-cli/buildroot/bin/'
[19:45:08] [INFO] running cli sanity check
[19:45:08] [INFO] [EXEC] /opt/static-php-cli/buildroot/bin/php -r "echo \"hello\";"
[19:45:08] [DEBU] testing ext: snappy
[19:45:08] [DEBU] Running command with result: /opt/static-php-cli/buildroot/bin/php --ri "snappy"
[19:45:08] [INFO] Build complete, used 63.543 s !
[19:45:08] [INFO] Static php binary path: /opt/static-php-cli/buildroot/bin/php
[19:45:08] [DEBU] Removing path recursively: "/opt/static-php-cli/buildroot/license"
[19:45:08] [DEBU] scanning directory /opt/static-php-cli/buildroot/license
[19:45:08] [DEBU] Making new directory recursive: /opt/static-php-cli/buildroot/license
[19:45:08] [INFO] License path: /opt/static-php-cli/buildroot/license/

@DubbleClick
Copy link
Contributor Author

It does take a little while, though. ~5 minutes on my 5950x system, so it might definitely be 30+ minutes on a single core.

@DubbleClick
Copy link
Contributor Author

Treat musl as a dependent library and write it in library/linux/musl.php

I'm thinking about this, but I'm not sure it's a great idea. Notably, at times it can make sense to rebuild all libraries, such as when extensions change, but you wouldn't want to recompile musl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/dependency Issues related to dependencies os/linux Things only for Linux OS question Further information is requested
Projects
None yet
2 participants