使用PCRE库的Cmake ExternalProject_Add不适用于NMake Generator

时间:2016-02-24 17:09:38

标签: c++ build cmake makefile nmake

我正在尝试构建PCRE库作为更大版本的一部分。我的工作设置在Ubuntu上找到了CMake 3.2.2和ninja或make,CMake 3.3.2在使用Mingw32-make或ninja的TDM-GCC的窗口上,但在使用带有visual studio 2015编译器的NMake时失败了。在添加我在下面描述的代码之前,构建在所有这些平台上工作。

我使用" ExternalProject_Add"为此构建创建目标。以下是我设置一些变量并设置外部项目的部分。为简洁起见,我删除了几条消息语句。 LibFolder 是源树中的一个文件夹, ProjectBinaryDir 在我的输出文件夹中。

set(PcreSrcDir "${LibFolder}pcre-8.38/")
set(PcreLibDir "${ProjectBinaryDir}PCRE-prefix/src/PCRE-build/")

set(PcreCppLib "${CMAKE_STATIC_LIBRARY_PREFIX}pcrecpp${CMAKE_STATIC_LIBRARY_SUFFIX}")
#set(PcreLib "${CMAKE_STATIC_LIBRARY_PREFIX}pcre${CMAKE_STATIC_LIBRARY_SUFFIX}")
#set(PcrePosixLib "${CMAKE_STATIC_LIBRARY_PREFIX}pcre${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(PcreLibs "${PcreLibDir}${PcreCppLib}")

set(PcreIncludeDirs "${PcreSrcDir}" "${PcreLibDir}")

include(ExternalProject)
ExternalProject_Add(
  PCRE
  SOURCE_DIR "${PcreSrcDir}"
  INSTALL_COMMAND ""
  BUILD_BYPRODUCTS "${PcreLibs}"
)

我稍后使用 PcreIncludeDirs 使用 include_directories 命令,这看似起作用我在任何构建期间都没有得到与查找标题相关的警告或错误。

我使用 PcreLibs 和目标名称​​ PCRE 来设置PCRE库与我构建的其他库和可执行文件之间的依赖关系。下面是一个示例, LibrarySource 是本示例中库的源文件数组, ProjectDynamicLib 是正在构建的So / Dll的名称:

add_library(${ProjectDynamicLib} SHARED "${LibrarySource}")
target_link_libraries(${ProjectDynamicLib} "${PcreLibs}")
add_dependencies(${ProjectDynamicLib} PCRE)

这再次与Make和Ninja相得益彰,但是却失败了。构建编译PCRE和我的大部分C ++代码,然后当链接到它时失败并出现以下错误:

NMAKE : fatal error U1073: don't know how to make 'PCRE-prefix\src\PCRE-build\pcrecpp.lib'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe"' : return code '0x2'
Stop.

起初我担心库名称省略了构建目录的绝对PATH。所以我尝试了几种方法调整名称,包括反转所有斜杠以使它们更友好,并将库名称作为 target_link_libraries 的相对路径传递。我输出每个相关的变量,所以我可以手动检查它们,我检查了库是构建的,我发现它们在属于Windows资源管理器的文件夹中。我尝试了一些其他无用的傻事。

为什么这会破坏使用NMake和msvc,但是在使用Mingw和GCC时使用Make,Ninja,Mingw32-make?

1 个答案:

答案 0 :(得分:0)

我正在手动修补PCRE构建,并发现它在不同版本中发出名称略有不同的二进制文件。我再次查看了我的输出目录,在我的msvc版本中,我注意到PCRE静态库有一个额外的" d"在名字里。所以他们是" pcrecppd.lib"," pcred.lib"和" pcreposixd.lib"。

我知道有些构建过程会这样做,以允许调试和发布版本在同一个构建目录中共存。所以我通过查看 CMakeCache.txt

来检查这是否是一个调试版本

工作构建 - CMakeCache的第17行到第20行:

//Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
// CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.
CMAKE_BUILD_TYPE:STRING=RELEASE

构建失败 - CMakeCache的第17到20行:

//Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
// CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.
CMAKE_BUILD_TYPE:STRING=DEBUG

假设这是我的问题,我决定将外部项目设置为仅在发布模式下构建。我们可以在需要调试regex库的不太可能的情况下将其设置为手动调试。我使用了ExternalProject cmake documentation页面上描述的CMAKE_ARGS。

include(ExternalProject)
ExternalProject_Add(
  PCRE
  SOURCE_DIR "${PcreSrcDir}"
  INSTALL_COMMAND ""
  BUILD_BYPRODUCTS "${PcreLibs}"
  *CMAKE_ARGS "-DCMAKE_BUILD_TYPE:STRING=Release"*
)

我删除了整个构建文件夹(以确保干净状态并避免因手动修补而受到污染)并使用cmake重新配置并重建软件。这次它构建和链接没有错误。

我仍然不知道为什么vs和nmake选择构建调试而其他工具链默认发布,我也不知道有多少" D"是PCRE,vs或nmake或CMake的错。