logo
Apache Lounge
Webmasters

 

About Forum Index Downloads Search Register Log in RSS X


Keep Server Online

If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.

or

Bitcoin

A donation makes a contribution towards the costs, the time and effort that's going in this site and building.

Thank You! Steffen

Your donations will help to keep this site alive and well, and continuing building binaries. Apache Lounge is not sponsored.
Post new topic   Forum Index -> How-to's & Documentation & Tips View previous topic :: View next topic
Reply to topic   Topic: HOWTO: Building extra Apache modules using CMake
Author
tangent
Moderator


Joined: 16 Aug 2020
Posts: 410
Location: UK

PostPosted: Mon 03 Nov '25 18:13    Post subject: HOWTO: Building extra Apache modules using CMake Reply with quote

This post previously focused on building ModSecurity as an additional module for Apache, but has been reworked to cover building a number of extra modules, currently tracking those listed on the downloads page https://www.apachelounge.com/download.

The post is supplemental to, and dependent on, the related HOWTO "Building Apache and dependencies using CMake" https://www.apachelounge.com/viewtopic.php?t=8609

Specifically, it assumes the same build platform, toolset and structure. However, the source code for most of these additional modules doesn't come with a CMakeLists.txt file, so to build with CMake, these need to be provided. Minimal working versions of these can be downloaded from Pastebin (see below for more details). Note, this script can be used to create 32bit as well as 64bit modules.

Change log :
21 Dec 2025 : 1.0 - Initial release.
22 Dec 2025 : 1.1 - Build YAJL and update ModSecurity to use it.
31 Dec 2025 : 1.2 - Build MOD_FCGID, MOD_WATCH and MOD_VIEW.

Sequence
  1. Prerequisites
    Complete the Apache build process detailed in HOWTO "Building Apache and dependencies using CMake" - https://www.apachelounge.com/viewtopic.php?t=8609

  2. Preparation
    Depending on which modules you wish to build, add the following source folders based on the appropriate version of the packages. This list matches the latest package versions available at the time of writing.

    Code:
    C:\Development
        └ Apache24
           ├ src
           │   ├ dbd-modules-1.06
           │   ├ modsecurity-v2.9.12
           │   ├ mod_bw-0.92
           │   ├ mod_evasive-2.4.0
           │   ├ mod_fcgid-2.3.9
           │   ├ mod_log_rotate-1.02
           │   ├ mod_qos-11.76
           │   ├ mod_view-2.2
           │   ├ mod_watch-4.3p
           │   ├ mod_xsendfile-0.12
           │   ├ tomcat-connectors-1.2.50-src
           │   └ yajl-2.1.0
           └ build

  3. Source Packages
    Download and extract the above source code packages (*.tar.gz or *.zip format) into the corresponding source folders shown above.

    Most of these packages can be downloaded from GitHub or SourceForge. However, the source code for some of these modules is no longer publicly available (notably mod_watch and mod_view); nonetheless, build code for all these modules has been included for completeness.

  4. Build Batch File
    Download the build batch file code from the post below in this thread, and save it in the above 'build' folder as build_extra_modules.bat

    a) Edit the build batch file to set BUILD_BASE as required, if using a different path to that before.
    b) Update the target PREFIX, if the default location of C:\Apache24 isn't correct (no whitespace advised).
    c) Choose 32 or 64 bit builds by setting the PLATFORM variable in the build batch file to x86 or x64 as required.
    d) Similarly, set the variable BUILD_TYPE to Release or Debug.
    e) Edit the package version details to match your downloads as appropriate.
    f) Comment out the package version variable for any module you don't want to build, e.g. mod_view and mod_watch.
    g) Choose VS2022(17) or VS2026(18) builds by setting the MSVS-SERIES variable to 17 or 18 as required, to match your build toolset.

  5. Additional CMakeLists.txt Files
    As mentioned above, additional CMakeLists.txt files are required to build these modules, and minimal working versions can be downloaded from https://pastebin.com/u/tangentia.

    These should be saved in the above source (src) folder with names of the form "CMakeLists - PACKAGE.txt", where PACKAGE should match the corresponding package build variable with version detail, e.g. for MOD_EVASIVE the file should be named "CMakeLists - mod_evasive-2.4.0.txt". The build script looks for the appropriate file, and initially copies it into the package folder as CMakeLists.txt.

  6. Build
    Open a command or Powershell window with administrative rights, change to the above build folder, and run the build_all_modules.bat batch file. Ideally, redirect the build process output to a log file so you can check for errors. If using Powershell, you can use the tee command, viz:

    Code:
    C:\Development\Apache24\build> .\build_extra_modules.bat 2>&1 | tee build_extra_modules.log

    N.B. A Windows native binary of tee can be found still at https://gnuwin32.sourceforge.net/packages/coreutils.htm

  7. Checks
    When finished search the log file output for fatal errors (hopefully none).

    Confirm the relevant Apache module files have been created and installed below PREFIX, e.g.
    Code:
    C:\Development\apache24\build>dir C:\Apache24\modules\mod_security2.so
     Volume in drive C has no label.
     Volume Serial Number is 6874-FF76

     Directory of c:\Apache24\modules

    31/02/2025  11:45           671,744 mod_security2.so
                   1 File(s)        671,744 bytes
                   0 Dir(s)  65,599,393,792 bytes free

    C:\Development\apache24\build>dir c:\Apache24\conf\extra\modsecurity*
     Volume in drive C has no label.
     Volume Serial Number is 6874-FF76

     Directory of c:\Apache24\conf\extra

    05/08/2025  19:08             9,047 modsecurity.conf-recommended
                   1 File(s)          9,047 bytes
                   0 Dir(s)  54,406,705,152 bytes free


    Prepare and test your extra module configuration within Apache as required.

    I hope people find this HOWTO useful.


