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

Windows: compile xz with CMake #6947

Merged
merged 8 commits into from
Mar 29, 2023
Prev Previous commit
Next Next commit
windows: compile dependencies with ninja instead of nmake
  • Loading branch information
nulano committed Feb 13, 2023
commit abd2a3f7ee5a08ebbff3c21cd4658669d37a2fa8
6 changes: 5 additions & 1 deletion winbuild/build.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ Download and install:
* `CMake 3.13 or newer <https://cmake.org/download/>`_
(also available as Visual Studio component C++ CMake tools for Windows)

* x86/x64: `NASM <https://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D>`_
* `Ninja <https://ninja-build.org/>`_
(optional, use ``--nmake`` if not available; bundled in Visual Studio CMake component)

* x86/x64: `Netwide Assembler (NASM) <https://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D>`_

Any version of Visual Studio 2017 or newer should be supported,
including Visual Studio 2017 Community, or Build Tools for Visual Studio 2019.
Expand Down Expand Up @@ -53,6 +56,7 @@ behaviour of ``build_prepare.py``:
``build_prepare.py`` also supports the following command line parameters:

* ``-v`` will print generated scripts.
* ``--nmake`` will use NMake instead of Ninja for CMake dependencies
* ``--no-imagequant`` will skip GPL-licensed ``libimagequant`` optional dependency
* ``--no-fribidi`` or ``--no-raqm`` will skip optional LGPL-licensed dependency FriBiDi
(required for Raqm text shaping).
Expand Down
100 changes: 44 additions & 56 deletions winbuild/build_prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,28 @@ def cmd_nmake(makefile=None, target="", params=None):
)


def cmd_cmake(params=None, file="."):
if params is None:
params = ""
elif isinstance(params, (list, tuple)):
params = " ".join(params)
def cmds_cmake(target, *params):
if isinstance(target, str):
targets = ("clean", target)
else:
params = str(params)
return " ".join(
[
"{cmake}",
"-DCMAKE_VERBOSE_MAKEFILE=ON",
"-DCMAKE_RULE_MESSAGES:BOOL=OFF",
"-DCMAKE_BUILD_TYPE=Release",
f"{params}",
'-G "NMake Makefiles"',
f'"{file}"',
]
)
targets = ("clean", *target)

return [
" ".join(
[
"{cmake}",
"-DCMAKE_BUILD_TYPE=Release",
"-DCMAKE_VERBOSE_MAKEFILE=ON",
"-DCMAKE_RULE_MESSAGES:BOOL=OFF", # for NMake
"-DCMAKE_C_COMPILER=cl.exe", # for Ninja
"-DCMAKE_CXX_COMPILER=cl.exe", # for Ninja
*params,
'-G "{cmake_generator}"',
".",
]
),
*(f"{{cmake}} --build . --target {tgt}" for tgt in targets),
]


