我正在尝试编译一个简单的测试项目,以确保我的所有工具,如CMake,Boost,Clang都能正常工作。
我想编译的源代码是LibLinkTest.cpp:
#include <boost/filesystem.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <assert.h>
using namespace boost::filesystem;
int main(int argc, char* argv[])
{
std::string str{"test passed"};
std::cout << str << std::endl;
boost::filesystem::path p{argv[1]};
try {
std::cout << p.string() << std::endl;
if (exists(p)) {
if (is_regular_file(p)) {
std::ifstream file{p.c_str()};
std::string line;
if (file.good() && file.is_open()) {
while (file >> line) {
std::cout << line << std::endl;
}
}
file.close();
} else if (is_directory(p)) {
std::cout << p.string() << " is a directory " << std::endl; // path stream inserter
} else
std::cout << p.string() << " exists, but is neither a regular file nor a directory" << std::endl;
}
else {
std::cout << p.string() << " does not exist" << std::endl;
}
}
catch (const filesystem_error& ex) {
std::cout << ex.what() << std::endl;
}
}
运行:
c++ -std=c++11 -I /usr/boost_1_54_0/boost/ LibLinkTest.cpp -o LibTest -L /usr/boost_1_54_0/lib/ -lboost_filesystem -lboost_system
编译得很好并且代码运行(带有seg错误,但我将单独解决)。
但是,我想在其他项目中使用CMake。尝试使用以下CMakeLists.txt编译LibLinkTest.cpp会导致链接错误。
CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
PROJECT(BoostTest CXX)
SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
FIND_PACKAGE(Boost 1.54.0 COMPONENTS filesystem system REQUIRED)
INCLUDE_DIRECTORIES(
${Boost_INCLUDE_DIR}
/usr/include/
/usr/include/c++/4.2.1/
)
ADD_EXECUTABLE(
LibTest
LibLinkTest.cpp
)
TARGET_LINK_LIBRARIES(LibTest boost_filesystem boost_system)
运行cmake ../
的输出是:
-- The CXX compiler identification is Clang 5.0.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Boost version: 1.54.0
-- Found the following Boost libraries:
-- filesystem
-- system
-- Configuring done
-- Generating done
最后运行make
会出现错误:
Scanning dependencies of target LibTest
[100%] Building CXX object CMakeFiles/LibTest.dir/LibLinkTest.cpp.o
Linking CXX executable LibTest
Undefined symbols for architecture x86_64:
"std::string::c_str() const", referenced from:
boost::system::system_error::what() const in LibLinkTest.cpp.o
boost::filesystem::path::c_str() const in LibLinkTest.cpp.o
"std::string::empty() const", referenced from:
boost::system::system_error::what() const in LibLinkTest.cpp.o
"std::basic_ios<char, std::char_traits<char> >::good() const", referenced from:
_main in LibLinkTest.cpp.o
似乎CMake中的设置不正确,也许是指向std c ++ lib的东西。有谁知道我如何正确配置CMake?
答案 0 :(得分:2)
我通过更改行解决了这个问题:
SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
到
SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libstdc++")
好像我刚刚在CMakeLists.txt中输入了一个拼写错误。
另外,有人知道为什么我需要设置这个标志吗?它是C ++ 11的东西吗?它似乎也解决了我在从命令行编译时遇到的seg错误的问题。
答案 1 :(得分:1)
您应该更改
行TARGET_LINK_LIBRARIES(LibTest boost_filesystem boost_system)
到
TARGET_LINK_LIBRARIES(LibTest ${Boost_LIBRARIES})
FIND_PACKAGE
命令将Boost_LIBRARIES
变量设置为您需要链接的变量。
答案 2 :(得分:0)
如果从输出中看到这两行
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
它告诉你它可能不是用于编译源代码的clang。例如,看它是否是
$ c++ --version
看看它实际上是什么编译器。如果它没有说清楚,你可能想要这样做。
$ ls -l /usr/bin/c++
如果它是符号链接,则检查链接(依此类推)。在我的系统(Ubuntu 13.10)上,文件/usr/bin/c++
是/etc/alternatives/c++
的符号链接,它是/usr/bin/g++
的符号链接,这意味着在我的系统上命令c++
实际上是GCC C ++编译器。
要确保使用clang,请重新设置cmake
命令(来自干净文件夹,之前未运行cmake
),并将环境变量CXX
设置为clang++
,例如
$ CXX=clang++ cmake path/to/folder/with/CMakeLists.txt
专业提示:创建一个单独的文件夹进行构建,然后从中运行cmake
。然后,如果需要,只需将其移除即可轻松清理它。