Last edited by tangent on Fri 02 Jan '26 22:15; edited 5 times in total
Back to top
tangent
Moderator


Joined: 16 Aug 2020
Posts: 410
Location: UK

PostPosted: Mon 03 Nov '25 18:14    Post subject: Reply with quote

Change log :
21 Dec 2025 : 1.0 - Initial release.
22 Dec 2025 : 1.1 - Build YAJL and update ModSecurity to use it.
31 Dec 2025 : 1.2 - Build MOD_FCGID, MOD_WATCH and MOD_VIEW.

Code:
@echo off

rem @(#)build_extra_modules.bat 1.2 - 2025-12-31 tangent
rem
rem 1.0 - Initial release. 2025-12-21
rem 1.1 - Build YAJL and update ModSecurity to use it. 2025-12-22
rem 1.2 - Build MOD_FCGID, MOD_WATCH and MOD_VIEW. 2025-12-31

rem Build additional modules for Apache command file for Windows, using custom
rem CMakeLists.txt files where necessary. The script looks for these files in
rem the source folder with names of the form "CMakelists - %PACKAGE%.txt".
rem
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

rem Set required build base folder and target prefix.
rem
set BUILD_BASE=C:\Development\Apache24\build
set PREFIX=C:\Apache24

rem Set required build platform to x86 or x64.
rem
rem set PLATFORM=x86
set PLATFORM=x64

rem Set required build type to Release or Debug.
rem
rem set BUILD_TYPE=Debug
set BUILD_TYPE=Release

rem Request PDB files - ON or OFF.
rem
set INSTALL_PDB=OFF

rem ------------------------------------------------------------------------------
rem
rem Define build packages with their version.
rem Comment out any you don't wish to build.
rem
set MOD_JK=tomcat-connectors-1.2.50-src
set MOD_QOS=mod_qos-11.76
set MOD_FCGID=mod_fcgid-2.3.9
set YAJL=yajl-2.1.0
set MOD_SECURITY2=modsecurity-v2.9.12
set MOD_XSENDFILE=mod_xsendfile-0.12
set MOD_LOG_ROTATE=mod_log_rotate-1.02
set DBD_MODULES=dbd-modules-1.06
set MOD_BW=mod_bw-0.92
rem set MOD_VIEW=mod_view-2.2
rem set MOD_WATCH=mod_watch-4.3p
set MOD_EVASIVE=mod_evasive-2.4.0

rem ------------------------------------------------------------------------------
rem
rem Define MS Visual Studio series to be used for the build.
rem Visual Studio 2022 is series 17 whilst 2026 is series 18.
rem
set MSVS-SERIES=17
rem set MSVS-SERIES=18

echo Build request using MS Visual Studio series %MSVS-SERIES%

rem Define path to MS Visual Studio build environment script.
rem
if not defined VCVARSALL (
  rem Choose path based on MS Visual Studio series.
  rem
  if "%MSVS-SERIES%" == "17" (
    set "VCVARSALL=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat"
  ) else if "%MSVS-SERIES%" == "18" (
    set "VCVARSALL=C:\Program Files\Microsoft Visual Studio\18\Community\VC\Auxiliary\Build\vcvarsall.bat"
  ) else (
    echo MS Visual Studio series not supported
    exit /b
  )
)

if exist "%VCVARSALL%" (
  call "%VCVARSALL%" %PLATFORM%
) else (
  echo Could not find "%VCVARSALL%"
  exit /b
)

rem ------------------------------------------------------------------------------
rem
rem Get best CMake version and path. Needed to set CMake policy and other options.
rem
call :get_best_cmake_version

rem ------------------------------------------------------------------------------
rem
rem Define CMake policy minimum version for those packages that don't currently comply with
rem the minimum version supported by a given version of MSVC CMake. This version can be
rem passed to CMake to override any version entry in the current CMakeLists.txt file, but
rem may produce a warning message.
rem
set CMAKE_POL_VER_MIN=3.15

rem Define CMake common options, passed to all CMake build requests. The CMAKE_PREFIX_PATH
rem is needed to prevent libraries on the search path being chosen in preference to ones
rem we've compiled.
rem
set CMAKE_COMMON_OPTS=-DCMAKE_INSTALL_PREFIX=%PREFIX% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_PREFIX_PATH=%PREFIX%\lib

rem Define verbose to see more processing details from CMake.
rem
rem set VERBOSE=1

rem If selected CMake version is >= 4 then add policy version minimum setting.
rem
if !CMAKE_MAJOR_VERSION! geq 4 (
  set CMAKE_COMMON_OPTS=!CMAKE_COMMON_OPTS! -DCMAKE_POLICY_VERSION_MINIMUM=%CMAKE_POL_VER_MIN%
)

rem ------------------------------------------------------------------------------
rem
rem MOD_JK
rem
if DEFINED %MOD_JK% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_JK%

  if !STATUS! == 0 (
    set MOD_JK_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_JK% "!MOD_JK_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem MOD_QOS
rem
if DEFINED %MOD_QOS% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_QOS%

  if !STATUS! == 0 (
    set MOD_QOS_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_QOS% "!MOD_QOS_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem MOD_FCGID
rem
if DEFINED %MOD_FCGID% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_FCGID%

  if !STATUS! == 0 (
    rem Check if we're building MOD_FCGID 2.3.9 and if so define build subfolder.
    rem
    if "%MOD_FCGID:*2.3.9=YES%" == "YES" (
      set MOD_FCGID_BUILD_SUBFOLDER=modules\fcgid
    )

    set MOD_FCGID_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_FCGID% "!MOD_FCGID_CMAKE_OPTS!" !MOD_FCGID_BUILD_SUBFOLDER!
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem YAJL
rem
if DEFINED %YAJL% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %YAJL%

  if !STATUS! == 0 (
    rem Patch src CMakeLists.txt file to adjust install locations and
    rem replace obsolete EXEC_PROGRAM() directive with EXECUTE_PROCESS().
    rem
    perl -pi.bak -e ^" ^
      s~(RUNTIME DESTINATION^) lib~${1} bin~; ^
      s~(DESTINATION^) share(/pkgconfig^)~${1} lib${2}~; ^
      s~^^(([\h]+^)(EXEC_PROGRAM\(^)(.+^)( ARGS^)(.+^)^)$~#${1}\n${2}EXECUTE_PROCESS(COMMAND ${4}${6}~; ^
      ^" src\CMakeLists.txt

    rem Patch reformatter & verify CMakeLists.txt files to replace obsolete
    rem GET_TARGET_PROPERTY() directive with updated add_custom_command().
    rem
    perl -pi.bak -e ^" ^
      s~^^(GET_TARGET_PROPERTY^)~# *** OBSOLETE *** =\x3E ${1}~; ^
      s~\x24\x7BbinPath\x7D~^\x24\x3CTARGET_FILE:json_reformat\x3E~; ^
      ^" reformatter\CMakeLists.txt verify\CMakeLists.txt

    set YAJL_CMAKE_OPTS=%CMAKE_COMMON_OPTS%
    call :build_package %YAJL% "!YAJL_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem MOD_SECURITY2
rem
if DEFINED %MOD_SECURITY2% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_SECURITY2%

  if !STATUS! == 0 (
    set MOD_SECURITY2_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_SECURITY2% "!MOD_SECURITY2_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem MOD_XSENDFILE
rem
if DEFINED %MOD_XSENDFILE% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_XSENDFILE%

  if !STATUS! == 0 (
    rem Original source at https://tn123.org/mod_xsendfile
    rem Patch to include fix: https://github.com/nmaier/mod_xsendfile/issues/8
    rem
    perl -pi.bak -e ^" ^
      s~(\(rv = apr_file_info_get.+= ^)(APR_SUCCESS^)\^) {~${1}${2} \x26\x26 ${1}APR_INCOMPLETE^) {~i;^
      ^" mod_xsendfile.c

    set MOD_XSENDFILE_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_XSENDFILE% "!MOD_XSENDFILE_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem MOD_LOG_ROTATE
rem
if DEFINED %MOD_LOG_ROTATE% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_LOG_ROTATE%

  if !STATUS! == 0 (
    set MOD_LOG_ROTATE_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_LOG_ROTATE% "!MOD_LOG_ROTATE_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem DBD_MODULES
rem
if DEFINED %DBD_MODULES% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %DBD_MODULES%

  if !STATUS! == 0 (
    set DBD_MODULES_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %DBD_MODULES% "!DBD_MODULES_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem MOD_BW
rem
if DEFINED %MOD_BW% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_BW%

  if !STATUS! == 0 (
    rem Original source at https://github.com/lvnSoft/mod_bw
    rem Patch source file to support Apache 2.4 declaration.
    rem
    perl -pi.bak -e ^" ^
      s~(^>^)remote_addr~${1}client_addr~i;^
      ^" mod_bw.c

    set MOD_BW_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_Bw% "!MOD_BW_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem MOD_VIEW
rem
if DEFINED %MOD_VIEW% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_VIEW%

  if !STATUS! == 0 (
    set MOD_VIEW_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_VIEW% "!MOD_VIEW_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem MOD_WATCH
rem
if DEFINED %MOD_WATCH% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_WATCH%

  if !STATUS! == 0 (
    set MOD_WATCH_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_WATCH% "!MOD_WATCH_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)

rem ------------------------------------------------------------------------------
rem
rem MOD_EVASIVE
rem
if DEFINED %MOD_EVASIVE% then (
  rem Check for package and switch to source folder.
  rem
  call :check_package_source %MOD_EVASIVE%

  if !STATUS! == 0 (
    set MOD_EVASIVE_CMAKE_OPTS=%CMAKE_COMMON_OPTS% -DINSTALL_PDB=%INSTALL_PDB%
    call :build_package %MOD_EVASIVE% "!MOD_EVASIVE_CMAKE_OPTS!"
  )
  if not !STATUS! == 0 (exit /b !STATUS!)
)
exit /b !STATUS!

rem ------------------------------------------------------------------------------
rem
rem Get current errorlevel value and assign it to the status variable.
rem
:get_status
call doskey /exename=err err=%%errorlevel%%
for /f "usebackq tokens=2 delims== " %%i in (`doskey /m:err`) do (set STATUS=%%i)
exit /b !STATUS!

rem ------------------------------------------------------------------------------
rem
rem Get package and version from release variable passed as first parameter.
rem
:get_package_details
set RELEASE=%~1
for /f "delims=-" %%i in ('echo(%RELEASE:-=^&echo(%') do call set "PACKAGE=%%RELEASE:-%%i=%%"
for %%i in (%RELEASE:-= %) do set VERSION=%%i
exit /b

rem ------------------------------------------------------------------------------
rem
rem Check package source folder exists, from release variable passed as first parameter.
rem Parameter one is the package release variable.
rem Parameter two (optional) is any package sub-folder to the main CMakeLists.txt file.
rem
:check_package_source

call :get_package_details %~1

pushd %BUILD_BASE%\..\src
set SRC_DIR=!CD!\%~1
popd
if not "%~2" == "" (
  set SRC_DIR=!SRC_DIR!\%~2
)

if not exist "!SRC_DIR!" (
  echo Warning for package %~1
  echo Could not find package source folder "!SRC_DIR!"
  set STATUS=1
) else (
  cd /d "!SRC_DIR!"
  set STATUS=0
)
exit /b !STATUS!

rem ------------------------------------------------------------------------------
rem
rem Build subroutine.
rem Parameter one is the package release variable, used as a folder reference.
rem Parameter two is any required CMake options.
rem Parameter three (optional) is any package sub-folder to the main CMakeLists.txt file.
rem
:build_package

rem Check source folder exists, else exit.
rem
call :check_package_source %~1 %~3
if not !STATUS! == 0 (
  exit /b !STATUS!
) else (
  echo. & echo Building %~1
)

rem Check for CMakeLists.txt file in package named source folder.
rem
if not exist CMakeLists.txt (
  rem File not found, so attempt to install a reference copy from parent
  rem folder using a filename of the form "CMakeLists - %~1.txt"
  rem
  pushd %BUILD_BASE%\..\src
  if exist "CMakeLists - %~1.txt" (
    copy "CMakeLists - %~1.txt" !SRC_DIR!\CMakeLists.txt 1>nul 2>&1 & call :get_status
    if not !STATUS! == 0 (
      echo Failed to copy "!CD!\CMakeLists - %~1.txt"
      echo to "!SRC_DIR!\CMakeLists.txt"
      set STATUS=1 & exit /b !STATUS!
    )
  ) else (
    echo Could not find package CMakeLists.txt file "!SRC_DIR!\CMakeLists.txt"
    echo or reference CMakeLists.txt file "!CD!\CMakeLists - %~1.txt"
    set STATUS=1 & exit /b !STATUS!
  )
  popd
)

rem Clean up any previous build.
rem
if exist "%BUILD_BASE%\!PACKAGE!" rmdir /s /q "%BUILD_BASE%\!PACKAGE!" 1>nul 2>&1
mkdir "%BUILD_BASE%\!PACKAGE!" 1>nul 2>&1

rem Build, make and install.
rem
if exist "%BUILD_BASE%\!PACKAGE!" (
  cd /d "%BUILD_BASE%\!PACKAGE!"

  rem Patch CMakeLists.txt to remove debug suffix from libraries. Messes up various builds.
  rem Tried setting CMAKE_DEBUG_POSTFIX to an empty string on the CMake command line but
  rem this doesn't work with all packages, e.g. PCRE2, EXPAT, LIBXML2, etc.
  rem
  perl -pi -e ^" ^
    s~((DEBUG_POSTFIX^|POSTFIX_DEBUG^)\s+^)([\x22]*^)[-_]*(^|s^)d([\x22]*^)~${1}\x22${4}\x22~i; ^
    ^" "!SRC_DIR!\CMakeLists.txt"

  rem Patch CMakeLists.txt to put a CMAKE_MINIMUM_REQUIRED statement before the PROJECT
  rem statement, which is misplaced in some packages, e.g. APR-UTIL, HTTPD. Also change
  rem any CMAKE_MINIMUM_REQUIRED version which is set to 2.x, to %CMAKE_POL_VER_MIN%.
  rem This change is needed to remove CMake warnings including those about CMake policy
  rem CMP0054 not being set.
  rem
  perl -pi.bak -0777 -Mopen=OUT,:raw -e ^" ^
    s~(PROJECT[\h]*\(.+ C[\h]*\^)^)([\r\n^]+^)(CMAKE_MINIMUM_REQUIRED[\h]*\([\h]*VERSION[\h]+[0-9\.]+[\h]*\^)^)~${3}${2}${1}~smgi; ^
    s~(CMAKE_MINIMUM_REQUIRED[\h]*\([\h]*VERSION[\h]+^)2\.[0-9]+([\h]*\^)^)~${1}%CMAKE_POL_VER_MIN%${2}~smgi; ^
    ^" "!SRC_DIR!\CMakeLists.txt"

  rem Run CMake to create an NMake makefile, which we then process.
  rem
  %CMAKE% -G "NMake Makefiles" %~2 -S "!SRC_DIR!" -B . & call :get_status
  if !STATUS! == 0 (
    nmake & call :get_status
    if !STATUS! == 0 (
      nmake install & call :get_status
      if !STATUS! == 0 (
        exit /b !STATUS!
      ) else (
        echo nmake install for !PACKAGE! failed with exit status !STATUS!
        exit /b !STATUS!
      )
    ) else (
      echo nmake for !PACKAGE! failed with exit status !STATUS!
      exit /b !STATUS!
    )
  ) else (
    echo cmake for !PACKAGE! failed with exit status !STATUS!
    exit /b !STATUS!
  )
) else (
  echo Failed to make folder "%BUILD_BASE%\!PACKAGE!"
  exit /b 1
)
exit /b

rem ------------------------------------------------------------------------------
rem
rem Get best CMake version
rem
:get_best_cmake_version

rem Define variables for best version of CMake we can find.
rem
set BEST_CMAKE_VERSION=0.0.0
set BEST_CMAKE_PATH=

rem Check for more than one CMake in the search path and print a warning if found.
rem
for /f "usebackq" %%a in (`where cmake ^| find /v /c "" `) do (
  if %%a gtr 1 (
    echo.
    echo *** Note there is more than one version of CMake in your search path ***
    echo.
  )
)

rem Choose version of CMake to be used for the build.
rem Scan each instance of CMake found on the path.
rem
for /f "tokens=* usebackq" %%a in (`where cmake`) do (
  set NEXT=%%a

  rem Run CMake and extract version string.
  rem
  set cmdline="!NEXT!" --version
  for /f "usebackq delims=" %%b in (`cmd /c !cmdline! ^| findstr /i /c:"cmake version"`) do (
    set LINE_VER=%%b
  )

  rem Extract numeric version: remove "cmake version".
  rem
  for /f "tokens=3" %%v in ("!LINE_VER!") do set THIS_VER=%%v

  rem Compare versions numerically and update best version variables.
  rem
  call :is_version_newer "!THIS_VER!" "!BEST_CMAKE_VERSION!" RESULT
  if "!RESULT!" == "1" (
      set BEST_CMAKE_VERSION=!THIS_VER!
      set BEST_CMAKE_PATH=!NEXT!
  )
)

rem Chose CMake binary to be used for the build process.
rem
set CMAKE="!BEST_CMAKE_PATH!"

rem Split BEST_CMAKE_VERSION to get major and minor version numbers.
rem
for /f "tokens=1-2 delims=." %%a in ("!BEST_CMAKE_VERSION!") do (
    set CMAKE_MAJOR_VERSION=%%a
    set CMAKE_MINOR_VERSION=%%b
)
echo Best CMake path:    !BEST_CMAKE_PATH!
echo Best CMake version: !BEST_CMAKE_VERSION!
exit /b

rem ------------------------------------------------------------------------------
rem
rem  Compare two version strings A and B (e.g. 3.25.1)
rem  Returns RESULT=1 if A > B, otherwise RESULT=0
rem
:is_version_newer
setlocal

set A=%~1
set B=%~2

rem Split A.
rem
for /f "tokens=1-3 delims=." %%a in ("%A%") do (
    set A1=%%a
    set A2=%%b
    set A3=%%c
)

rem Split B.
rem
for /f "tokens=1-3 delims=." %%a in ("%B%") do (
    set B1=%%a
    set B2=%%b
    set B3=%%c
)

rem Default missing parts to zero.
rem
if "%A2%" == "" set A2=0
if "%A3%" == "" set A3=0
if "%B2%" == "" set B2=0
if "%B3%" == "" set B3=0

rem Compare major revision.
rem
if %A1% gtr %B1% (endlocal & set "%3=1" & exit /b)
if %A1% ltr %B1% (endlocal & set "%3=0" & exit /b)

rem Compare minor revision.
rem
if %A2% gtr %B2% (endlocal & set "%3=1" & exit /b)
if %A2% ltr %B2% (endlocal & set "%3=0" & exit /b)

rem Compare patch revision.
rem
if %A3% gtr %B3% (endlocal & set "%3=1" & exit /b)
if %A3% ltr %B3% (endlocal & set "%3=0" & exit /b)

rem Same version.
rem
endlocal & set "%3=0"
exit /b
Back to top
tangent
Moderator


Joined: 16 Aug 2020
Posts: 410
Location: UK

PostPosted: Thu 01 Jan '26 17:26    Post subject: Reply with quote

This HowTo previously focused on building ModSecurity as an additional module for Apache, but has been reworked to cover building a number of extra modules, currently tracking those listed on the downloads page https://www.apachelounge.com/download.
Back to top


Reply to topic   Topic: HOWTO: Building extra Apache modules using CMake View previous topic :: View next topic
Post new topic   Forum Index -> How-to's & Documentation & Tips