使用 CMake 构建 zLib

Build zLib with CMake

我正在尝试用我的项目的其余部分自动构建 Zlib 和 quazip。我想以与将 googletest 添加到我的项目中类似的方式进行操作。 zLib 和 Quazip 应静态链接到我的应用程序。

我想这样做是因为 CI/ CD 原因,如果其他人想要构建项目,他不必担心这些依赖项(尤其是在 windows 下)...

  1. 在配置时使用 CMake 下载它 ExternalProject_Add
  2. 将其添加到目标级别

我的结构如下:

project/
├── CMakelists.txt (1)
├── sources/
│   ├── APP/
│   │   ├── CMakeLists.txt (2)
│   │   ├── thirdparty/
│   │   │   ├── CMakeLists.txt (3)
│   │   │   ├── zlib
│   │   │   │   ├── CMakeLists.txt.in
│   │   │   ├── quazip
│   │   │   │   ├── CMakeLists.txt.in
│   │   │   │   ├── CMakeListsBuild.txt.in

这已经够复杂了,但让我告诉你我在哪里做什么...

(1) CMakeLists.txt

注意只是像 APP 一样把所有的包加在一起

(2) CMakeLists.txt

cmake_minimum_required(VERSION 3.15.2)

project(Project VERSION 0.0.1)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

#Add the needed Qt Components
find_package(Qt5 COMPONENTS
                            Core
                            Network
                            REQUIRED)

add_subdirectory(thirdparty) 

SET(INCLUDES
    ...
    )

SET(SOURCES
    ...
    )

target_compile_options(${PROJECT_NAME}  PUBLIC
                                        ...
                                        )

target_compile_definitions(${PROJECT_NAME} PUBLIC
                                                    QUAZIP_STATIC )

target_include_directories(${PROJECT_NAME} PRIVATE
    OtherIncludes
    "${QUAZIP_INCLUDE_DIR}"
    )

target_link_libraries(${PROJECT_NAME}
    Qt5::Network
    Qt5::Core
    SomeOtherDep
    quazip_static  <---- adding static targets here
    zlibstatic     <---- adding static targets here
    )

(3) CMakeLists.txt

# Download and unpack at configure time
configure_file(zlib/CMakeLists.txt.in zlib-download/CMakeLists.txt)

execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/zlib-download"
)
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/zlib-download"
)

add_subdirectory("${CMAKE_BINARY_DIR}/zlib-src"
                 "${CMAKE_BINARY_DIR}/zlib-build"
)

# Download and unpack at configure time
configure_file(quazip/CMakeLists.txt.in quazip-download/CMakeLists.txt)

execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/quazip-download"
)
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/quazip-download"
)

configure_file(quazip/CMakeListsBuild.txt.in ${CMAKE_BINARY_DIR}/quazip-src/CMakeLists.txt COPYONLY)

add_subdirectory("${CMAKE_BINARY_DIR}/quazip-src"
                 "${CMAKE_BINARY_DIR}/quazip-build"
)

set(QUAZIP_INCLUDE_DIR
                "${CMAKE_BINARY_DIR}/quazip-src/quazip" PARENT_SCOPE)

两个CMakeLists.txt.in的内容几乎一样...

cmake_minimum_required(VERSION 2.8.2)

include(ExternalProject)

project(quazip-download NONE)

ExternalProject_Add(quazip
    GIT_REPOSITORY git://github.com/stachenov/quazip.git
    GIT_TAG v0.8.1
    SOURCE_DIR "${CMAKE_BINARY_DIR}/quazip-src"
    BINARY_DIR "${CMAKE_BINARY_DIR}/quazip-build"
    CONFIGURE_COMMAND ""
    BUILD_COMMAND ""
    INSTALL_COMMAND ""
    TEST_COMMAND ""
)
cmake_minimum_required(VERSION 2.8.2)

include(ExternalProject)

project(zlib-download NONE)

