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

cmake: mimic behavior of Makefile properly. Add test to be sure. #5

Closed
wants to merge 8 commits into from
13 changes: 4 additions & 9 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ check_ubu1804_task:
container:
dockerfile: tooling/cirrus/ubu1804/Dockerfile
test_script:
- cc --version
- mkdir btmp; cd btmp; cmake -G Ninja .. && ninja && ctest -V
- sh tooling/test-cmake.sh && sh tooling/pkgcheck.sh
always:
junit_artifacts:
path: "btmp/*-results.xml"
Expand All @@ -14,8 +13,7 @@ check_ubu2004_task:
container:
dockerfile: tooling/cirrus/ubu2004/Dockerfile
test_script:
- cc --version
- mkdir btmp; cd btmp; cmake -G Ninja .. && ninja && ctest -V
- sh tooling/test-cmake.sh && sh tooling/pkgcheck.sh
always:
junit_artifacts:
path: "btmp/*-results.xml"
Expand All @@ -28,9 +26,7 @@ check_mac_task:
install_script:
- brew install ninja
test_script:
- cc --version
- ninja --version
- mkdir btmp; cd btmp; cmake -G Ninja .. && cmake --build . && ctest -V
- sh tooling/test-cmake.sh && sh tooling/pkgcheck.sh
always:
junit_artifacts:
path: "btmp/*-results.xml"
Expand All @@ -43,8 +39,7 @@ check_bsd_task:
install_script:
- pkg install -y gcc cmake ninja
test_script:
- cc --version
- mkdir btmp; cd btmp; cmake -G Ninja .. && ninja && ctest -V
- sh tooling/test-cmake.sh && sh tooling/pkgcheck.sh
always:
junit_artifacts:
path: "btmp/*-results.xml"
Expand Down
98 changes: 79 additions & 19 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)

project(zlib C)

# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
"\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
MESSAGE("ZLIB_FULL_VERSION=${ZLIB_FULL_VERSION}")
# FIXME: parse this from ZLIB_FULL_VERSION
set(VERSION "1.2.11.1")

option(ASM686 "Enable building i686 assembly implementation")
Expand All @@ -12,7 +18,16 @@ set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation direc
set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries")
set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers")
set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages")
set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
set(INSTALL_PKGCONFIG_DIR "${INSTALL_LIB_DIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")

# Set a default build type if none was specified
set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

include(CheckTypeSize)
include(CheckFunctionExists)
Expand All @@ -23,6 +38,33 @@ enable_testing()
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(stddef.h HAVE_STDDEF_H)
check_include_file(stdarg.h HAVE_STDARG_H)
check_include_file(unistd.h HAVE_UNISTD_H)

#
# Match configure's zconf.h exactly
#
if (HAVE_STDARG_H)
SET(ZCONF_STDARG_LINE "#if 1 /* was set to #if 1 by ./configure */")
else()
SET(ZCONF_STDARG_LINE "#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */")
endif()
if (HAVE_UNISTD_H)
SET(ZCONF_UNISTD_LINE "#if 1 /* was set to #if 1 by ./configure */")
else()
SET(ZCONF_UNISTD_LINE "#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */")
endif()

#
# Check to see if compiler supports __attribute__((visibility ("hidden")))
#
check_c_source_compiles(
"int __attribute__((visibility (\"hidden\"))) foo; int main() { return foo; }"
HAVE_HIDDEN
)
if(HAVE_HIDDEN)
add_definitions(-DHAVE_HIDDEN)
endif()

#
# Check to see if we have large file support
Expand Down Expand Up @@ -54,11 +96,6 @@ if(NOT HAVE_FSEEKO)
add_definitions(-DNO_FSEEKO)
endif()

#
# Check for unistd.h
#
check_include_file(unistd.h Z_HAVE_UNISTD_H)

if(MSVC)
set(CMAKE_DEBUG_POSTFIX "d")
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
Expand All @@ -78,6 +115,19 @@ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
endif()
endif()

# Refer to prefix symbolically to ease relocation by end user,
# and match Makefile-generate .pc file exactly.
if(INSTALL_INC_DIR STREQUAL "${CMAKE_INSTALL_PREFIX}/include")
set(PC_INSTALL_INC_DIR "\${prefix}/include")
else()
set(PC_INSTALL_INC_DIR "${INSTALL_INC_DIR}")
endif()
if(INSTALL_LIB_DIR STREQUAL "${CMAKE_INSTALL_PREFIX}/lib")
set(PC_INSTALL_LIB_DIR "\${exec_prefix}/lib")
else()
set(PC_INSTALL_LIB_DIR "${INSTALL_LIB_DIR}")
endif()

set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein
${ZLIB_PC} @ONLY)
Expand Down Expand Up @@ -105,22 +155,27 @@ set(ZLIB_PRIVATE_HDRS
trees.h
zutil.h
)

# Note: keep these in the same order as in Makefile.in
# This allows libz.so to be identical between the two build systems.
set(ZLIB_SRCS
# Makefile.in: PIC_OBJZ
adler32.c
compress.c
crc32.c
deflate.c
gzclose.c
gzlib.c
gzread.c
gzwrite.c
inflate.c
infback.c
inftrees.c
inffast.c
inflate.c
inftrees.c
trees.c
uncompr.c
zutil.c
# Makefile.in: PIC_OBJG
compress.c
uncompr.c
gzclose.c
gzlib.c
gzread.c
gzwrite.c
)

if(NOT MINGW)
Expand Down Expand Up @@ -162,11 +217,6 @@ if(MSVC)
endif()
endif()

# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
"\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})

if(MINGW)
# This gets us DLL resource information when compiling on MinGW.
if(NOT CMAKE_RC_COMPILER)
Expand Down Expand Up @@ -199,6 +249,16 @@ if(NOT CYGWIN)
set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
endif()

