Skip to content

Commit

Permalink
boost: cmake test (#5640)
Browse files Browse the repository at this point in the history
* boost: cmake test

* fix windows build

* move test to single file

* add iostreams support

* support regex, locale

* use tar.gz

* support locale, python

* Use sorted libs

* support all buildable by default configs

* support all configs

* support header only config

* improve all config

* improve header only config

* add warning for mpi config

* merge to boost package

* workaround for cmake url

* boostdep: add package

* hack add_urls

* boostdep: fix c++ language

* improve xmake.lua
  • Loading branch information
star-hengxing authored Nov 4, 2024
1 parent bf358b3 commit ba8fd3c
Show file tree
Hide file tree
Showing 10 changed files with 1,066 additions and 461 deletions.
269 changes: 269 additions & 0 deletions packages/b/boost/b2/install.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
import("core.tool.toolchain")
import("core.base.option")

function _get_compiler(package, toolchain)
local cxx = package:build_getenv("cxx")
if package:is_plat("macosx") then
-- we uses ld/clang++ for link stdc++ for shared libraries
-- and we need `xcrun -sdk macosx clang++` to make b2 to get `-isysroot` automatically
local cc = package:build_getenv("ld")
if cc and cc:find("clang", 1, true) and cc:find("Xcode", 1, true) then
cc = "xcrun -sdk macosx clang++"
end
return format("using darwin : : %s ;", cc)
elseif package:is_plat("windows") then
local vs_toolset = toolchain:config("vs_toolset")
local msvc_ver = ""
local win_toolset = "msvc"
if toolchain:name() == "clang-cl" then
win_toolset = "clang-win"
cxx = cxx:gsub("(clang%-cl)$", "%1.exe", 1)
msvc_ver = ""
elseif vs_toolset then
local i = vs_toolset:find("%.")
msvc_ver = i and vs_toolset:sub(1, i + 1)
end

-- Specifying a version will disable b2 from forcing tools
-- from the latest installed msvc version.
return format("using %s : %s : \"%s\" ;", win_toolset, msvc_ver, cxx:gsub("\\", "\\\\"))
else
cxx = cxx:gsub("gcc$", "g++")
cxx = cxx:gsub("gcc%-", "g++-")
cxx = cxx:gsub("clang$", "clang++")
cxx = cxx:gsub("clang%-", "clang++-")
if cxx and cxx:find("clang", 1, true) then
return format("using clang : : \"%s\" ;", cxx:gsub("\\", "/"))
else
return format("using gcc : : \"%s\" ;", cxx:gsub("\\", "/"))
end
end
end

function _config_deppath(file, depname, rule)
local dep = package:dep(depname)
local info = dep:fetch({external = false})
if info then
local includedirs = table.wrap(info.sysincludedirs or info.includedirs)
for i, dir in ipairs(includedirs) do
includedirs[i] = path.unix(dir)
end
local linkdirs = table.wrap(info.linkdirs)
for i, dir in ipairs(linkdirs) do
linkdirs[i] = path.unix(dir)
end
local links = table.wrap(info.links)
local usingstr = format("\nusing %s : %s : <include>%s <search>%s <name>%s ;",
rule, dep:version(),
table.concat(includedirs, ";"),
table.concat(linkdirs, ";"),
table.concat(links, ";"))
file:write(usingstr)
end
end

function main(package)
import("libs", {rootdir = package:scriptdir()})

-- get host toolchain
local host_toolchain
if package:is_plat("windows") then
host_toolchain = toolchain.load("msvc", {plat = "windows", arch = os.arch()})
if not host_toolchain:check() then
host_toolchain = toolchain.load("clang-cl", {plat = "windows", arch = os.arch()})
end
assert(host_toolchain:check(), "host msvc or clang-cl not found!")
end

-- force boost to compile with the desired compiler
local file = io.open("user-config.jam", "w")
if file then
file:write(_get_compiler(package, host_toolchain))
file:close()
end

local bootstrap_argv =
{
"--prefix=" .. package:installdir(),
"--libdir=" .. package:installdir("lib"),
"--without-icu"
}

if package:has_tool("cxx", "clang", "clangxx") then
table.insert(bootstrap_argv, "--with-toolset=clang")
end

if package:is_plat("windows") then
-- for bootstrap.bat, all other arguments are useless
bootstrap_argv = { "msvc" }
os.vrunv("bootstrap.bat", bootstrap_argv, {envs = host_toolchain:runenvs()})
elseif package:is_plat("mingw") and is_host("windows") then
bootstrap_argv = { "gcc" }
os.vrunv("bootstrap.bat", bootstrap_argv)
-- todo looking for better solution to fix the confict between user-config.jam and project-config.jam
io.replace("project-config.jam", "using[^\n]+", "")
else
os.vrunv("./bootstrap.sh", bootstrap_argv)
end

-- get build toolchain
local build_toolchain
local build_toolset
local runenvs
if package:is_plat("windows") then
if package:has_tool("cxx", "clang_cl") then
build_toolset = "clang-win"
build_toolchain = package:toolchain("clang-cl")
elseif package:has_tool("cxx", "clang") then
build_toolset = "clang-win"
build_toolchain = package:toolchain("clang") or package:toolchain("llvm")
elseif package:has_tool("cxx", "cl") then
build_toolset = "msvc"
build_toolchain = package:toolchain("msvc")
end
if build_toolchain then
runenvs = build_toolchain:runenvs()
end
end

local file = io.open("user-config.jam", "w")
if file then
file:write(_get_compiler(package, build_toolchain))
if package:config("lzma") then
_config_deppath(file, "xz", "lzma")
end
if package:config("zstd") then
_config_deppath(file, "zstd", "zstd")
end
if package:config("zlib") then
_config_deppath(file, "zlib", "zlib")
end
if package:config("bzip2") then
_config_deppath(file, "bzip2", "bzip2")
end
file:close()
end
os.vrun("./b2 headers")

local njobs = option.get("jobs") or tostring(os.default_njob())
local argv =
{
"--prefix=" .. package:installdir(),
"--libdir=" .. package:installdir("lib"),
"-d2",
"-j" .. njobs,
"--hash",
"-q", -- quit on first error
"--layout=tagged-1.66", -- prevent -x64 suffix in case cmake can't find it
"--user-config=user-config.jam",
"install",
"threading=" .. (package:config("multi") and "multi" or "single"),
"debug-symbols=" .. (package:debug() and "on" or "off"),
"link=" .. (package:config("shared") and "shared" or "static"),
"variant=" .. (package:is_debug() and "debug" or "release"),
"runtime-debugging=" .. (package:is_debug() and "on" or "off")
}

local cxxflags = {}
if package:config("lzma") then
if package:is_plat("windows") and not package:dep("xz"):config("shared") then
table.insert(cxxflags, "-DLZMA_API_STATIC")
end
else
table.insert(argv, "-sNO_LZMA=1")
end
if not package:config("zstd") then
table.insert(argv, "-sNO_ZSTD=1")
end
if not package:config("zlib") then
table.insert(argv, "-sNO_ZLIB=1")
end
if not package:config("bzip2") then
table.insert(argv, "-sNO_BZIP2=1")
end

if package:config("lto") then
table.insert(argv, "lto=on")
end
if package:is_arch("aarch64", "arm+.*") then
table.insert(argv, "architecture=arm")
end
if package:is_arch(".+64.*") then
table.insert(argv, "address-model=64")
else
table.insert(argv, "address-model=32")
end

local linkflags = {}
table.join2(cxxflags, table.wrap(package:config("cxflags")))
table.join2(cxxflags, table.wrap(package:config("cxxflags")))
if package:is_plat("windows") then
if package:config("shared") then
table.insert(argv, "runtime-link=shared")
elseif package:has_runtime("MT", "MTd") then
table.insert(argv, "runtime-link=static")
else
table.insert(argv, "runtime-link=shared")
end
table.insert(argv, "toolset=" .. build_toolset)
table.insert(cxxflags, "-std:c++14")
elseif package:is_plat("mingw") then
table.insert(argv, "toolset=gcc")
elseif package:is_plat("macosx") then
table.insert(argv, "toolset=darwin")

-- fix macosx arm64 build issue https://github.com/microsoft/vcpkg/pull/18529
table.insert(cxxflags, "-std=c++14")
table.insert(cxxflags, "-arch")
table.insert(cxxflags, package:arch())
local xcode = package:toolchain("xcode") or import("core.tool.toolchain").load("xcode", {plat = package:plat(), arch = package:arch()})
if xcode:check() then
local xcode_dir = xcode:config("xcode")
local xcode_sdkver = xcode:config("xcode_sdkver")
local target_minver = xcode:config("target_minver")
if xcode_dir and xcode_sdkver then
local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX" .. xcode_sdkver .. ".sdk"
table.insert(cxxflags, "-isysroot")
table.insert(cxxflags, xcode_sdkdir)
end
if target_minver then
table.insert(cxxflags, "-mmacosx-version-min=" .. target_minver)
end
end
else
table.insert(cxxflags, "-std=c++14")
if package:config("pic") ~= false then
table.insert(cxxflags, "-fPIC")
end
end
if package.has_runtime and package:has_runtime("c++_shared", "c++_static") then
table.insert(cxxflags, "-stdlib=libc++")
table.insert(linkflags, "-stdlib=libc++")
if package:has_runtime("c++_static") then
table.insert(linkflags, "-static-libstdc++")
end
end
if package:config("asan") then
table.insert(cxxflags, "-fsanitize=address")
table.insert(linkflags, "-fsanitize=address")
end
if cxxflags then
table.insert(argv, "cxxflags=" .. table.concat(cxxflags, " "))
end
if linkflags then
table.insert(argv, "linkflags=" .. table.concat(linkflags, " "))
end
libs.for_each(function (libname)
if package:config("all") or package:config(libname) then
table.insert(argv, "--with-" .. libname)
end
end)

if package:is_plat("linux") then
table.insert(argv, "pch=off")
end
local ok = os.execv("./b2", argv, {envs = runenvs, try = true, stdout = "boost-log.txt"})
if ok ~= 0 then
raise("boost build failed, please check log in " .. path.join(os.curdir(), "boost-log.txt"))
end
end
94 changes: 94 additions & 0 deletions packages/b/boost/b2/load.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
function _get_linkname(package, libname)
local linkname
if package:is_plat("windows") then
linkname = (package:config("shared") and "boost_" or "libboost_") .. libname
else
linkname = "boost_" .. libname
end
if libname == "python" or libname == "numpy" then
linkname = linkname .. package:config("pyver"):gsub("%p+", "")
end
if package:config("multi") then
linkname = linkname .. "-mt"
end
if package:is_plat("windows") then
if package:config("shared") then
if package:debug() then
linkname = linkname .. "-gd"
end
elseif package:config("asan") or package:has_runtime("MTd") then
linkname = linkname .. "-sgd"
elseif package:has_runtime("MT") then
linkname = linkname .. "-s"
elseif package:config("asan") or package:has_runtime("MDd") then
linkname = linkname .. "-gd"
end
else
if package:debug() then
linkname = linkname .. "-d"
end
end
return linkname
end

function main(package)
import("libs", {rootdir = package:scriptdir()})

-- we need the fixed link order
local headeronly = not package:config("all")
local sublibs = {log = {"log_setup", "log"},
python = {"python", "numpy"},
stacktrace = {"stacktrace_backtrace", "stacktrace_basic"}}

libs.for_each(function (libname)
if package:config(libname) then
headeronly = false
end
local libs = sublibs[libname]
if libs then
for _, lib in ipairs(libs) do
package:add("links", _get_linkname(package, lib))
end
else
package:add("links", _get_linkname(package, libname))
end
end)

if headeronly then
package:set("kind", "library", {headeronly = true})
end
-- disable auto-link all libs
if package:is_plat("windows") then
package:add("defines", "BOOST_ALL_NO_LIB")
end

if package:config("python") then
if not package:config("shared") then
package:add("defines", "BOOST_PYTHON_STATIC_LIB")
end
package:add("deps", "python " .. package:config("pyver") .. ".x", {configs = {headeronly = true}})
end
if package:config("zstd") then
package:add("deps", "zstd")
end
if package:config("lzma") then
package:add("deps", "xz")
end
if package:config("zlib") then
package:add("deps", "zlib")
end
if package:config("bzip2") then
package:add("deps", "bzip2")
end

if package:is_plat("windows") and package:version():le("1.85.0") then
local vs_toolset = package:toolchain("msvc"):config("vs_toolset")
if vs_toolset then
local vs_toolset_ver = import("core.base.semver").new(vs_toolset)
local minor = vs_toolset_ver:minor()
if minor and minor >= 40 then
package:add("patches", "<=1.85.0", "patches/1.85.0/fix-v144.patch", "1ba99cb2e2f03a4ba489a32596c62e1310b6c73ba4d19afa8796bcf180c84422")
end
end
end
end
Loading

0 comments on commit ba8fd3c

Please sign in to comment.