c++ - 使用 CMake 构建 zLib

标签 c++ qt cmake zlib quazip

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

由于 CI/CD 原因,我想这样做,如果其他人想要构建该项目,他不必担心这些依赖项(特别是在 Windows 下)...

  1. 在配置时使用 CMakeExternalProject_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 构建工程安装 header ...但是为什么;)因为没有地方调用 find_package...

最佳答案

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

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

我为 zlib 添加了一个附加的 CMakeLists.txt.in,它将替换原来的 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 的 header 添加到我的项目中,这是通过编辑 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
...

关于c++ - 使用 CMake 构建 zLib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58329956/

相关文章:

c++ - 如何为 noexcept 函数指针创建别名?

python - Django View 使用 PyQt 将 URL 转换为 PDF

c++ - 面向 Delphi 开发人员的 Qt

c++ - 'make' 的输出是共享对象,而不是可执行文件

build - 了解 CMake 背后的目的

c++ - 如何使用类型特征使这种数组到指针的转换明确?

c++ - 跟踪视频中的编号标记

c++ - 使用动态 boolean 数组的问题

c++ - QML 中 ListView 的问题

makefile - MinGW 尝试使用 CMake Makefiles 中的 cmd.exe