def cmd_msbuild(
Expand Down Expand Up @@ -118,19 +122,14 @@ def cmd_msbuild(
".+(libjpeg-turbo Licenses\n======================\n\n.+)$"
),
"build": [
cmd_cmake(
[
"-DENABLE_SHARED:BOOL=FALSE",
"-DWITH_JPEG8:BOOL=TRUE",
"-DWITH_CRT_DLL:BOOL=TRUE",
]
*cmds_cmake(
("jpeg-static", "cjpeg-static", "djpeg-static"),
"-DENABLE_SHARED:BOOL=FALSE",
"-DWITH_JPEG8:BOOL=TRUE",
"-DWITH_CRT_DLL:BOOL=TRUE",
),
cmd_nmake(target="clean"),
cmd_nmake(target="jpeg-static"),
cmd_copy("jpeg-static.lib", "libjpeg.lib"),
cmd_nmake(target="cjpeg-static"),
cmd_copy("cjpeg-static.exe", "cjpeg.exe"),
cmd_nmake(target="djpeg-static"),
cmd_copy("djpeg-static.exe", "djpeg.exe"),
],
"headers": ["j*.h"],
Expand All @@ -157,9 +156,7 @@ def cmd_msbuild(
"dir": "xz-5.4.1",
"license": "COPYING",
"build": [
cmd_cmake("-DBUILD_SHARED_LIBS:BOOL=OFF"),
cmd_nmake(target="clean"),
cmd_nmake(target="liblzma"),
*cmds_cmake("liblzma", "-DBUILD_SHARED_LIBS:BOOL=OFF"),
cmd_mkdir(r"{inc_dir}\lzma"),
cmd_copy(r"src\liblzma\api\lzma\*.h", r"{inc_dir}\lzma"),
],
Expand Down Expand Up @@ -205,11 +202,11 @@ def cmd_msbuild(
},
},
"build": [
cmd_cmake(
"-DBUILD_SHARED_LIBS:BOOL=OFF", "-DCMAKE_C_FLAGS=-DLZMA_API_STATIC"
),
cmd_nmake(target="clean"),
cmd_nmake(target="tiff"),
*cmds_cmake(
"tiff",
"-DBUILD_SHARED_LIBS:BOOL=OFF",
"-DCMAKE_C_FLAGS=-DLZMA_API_STATIC",
)
],
"headers": [r"libtiff\tiff*.h"],
"libs": [r"libtiff\*.lib"],
Expand All @@ -221,10 +218,7 @@ def cmd_msbuild(
"dir": "lpng1639",
"license": "LICENSE",
"build": [
# lint: do not inline
cmd_cmake(("-DPNG_SHARED:BOOL=OFF", "-DPNG_TESTS:BOOL=OFF")),
cmd_nmake(target="clean"),
cmd_nmake(),
*cmds_cmake("png_static", "-DPNG_SHARED:BOOL=OFF", "-DPNG_TESTS:BOOL=OFF"),
cmd_copy("libpng16_static.lib", "libpng16.lib"),
],
"headers": [r"png*.h"],
Expand All @@ -236,10 +230,7 @@ def cmd_msbuild(
"dir": "brotli-1.0.9",
"license": "LICENSE",
"build": [
cmd_cmake(),
cmd_nmake(target="clean"),
cmd_nmake(target="brotlicommon-static"),
cmd_nmake(target="brotlidec-static"),
*cmds_cmake(("brotlicommon-static", "brotlidec-static")),
cmd_xcopy(r"c\include", "{inc_dir}"),
],
"libs": ["*.lib"],
Expand Down Expand Up @@ -317,9 +308,9 @@ def cmd_msbuild(
}
},
"build": [
cmd_cmake(("-DBUILD_CODEC:BOOL=OFF", "-DBUILD_SHARED_LIBS:BOOL=OFF")),
cmd_nmake(target="clean"),
cmd_nmake(target="openjp2"),
*cmds_cmake(
"openjp2", "-DBUILD_CODEC:BOOL=OFF", "-DBUILD_SHARED_LIBS:BOOL=OFF"
),
cmd_mkdir(r"{inc_dir}\openjpeg-2.5.0"),
cmd_copy(r"src\lib\openjp2\*.h", r"{inc_dir}\openjpeg-2.5.0"),
],
Expand All @@ -338,10 +329,7 @@ def cmd_msbuild(
}
},
"build": [
# lint: do not inline
cmd_cmake(),
cmd_nmake(target="clean"),
cmd_nmake(target="imagequant_a"),
*cmds_cmake("imagequant_a"),
cmd_copy("imagequant_a.lib", "imagequant.lib"),
],
"headers": [r"*.h"],
Expand All @@ -354,9 +342,7 @@ def cmd_msbuild(
"license": "COPYING",
"build": [
cmd_set("CXXFLAGS", "-d2FH4-"),
cmd_cmake("-DHB_HAVE_FREETYPE:BOOL=TRUE"),
cmd_nmake(target="clean"),
cmd_nmake(target="harfbuzz"),
*cmds_cmake("harfbuzz", "-DHB_HAVE_FREETYPE:BOOL=TRUE"),
],
"headers": [r"src\*.h"],
"libs": [r"*.lib"],
Expand All @@ -369,9 +355,7 @@ def cmd_msbuild(
"build": [
cmd_copy(r"COPYING", r"{bin_dir}\fribidi-1.0.12-COPYING"),
cmd_copy(r"{winbuild_dir}\fribidi.cmake", r"CMakeLists.txt"),
cmd_cmake(),
cmd_nmake(target="clean"),
cmd_nmake(target="fribidi"),
*cmds_cmake("fribidi"),
],
"bins": [r"*.dll"],
},
Expand Down Expand Up @@ -600,10 +584,13 @@ def build_pillow():
else ("x86" if struct.calcsize("P") == 4 else "x64"),
)
build_dir = os.environ.get("PILLOW_BUILD", os.path.join(winbuild_dir, "build"))
cmake_generator = "Ninja"
sources_dir = ""
for arg in sys.argv[1:]:
if arg == "-v":
verbose = True
elif arg == "--nmake":
cmake_generator = "NMake Makefiles"
elif arg == "--no-imagequant":
disabled += ["libimagequant"]
elif arg == "--no-raqm" or arg == "--no-fribidi":
Expand Down Expand Up @@ -679,6 +666,7 @@ def build_pillow():
# Compilers / Tools
**msvs,
"cmake": "cmake.exe", # TODO find CMAKE automatically
"cmake_generator": cmake_generator,
# TODO find NASM automatically
# script header
"header": sum([header, msvs["header"], ["@echo on"]], []),
Expand Down