2

我正在尝试使用我的项目的其余部分自动构建 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。(链接) 他们将源和二进制文件夹的所有内容添加到包含以下内容:

include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})

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

编辑

如果我安装带有 apt 构建作品的标题...但是为什么;)因为没有地方调用 find_package...

4

1 回答 1

3

感谢@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 的标头添加到我的项目中,方法是编辑 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
...
于 2019-10-11T09:00:43.887 回答