if(APPLE)
set_target_properties(zlib PROPERTIES
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
)
elseif (UNIX)
# Makefile.in uses -lc...
set(LDSHAREDLIBC -lc)
target_link_libraries(zlib ${LDSHAREDLIBC})
endif()

if(UNIX)
# On unix-like platforms the library is almost always called libz
set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z)
Expand Down
2 changes: 1 addition & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ if test $SRCDIR = "."; then
ZINCOUT="-I."
SRCDIR=""
else
ZINC='-include zconf.h'
ZINC='-I. -include zconf.h'
ZINCOUT='-I. -I$(SRCDIR)'
SRCDIR="$SRCDIR/"
fi
Expand Down
2 changes: 1 addition & 1 deletion tooling/cirrus/ubu1804/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM ubuntu:18.04

RUN apt-get update && \
apt-get install --no-install-recommends -y cmake gcc libc6-dev ninja-build && \
apt-get install --no-install-recommends -y cmake gcc libc6-dev ninja-build make && \
apt-get clean
2 changes: 1 addition & 1 deletion tooling/cirrus/ubu2004/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM ubuntu:20.04

RUN apt-get update && \
apt-get install --no-install-recommends -y cmake gcc libc6-dev ninja-build && \
apt-get install --no-install-recommends -y cmake gcc libc6-dev ninja-build make && \
apt-get clean
83 changes: 83 additions & 0 deletions tooling/pkgcheck.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/bin/sh
# Verify that the various build systems produce identical results on a Unixlike system
set -ex

# Tell GNU's ld etc. to use Jan 1 1970 when embedding timestamps
export SOURCE_DATE_EPOCH=0
# Tell Apple's ar etc. to use zero timestamps
export ZERO_AR_DATE=1

# Original build system
rm -rf btmp1 pkgtmp1
mkdir btmp1 pkgtmp1
export DESTDIR=$(pwd)/pkgtmp1
cd btmp1
case $(uname) in
Darwin)
# Tell configure which compiler etc. to use to match cmake
# Tell configure to pad the executable the same way cmake will
CC="$(xcrun --find gcc || echo gcc)" \
CFLAGS="-DNDEBUG -O3 -isysroot $(xcrun --show-sdk-path)" \
LDFLAGS="-Wl,-headerpad_max_install_names" \
../configure
;;
FreeBSD)
# 1) tell configure to tell ar to be deterministic?
# 2) configure fails with cc, so use clang or gcc
# 3) Force same CC for configure and clang
#export ARFLAGS="Drc"
if clang --version
then
export CC=clang
../configure
elif gcc --version
then
export CC=gcc
../configure
else
# will probably fail
../configure
fi
;;
*)
../configure
;;
esac
make
make install
cd ..

# New build system
rm -rf btmp2 pkgtmp2
mkdir btmp2 pkgtmp2
export DESTDIR=$(pwd)/pkgtmp2
cd btmp2
cmake -G Ninja ..
ninja -v
ninja install
cd ..

case $(uname) in
Darwin)
# Alas, dylibs still have an embedded hash or something,
# so nuke it. There's probably a better way.
dylib1=$(find pkgtmp1 -name '*.dylib*' -type f)
dylib2=$(find pkgtmp2 -name '*.dylib*' -type f)
dd conv=notrunc if=/dev/zero of=$dylib1 skip=1337 count=16
dd conv=notrunc if=/dev/zero of=$dylib2 skip=1337 count=16
;;
FreeBSD)
# I had trouble passing -D to the ar inside CMakeLists.txt,
# so punt and unpack the archive before comparing.
cd pkgtmp1; ar x usr/local/lib/libz.a; rm usr/local/lib/libz.a; cd ..
cd pkgtmp2; ar x usr/local/lib/libz.a; rm usr/local/lib/libz.a; cd ..
;;
esac

if diff -Nur pkgtmp1 pkgtmp2
then
echo pkgcheck-cmake-bits-identical PASS
else
echo pkgcheck-cmake-bits-identical FAIL
exit 1
fi
11 changes: 11 additions & 0 deletions tooling/test-cmake.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh
# Build and test with CMake
set -ex

rm -rf btmp
mkdir btmp
cd btmp
cmake -G Ninja ..
ninja
ctest -V
cd ..
11 changes: 11 additions & 0 deletions tooling/test-make.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh
# Build and test with Make
set -ex

rm -rf btmp
mkdir btmp
cd btmp1
../configure
make
make test
cd ..
6 changes: 2 additions & 4 deletions zconf.h.cmakein
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

#ifndef ZCONF_H
#define ZCONF_H
#cmakedefine Z_PREFIX
#cmakedefine Z_HAVE_UNISTD_H

/*
* If you *really* need a unique prefix for all types and library functions,
Expand Down Expand Up @@ -433,11 +431,11 @@ typedef uLong FAR uLongf;
typedef unsigned long z_crc_t;
#endif

#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
@ZCONF_UNISTD_LINE@
# define Z_HAVE_UNISTD_H
#endif

#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
@ZCONF_STDARG_LINE@
# define Z_HAVE_STDARG_H
#endif

Expand Down
10 changes: 5 additions & 5 deletions zlib.pc.cmakein
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@INSTALL_LIB_DIR@
sharedlibdir=@INSTALL_LIB_DIR@
includedir=@INSTALL_INC_DIR@
exec_prefix=${prefix}
libdir=@PC_INSTALL_LIB_DIR@
sharedlibdir=${libdir}
includedir=@PC_INSTALL_INC_DIR@

Name: zlib
Description: zlib compression library
Version: @VERSION@
Version: @ZLIB_FULL_VERSION@

Requires:
Libs: -L${libdir} -L${sharedlibdir} -lz
Expand Down