-
-
Notifications
You must be signed in to change notification settings - Fork 418
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
OpenSSL: improve MinGW support on Windows #6079
Changes from 9 commits
4a58502
4556226
17ea9ac
abe12e9
79e98d4
79c6f04
0e4066b
d5e12bc
661f083
2121619
2cf58d8
43c7fb9
0de6b83
aeecc86
a7144ca
409ef37
6d5fbd8
d6a3f76
c86fa6e
dbe0b01
977b69c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
function _remove_unused_modules() | ||
io.replace("Configure", "use Pod::Usage;", "", {plain = true}) | ||
io.replace("Configure", "pod2usage.-;", "") | ||
end | ||
|
||
function main(package, opt) | ||
if not package:is_plat("windows") and not opt.perl.use_unix_path then | ||
os.tryrm("Configurations/unix*-checker.pm") | ||
end | ||
if package:is_plat("windows") and opt.perl.use_unix_path then | ||
io.replace("Configurations/10-main.conf", "NUL", "null", {plain = true}) | ||
end | ||
_remove_unused_modules() | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
function main(package, opt) | ||
if not package:is_plat("windows") and not opt.perl.use_unix_path then | ||
local apps_openssl = io.readfile("Makefile"):match("APPS_OPENSSL=([^\r\n]*)") | ||
io.gsub("Makefile", "\\([^%s\"\\])", "/%1") | ||
io.replace("Makefile", "APPS_OPENSSL=([^\r\n]*)", "APPS_OPENSSL=" .. apps_openssl) | ||
io.replace("Makefile", "$(APPS_OPENSSL)", [["$(APPS_OPENSSL)"]], {plain = true}) | ||
end | ||
|
||
if package:is_plat("windows") then | ||
io.replace("makefile", "PERL=([^\r\n]*)", "PERL=" .. opt.perl.program) | ||
else | ||
io.replace("Makefile", "PERL=([^\r\n]*)", ([[PERL="%s"]]):format(opt.perl.program)) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,20 +28,25 @@ package("openssl") | |
on_fetch("fetch") | ||
|
||
on_load(function (package) | ||
if not package:is_precompiled() then | ||
if package:is_plat("android") and is_subhost("windows") and os.arch() == "x64" then | ||
-- when building for android on windows, use msys2 perl instead of strawberry-perl to avoid configure issue | ||
package:add("deps", "msys2", {configs = {msystem = "MINGW64", base_devel = true}, private = true}) | ||
elseif is_subhost("windows") and not package:is_precompiled() then | ||
if package:is_plat("android") and is_subhost("windows") and os.arch() == "x64" then | ||
-- when building for android on windows, use msys2 perl instead of strawberry-perl to avoid configure issue | ||
package:add("deps", "msys2", {configs = {msystem = "MINGW64", base_devel = true}, private = true}) | ||
elseif is_subhost("windows") then | ||
import("lib.detect.find_tool") | ||
local perl = find_tool("perl", {paths={"$(env PERL)"}}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should not call |
||
if not perl then | ||
package:add("deps", "strawberry-perl", { private = true }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why remove There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please share more details about the scenarios where the system Perl might fail? There might be a workaround we can implement to address this issue. Using the system Perl helps save disk space. For your reference, I tested with Perl installed via There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't reproduce it because I don't remember what happened before. But since there is a clear comment to fix this problem by passing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment indicated that Perl bundled with GitForWindows fails to build OpenSSL. I encountered this issue too at the beginning. The error message is as follows:
I looked into the config script and found that |
||
end | ||
if package:is_plat("windows") then | ||
package:add("deps", "nasm", { private = true }) | ||
-- the perl executable found in GitForWindows will fail to build OpenSSL | ||
-- see https://github.com/openssl/openssl/blob/master/NOTES-PERL.md#perl-on-windows | ||
package:add("deps", "strawberry-perl", { system = false, private = true }) | ||
-- check xmake tool jom | ||
import("package.tools.jom", {try = true}) | ||
if jom then | ||
package:add("deps", "jom", {private = true}) | ||
end | ||
else | ||
wprint("package(openssl): OpenSSL should be built in a Unix-like shell (e.g., MSYS2, Git Bash) if not targeting MSVC. " .. | ||
"It seems you are not in such an environment. If you encounter build errors, please consider trying again in a Unix-like shell.") | ||
end | ||
end | ||
|
||
|
@@ -61,6 +66,20 @@ package("openssl") | |
end | ||
end) | ||
|
||
if on_check then | ||
on_check(function (package) | ||
import("lib.detect.find_tool") | ||
local perl = assert(find_tool("perl", {paths={"$(env PERL)"}}), "package(openssl): perl not found!") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use package:find_tool and add spaces |
||
local working_dir = os.iorunv(perl.program, {"-MFile::Spec::Functions=rel2abs", "-e", "print rel2abs('.')"}) | ||
-- Check if Perl is using Unix-style paths | ||
local use_unix_path = working_dir:find("/") == 1 | ||
if use_unix_path and package:is_plat("windows") or not use_unix_path and not package:is_plat("windows") then | ||
wprint("package(openssl): The detected Perl may not match your build platform. While it should generally work, it could potentially cause issues. If you encounter any build problems, " .. | ||
"please try installing a compatible version of Perl. If you already have a suitable Perl installed but still see this message, ensure it takes priority over other Perl installations in your system.") | ||
end | ||
end) | ||
end | ||
|
||
on_install("windows", function (package) | ||
import("package.tools.jom", {try = true}) | ||
import("package.tools.nmake") | ||
|
@@ -83,7 +102,13 @@ package("openssl") | |
table.insert(configs, "no-makedepend") | ||
table.insert(configs, "/FS") | ||
end | ||
os.vrunv("perl", configs) | ||
import("lib.detect.find_tool") | ||
local perl = assert(find_tool("perl", {paths={"$(env PERL)"}}), "package(openssl): perl not found!") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should not call |
||
local working_dir = os.iorunv(perl.program, {"-MFile::Spec::Functions=rel2abs", "-e", "print rel2abs('.')"}) | ||
perl.use_unix_path = working_dir:find("/") == 1 | ||
import("configure.patch")(package, {perl = perl}) | ||
os.vrunv(perl.program, configs, {envs = {CONFIGURE_INSIST = 1}}) | ||
import("makefile.patch")(package, {perl = perl}) | ||
|
||
if jom then | ||
jom.build(package) | ||
|
@@ -94,39 +119,10 @@ package("openssl") | |
end | ||
end) | ||
|
||
on_install("mingw", function (package) | ||
local configs = {"Configure", "no-tests"} | ||
table.insert(configs, package:is_arch("i386", "x86") and "mingw" or "mingw64") | ||
table.insert(configs, package:config("shared") and "shared" or "no-shared") | ||
local installdir = package:installdir() | ||
-- Use MSYS2 paths instead of Windows paths | ||
if is_subhost("msys") then | ||
installdir = installdir:gsub("(%a):[/\\](.+)", "/%1/%2"):gsub("\\", "/") | ||
end | ||
table.insert(configs, "--prefix=" .. installdir) | ||
table.insert(configs, "--openssldir=" .. installdir) | ||
local buildenvs = import("package.tools.autoconf").buildenvs(package) | ||
buildenvs.RC = package:build_getenv("mrc") | ||
if is_subhost("msys") then | ||
local rc = buildenvs.RC | ||
if rc then | ||
rc = rc:gsub("(%a):[/\\](.+)", "/%1/%2"):gsub("\\", "/") | ||
buildenvs.RC = rc | ||
end | ||
end | ||
-- fix 'cp: directory fuzz does not exist' | ||
if package:config("shared") then | ||
os.mkdir("fuzz") | ||
end | ||
os.vrunv("perl", configs, {envs = buildenvs}) | ||
import("package.tools.make").build(package) | ||
import("package.tools.make").make(package, {"install_sw"}) | ||
end) | ||
|
||
on_install("linux", "macosx", "bsd", "cross", "android", "iphoneos", function (package) | ||
on_install("linux", "macosx", "bsd", "cross", "android", "iphoneos", "mingw", function (package) | ||
-- https://wiki.openssl.org/index.php/Compilation_and_Installation#PREFIX_and_OPENSSLDIR | ||
local configs = {} | ||
if package:is_cross() then | ||
local configs = {"no-tests"} | ||
if package:is_cross() or package:is_plat("mingw") then | ||
local target_plat, target_arch | ||
if package:is_plat("macosx") then | ||
target_plat = "darwin64" | ||
|
@@ -145,6 +141,21 @@ package("openssl") | |
end | ||
target_arch = "cross" | ||
end | ||
elseif package:is_plat("mingw") then | ||
target_plat = package:is_arch("i386", "x86") and "mingw" or "mingw64" | ||
elseif package:is_plat("bsd") then | ||
target_plat = "BSD" | ||
if package:is_arch("i386") then | ||
target_arch = "x86" | ||
elseif package:is_arch("x86_64") then | ||
target_arch = "x86_64" | ||
elseif package:is_arch("arm64") then | ||
target_arch = "aarch64" | ||
elseif package:is_arch("riscv64") then | ||
target_arch = "riscv64" | ||
elseif package:is_arch(".*64") then | ||
target_arch = "generic64" | ||
end | ||
else | ||
target_plat = "linux" | ||
if package:is_arch("x86_64") then | ||
|
@@ -161,36 +172,83 @@ package("openssl") | |
target_arch = "generic32" | ||
end | ||
end | ||
table.insert(configs, target_plat .. "-" .. target_arch) | ||
if package:is_plat("cross", "android") then | ||
table.insert(configs, "-DOPENSSL_NO_HEARTBEATS") | ||
table.insert(configs, "no-threads") | ||
end | ||
table.insert(configs, target_arch and (target_plat .. "-" .. target_arch) or target_plat) | ||
end | ||
table.insert(configs, "--openssldir=" .. package:installdir():gsub("\\", "/")) | ||
table.insert(configs, "--prefix=" .. package:installdir():gsub("\\", "/")) | ||
if package:is_plat("cross", "android") then | ||
table.insert(configs, "-DOPENSSL_NO_HEARTBEATS") | ||
table.insert(configs, "no-threads") | ||
end | ||
local installdir = package:installdir() | ||
-- Use MSYS2 paths instead of Windows paths | ||
if is_subhost("msys") then | ||
installdir = installdir:gsub("(%a):[/\\](.+)", "/%1/%2") | ||
end | ||
installdir = installdir:gsub("\\", "/") | ||
table.insert(configs, "--openssldir=" .. installdir) | ||
table.insert(configs, "--prefix=" .. installdir) | ||
table.insert(configs, package:config("shared") and "shared" or "no-shared") | ||
if package:debug() then | ||
table.insert(configs, "--debug") | ||
end | ||
|
||
local buildenvs = import("package.tools.autoconf").buildenvs(package) | ||
if package:is_cross() then | ||
if is_host("windows") and package:is_plat("android") then | ||
buildenvs.CFLAGS = buildenvs.CFLAGS:gsub("\\", "/") | ||
buildenvs.CXXFLAGS = buildenvs.CXXFLAGS:gsub("\\", "/") | ||
buildenvs.CPPFLAGS = buildenvs.CPPFLAGS:gsub("\\", "/") | ||
buildenvs.ASFLAGS = buildenvs.ASFLAGS:gsub("\\", "/") | ||
if is_host("windows") and package:is_plat("android") then | ||
buildenvs.CFLAGS = buildenvs.CFLAGS:gsub("\\", "/") | ||
buildenvs.CXXFLAGS = buildenvs.CXXFLAGS:gsub("\\", "/") | ||
buildenvs.CPPFLAGS = buildenvs.CPPFLAGS:gsub("\\", "/") | ||
buildenvs.ASFLAGS = buildenvs.ASFLAGS:gsub("\\", "/") | ||
end | ||
if package:is_plat("mingw") then | ||
buildenvs.RC = package:build_getenv("mrc") | ||
if is_subhost("msys") and buildenvs.RC then | ||
buildenvs.RC = buildenvs.RC:gsub("(%a):[/\\](.+)", "/%1/%2"):gsub("\\", "/") | ||
end | ||
os.vrunv("perl", table.join("./Configure", configs), {envs = buildenvs}) | ||
-- fix 'cp: directory fuzz does not exist' | ||
if package:config("shared") then | ||
os.mkdir("fuzz") | ||
end | ||
end | ||
|
||
import("lib.detect.find_tool") | ||
local perl = assert(find_tool("perl", {paths={"$(env PERL)"}}), "package(openssl): perl not found!") | ||
local working_dir = os.iorunv(perl.program, {"-MFile::Spec::Functions=rel2abs", "-e", "print rel2abs('.')"}) | ||
perl.use_unix_path = working_dir:find("/") == 1 | ||
import("configure.patch")(package, {perl = perl}) | ||
if package:is_cross() or package:is_plat("mingw") then | ||
os.vrunv(perl.program, table.join("./Configure", configs), {envs = buildenvs}) | ||
else | ||
os.vrunv("./config", configs, {shell = true, envs = buildenvs}) | ||
end | ||
|
||
import("makefile.patch")(package, {perl = perl}) | ||
import("package.tools.make").build(package) | ||
import("package.tools.make").make(package, {"install_sw"}) | ||
if package:config("shared") then | ||
os.tryrm(path.join(package:installdir("lib"), "*.a")) | ||
os.tryrm(path.join(package:installdir("lib"), "*.a|*.dll.a")) | ||
end | ||
end) | ||
on_test(function (package) | ||
assert(package:has_cfuncs("SSL_new", {includes = "openssl/ssl.h"})) | ||
assert(package:check_csnippets({test = [[ | ||
#include <openssl/ssl.h> | ||
|
||
int test(){ | ||
SSL_library_init(); | ||
SSL_load_error_strings(); | ||
SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); | ||
if(ctx == NULL){ | ||
return 1; | ||
} | ||
|
||
SSL *ssl = SSL_new(ctx); | ||
if(ssl == NULL){ | ||
SSL_CTX_free(ctx); | ||
return 1; | ||
} | ||
|
||
SSL_free(ssl); | ||
SSL_CTX_free(ctx); | ||
|
||
return 0; | ||
} | ||
]]})) | ||
end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and why not remove
not package:is_precompiled()
?If you are using the build-artifacts binary, you do not need to compile openssl and install its build dependencies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, there is no
is_precompiled
nowThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but we need is_precompiled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I misunderstood.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are downloading a precompiled binary, then all build dependencies do not need to be installed.
https://github.com/xmake-mirror/build-artifacts/releases?q=openssl&expanded=true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the outer
if not package:is_precompiled() then
might work .xmake-repo/packages/o/openssl/xmake.lua
Lines 30 to 31 in a7144ca