ExternalProject_Add(zlib
    GIT_REPOSITORY git://github.com/madler/zlib.git
    GIT_TAG v1.2.11
    SOURCE_DIR "${CMAKE_BINARY_DIR}/zlib-src"
    BINARY_DIR "${CMAKE_BINARY_DIR}/zlib-build"
    CONFIGURE_COMMAND ""
    BUILD_COMMAND ""
    INSTALL_COMMAND ""
    TEST_COMMAND ""
)

然后是quazip文件夹中的最后一个CMakeListsBuild.txt.in。我只是编辑原始的,直接将 zlib 依赖项提供进去。它看起来像这样:

cmake_minimum_required(VERSION 2.6)
project(QuaZip)

...
EVERYTHING ORIGINAL 
...
# Use system zlib on unix and Qt ZLIB on Windows
# will be set from outside ZLIB_LIBRARIES ZLIB_INCLUDE_DIRS
--------------------ADDED BY ME REMOVED find_packages...
set(ZLIB_INCLUDE_DIRS   ${CMAKE_BINARY_DIR}/zlib-src
                        ${CMAKE_BINARY_DIR}/zlib-build)
if(UNIX)
    set(ZLIB_LIBRARIES
                    "${CMAKE_BINARY_DIR}/zlib-build/libz.a")
elseif(MINGW)
    set(ZLIB_LIBRARIES
                    "${CMAKE_BINARY_DIR}/zlib-build/libzlibstatic.a")
endif()


...
EVERYTHING ORIGINAL 
...

问题

下载并构建 zlib 的静态库有效,但在 linux 下编译时出现以下错误。

/home/linuxmint/someDirectory/build/zlib-src/test/example.c:8:10: fatal error: zlib.h: No such file or directory
 #include "zlib.h"
          ^~~~~~~~
compilation terminated.
zlib-build/CMakeFiles/example.dir/build.make:75: recipe for target 'zlib-build/CMakeFiles/example.dir/test/example.o' failed
make[2]: *** [zlib-build/CMakeFiles/example.dir/test/example.o] Error 1
CMakeFiles/Makefile2:1355: recipe for target 'zlib-build/CMakeFiles/example.dir/all' failed
make[1]: *** [zlib-build/CMakeFiles/example.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....

这是我不明白的奇怪部分。如果我看一下 zlib 的 CMakeLists。 (LINK) 他们将源和二进制文件夹的所有内容添加到包含:

include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})

所以我不明白为什么不能构建 zlib 示例(以及其他所有需要 zlib.h 的示例)... 也许有人有暗示...... 谢谢...

编辑

如果我使用 apt building works 安装 headers...但是为什么 ;) 因为没有地方调用 find_package...

感谢@squarekittles 为我指明了正确的方向。

在 zlib 的 CMakeLists.txt 中,包含目录指定为 ${CMAKE_SOURCE_DIR}。这当然是错误的目录...

我为 zlib 添加了一个额外的 CMakeLists.txt.in,它将取代原来的。都是一样的,只有两行不同:

...
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
                                                        ^~~~~~~~~~~~~ Added in


#============================================================================
# zlib
#============================================================================

set(ZLIB_PUBLIC_HDRS
    ${CMAKE_CURRENT_BINARY_DIR}/zconf.h
    ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h
)     ^~~~~~~~~~~~~ Added in

...

现在示例编译... 我还需要将 zlib 的 headers 添加到我的项目中,方法是编辑 CMakeLists.txt (3)

...
configure_file(zlib/CMakeListsBuild.txt.in ${CMAKE_BINARY_DIR}/zlib-src/CMakeLists.txt COPYONLY) <--- Replacing CMakeLists.txt for zlib
...

set(QUAZIP_INCLUDE_DIR
                "${CMAKE_BINARY_DIR}/quazip-src/quazip" 
                ${ZLIB_INCLUDE_DIR} PARENT_SCOPE)
                  ^~~~~~~~~~~~ Added in
...