一个Xcode目标和普通目标的CMake区别

4
我有一段简单的C++11代码。
#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class A
{
    int x;
public:
    A() {}
    ~A() {}
    A(A& a) {}
    A(int x) {this->x = x;}
    int get() {return x;}
};

int main()
{
    vector<unique_ptr<A>> v;
    auto a = new A(10);
    unique_ptr<A> pa(a);
    v.push_back(move(pa)); // move(pa);

    auto a2 = new A(20);
    unique_ptr<A> pb(a2);
    v.push_back(move(pb)); // move(pa);

    for (auto& i: v)
    {
        cout << i->get();
    }
}

我正在尝试在Xcode和clang++上使用CMake设置构建此代码。

这是CMakeLists.txt文件:

cmake_minimum_required(VERSION 2.8)
project( testit )

set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")

set(testit
    testit.cpp
    )

add_executable(gv ${testit})

Clang++编译。

  1. 创建一个build文件夹并进入该文件夹
  2. export CC=/usr/bin/clang
  3. export CXX=/usr/bin/clang++
  4. cmake ..
  5. make

通过这些步骤可以得到正常工作的二进制文件。

Xcode 4.5目标

  1. 同样执行步骤1-3
  2. cmake .. -G Xcode
  3. xcodebuild

编译工作正常,但是在构建过程中出现了Undefined symbol错误。我用CMake中的以下命令设置了C++11:set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++").

Undefined symbols for architecture x86_64:
  "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
      void std::__1::vector<std::__1::unique_ptr<A, std::__1::default_delete<A> >, std::__1::allocator<std::__1::unique_ptr<A, std::__1::default_delete<A> > > >::__push_back_slow_path<std::__1::unique_ptr<A, std::__1::default_delete<A> > >(std::__1::unique_ptr<A, std::__1::default_delete<A> >&&) in testit.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(int)", referenced from:
      _main in testit.o
  "std::__1::cout", referenced from:
      _main in testit.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

可能出了什么问题?

新增

从这个链接来看,似乎 CMake 的 xbuildcode 目标设置有误: http://www.executionunit.com/blog/2012/10/27/xcode-std-link-errors/

新增

我已经修复了这个问题,但是必须使用与 CMakeLists.txt 文件位于同一目录下的相同目录。

Enter image description here

当我执行 CMake .. -G XCode 时,还遇到了另一个错误。

=== BUILD AGGREGATE TARGET ZERO_CHECK OF PROJECT XcodeTest WITH THE DEFAULT CONFIGURATION (Debug) ===
Check dependencies

PhaseScriptExecution "CMake Rules" build/XcodeTest.build/Debug/ZERO_CHECK.build/Script-BED7FB205C634C34A1ACD293.sh
    cd /Users/smcho/Desktop/cmake
    /bin/sh -c /Users/smcho/Desktop/cmake/build/XcodeTest.build/Debug/ZERO_CHECK.build/Script-BED7FB205C634C34A1ACD293.sh
echo ""

make -f /Users/smcho/Desktop/cmake/build/CMakeScripts/ReRunCMake.make
make[1]: *** No rule to make target `/Users/smcho/Desktop/cmake/build/CMakeFiles/2.8.10.2/CMakeCCompiler.cmake', needed by `CMakeFiles/cmake.check_cache'.  Stop.
make: *** [/Users/smcho/Desktop/cmake/build/CMakeFiles/ZERO_CHECK] Error 2
Command /bin/sh failed with exit code 2

** BUILD FAILED **

The following build commands failed:
    PhaseScriptExecution "CMake Rules" build/XcodeTest.build/Debug/ZERO_CHECK.build/Script-BED7FB205C634C34A1ACD293.sh

1
你是否也尝试向链接器传递-stdlib=libc++参数?set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++") - Fraser
@Fraser:谢谢,有了你的提示它可以工作了。 - prosseek
www.executionunit.com的链接已经失效(“未找到。无法定位所请求的项目。”)。 - Peter Mortensen
1个回答

4

有两个问题。

链接器选项

正如Fraser指出的那样,问题出在链接器的设置上。

...    
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
...

add_subdirectory

我不确定这是做什么的,但我需要在主CMakeLists.txt文件中使用add_subdirectory(src),并在该src目录中创建另一个CMakeLists.txt文件,以便在构建目录中运行CMake。如果没有它,我必须在与CMakeLists.txt文件位于同一目录中运行CMake。请参见Stack Overflow问题CMake Xcode generator creates a project that cannot build

这是src目录中的CMakeLists.txt:

set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
file ( GLOB SRCS *.cpp )
add_executable( program ${SRCS})

这是主目录下的CMakeLists.txt文件:

project( XcodeTest )
cmake_minimum_required( VERSION 2.6 )

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")

add_subdirectory(src)

我从这个YouTube视频中获得了提示:CMake XCode Demo 在此输入图片描述

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接