I have this simple C++11 code.
#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();
}
}
I'm trying to build this code with a CMake setup on Xcode and clang++.
This is the CMakeLists.txt file:
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++ build.
mkdir build and cd build
export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
cmake ..
make
I could get the binary that works fine.
Xcode 4.5 target
Same step 1-3
cmake .. -G Xcode
xcodebuild
Compilation works fine, but I got an error in the build with Undefined symbol error.
I setup C++11 with this command in CMake 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)
What might be wrong?
ADDED
From this link, it seems that the target setup is wrong with the xbuildcode from CMake:
http://www.executionunit.com/blog/2012/10/27/xcode-std-link-errors/
ADDED
I could fix this issue, but I had to use the same directory where the CMakeLists.txt file is located.
When I execute CMake .. -G XCode I got another error.
=== 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
There were two issues.
Linker option
As Fraser pointed out, the issue was from setup in the linker.
...
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
...
Add_subdirectory
I'm not sure why is this for, but I needed to use add_subdirectory(src) in the main CMakeLists.txt file, and make another CMakeLists.txt file in that src directory in order to run CMake in the build directory. Without it, I had to run CMake in the same directory where the CMakeLists.txt file is located. See Stack Overflow question CMake Xcode generator creates a project that cannot build
This is the CMakeLists.txt in the src directory:
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
file ( GLOB SRCS *.cpp )
add_executable( program ${SRCS})
This is the CMakeLists.txt in the main directory:
project( XcodeTest )
cmake_minimum_required( VERSION 2.6 )
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
add_subdirectory(src)
I got the hint from this YouTube video: CMake XCode Demo
Related
I am using cmake for the first time and was trying to add snappy-c to my c++ project. I compiled the snappy-c library using the Makefile in its repo. I was hoping that adding the snappy.o to my CMakeLists.txt would allow me to use the snappy library. Unfortunately, that gives me an undefined reference error.
How can I correctly add snappy-c to my c++ project?
My directory structure is
server-side
├── src
│── common_main.cpp
├── include
└── libs/snappy-c
This is my CMakeLists.txt file
cmake_minimum_required(VERSION 3.5)
add_definitions(-std=c++11)
# include public headers
include_directories("include" ${CMAKE_CURRENT_SOURCE_DIR}/libs/snappy-c)
# recursively add .cpp files to the SOURCES variable
file(GLOB_RECURSE SOURCES "src/*.cpp" main.cpp)
# create executable using SOURCES
add_executable(common-main ${SOURCES})
target_link_libraries(
common-main
${CMAKE_CURRENT_SOURCE_DIR}/libs/snappy-c/snappy.o
)
find_library(LIBRT rt)
if(LIBRT)
target_link_libraries(common-main ${LIBRT})
endif()
The code for which I get undefined reference is
#include <iostream>
#include "snappy.h"
int main(){
struct snappy_env env;
snappy_init_env(&env);
}
On running make VERBOSE=1, I get the following output
cd /home/kakashi/Workbench/project/build/server-side && /usr/bin/cmake -E cmake_link_script CMakeFiles/common-main.dir/link.txt --verbose=1
/usr/bin/c++ -pthread CMakeFiles/common-main.dir/src/common_main.cpp.o CMakeFiles/common-main.dir/src/server_service.cpp.o CMakeFiles/common-main.dir/src/service_manager.cpp.o -o common-main ../../server-side/libs/snappy.o /usr/lib/x86_64-linux-gnu/librt.so
CMakeFiles/common-main.dir/src/common_main.cpp.o: In function `main':
common_main.cpp:(.text+0x399): undefined reference to `snappy_init_env(snappy_env*)'
collect2: error: ld returned 1 exit status
server-side/CMakeFiles/common-main.dir/build.make:200: recipe for target 'server-side/common-main' failed
make[2]: *** [server-side/common-main] Error 1
.Makefile:83: recipe for target 'all' failed
.
.
.
.
I am trying to find a portable way of generating modules (dlopen, dlsym, dlerror, dlclose) with CMake.
The whole source code of my attempt is located here.
Here is the CMake script:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(dlopen_example CXX)
ADD_EXECUTABLE(main main.cpp print_ref.cpp)
TARGET_LINK_LIBRARIES(main dl)
ADD_LIBRARY(module MODULE module.cpp)
IF(APPLE)
SET_TARGET_PROPERTIES(module PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
ENDIF(APPLE)
As you may remark, I have to add
-undefined dynamic_lookup
to the set of link flags on Mac OSX (clang compiler). Indeed, while there is no problem on Linux Ubuntu, I get an error message on Mac OSX if I do not add this flag and let CMake handle flags with the line
ADD_LIBRARY(module MODULE module.cpp)
The error message I get is the following:
Undefined symbols for architecture x86_64:
"print_ref()", referenced from:
_module in module.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I am surprised that the MODULE option of ADD_LIBRARY does not handle such a flag.Is there a portable solution to this problem with CMake?
I got an issue when compiling glog by running 'make' after running './configure'
Then I got an error:
Undefined symbols for architecture x86_64:
"testing::internal::StrStreamToString(std::__1::basic_stringstream, std::__1::allocator >)", referenced from:
testing::internal::String testing::internal::StreamableToString(void const const&) in logging_unittest-logging_unittest.o
testing::internal::String testing::internal::StreamableToString(int const&) in logging_unittest-logging_unittest.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: * [logging_unittest] Error 1
I am using glog-0.3.3 on Mac OS X.
SO how can i turn of testing while compiling glog?
In another context, i installed glog and gflags by using Macport, then i run a small program. It will generate a error :
"ERROR: unknown command line flag 'logtostderr'"
I believe that's the problem with linking to gflags. So how can i fix it. Thanks
GLog needs GFlags compiled in the "google" namespace instead of the now default "gflags" namespace.
In order to set this namespace you must compile and install gflags from source and set the GFLAGS_NAMESPACE variable to "google".
Here are the steps I followed in Kubuntu 14.04 and should be similar to what you should do in Mac OSX. These will place the GFlags source in /usr/local/src and install the library in the /usr/local/lib&include directories. The last command (ldconfig) registers the library in the system.
cd /usr/local/src/
cp /path/to/downloaded/gflags-2.1.1.tar.gz .
sudo tar xzf gflags-2.1.1.tar.gz
cd /tmp
mkdir buildgflags
cd buildgflags
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_SHARED_LIBS=ON \
-DGFLAGS_NAMESPACE=google -G"Unix Makefiles" /usr/local/src/gflags-2.1.1/
make
sudo make install
sudo ldconfig
Alternatively you can apply the following patch in the GLog source (attached in the last reply):
https://code.google.com/p/google-glog/issues/detail?id=194
It basically uses the namespace of gflags after the includes on the GLogs unit test source files like so:
#ifdef HAVE_LIB_GFLAGS
#include <gflags/gflags.h>
using namespace gflags;
#endif
I am following this guide on how to build a project using GLFW3 with CMake on OSX 10.9.1, and I've run into some trouble. When I get to building the actual project I get the following errors:
$ make
Scanning dependencies of target Graphics
[100%] Building CXX object CMakeFiles/Graphics.dir/graphics.cpp.o
Linking CXX executable Graphics
Undefined symbols for architecture x86_64:
"_glBegin", referenced from:
_main in graphics.cpp.o
"_glClear", referenced from:
_main in graphics.cpp.o
"_glColor3f", referenced from:
_main in graphics.cpp.o
"_glEnd", referenced from:
_main in graphics.cpp.o
"_glLoadIdentity", referenced from:
_main in graphics.cpp.o
"_glMatrixMode", referenced from:
_main in graphics.cpp.o
"_glOrtho", referenced from:
_main in graphics.cpp.o
"_glRotatef", referenced from:
_main in graphics.cpp.o
"_glVertex3f", referenced from:
_main in graphics.cpp.o
"_glViewport", referenced from:
_main in graphics.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Graphics] Error 1
make[1]: *** [CMakeFiles/Graphics.dir/all] Error 2
make: *** [all] Error 2
My CMakeLists.txt looks like:
cmake_minimum_required (VERSION 2.8)
project (Graphics)
# The version number.
set (Graphics_VERSION_MAJOR 1)
set (Graphics_VERSION_MINOR 0)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/GraphicsConfig.h.in"
"${PROJECT_BINARY_DIR}/GraphicsConfig.h"
)
# add the binary tree to the search path for include files
# so that we will find GraphicsConfig.h
include_directories("${PROJECT_BINARY_DIR}")
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
include_directories(${GLFW_INCLUDE_DIRS})
# add the executable
add_executable (Graphics graphics.cpp)
target_link_libraries(Graphics ${GLFW_STATIC_LIBRARIES})
# add the install targets
install (TARGETS Graphics DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/GraphicsConfig.h"
DESTINATION include)
However can build the project just fine using
cc `pkg-config --cflags glfw3` -o graphics graphics.cpp \
`pkg-config --static --libs glfw3`
I can't offer you an explanation for why one links with the OpenGL libs and the other doesn't, but the following solution worked for me with a similar problem on OSX (Mountain Lion).
At the end of the 'add executable' block, add an Apple-specific condition to link with the OpenGL framework:
# add the executable
add_executable (Graphics graphics.cpp)
target_link_libraries(Graphics ${GLFW_STATIC_LIBRARIES})
if (APPLE)
target_link_libraries(Graphics "-framework OpenGL")
endif()
I figured there must be something in the GLFW CMake config that was responsible for linking with the OpenGL libs so I had a look at the GLFW 3.0.4 CMakeLists.txt and found that '-framework' line.
This will only help you on OSX - you'd need to supply other platform specific ways of linking to make it cross platform.
You may have already considered it, but the same guide also provides a way to include the GLFW source with your app and build it that way. That's probably the easiest way to guarantee cross-platform compatibility.
I had to do this.
elseif(APPLE)
# GLFW
find_package(glfw3 REQUIRED)
include_directories(${GLFW_INCLUDE_DIRS})
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
# app_framework executable
add_executable(app_framework ${SOURCE_FILES})
target_link_libraries(app_framework app_framework_library ${GLEW_LIBRARY} glfw3)
target_link_libraries(app_framework "-framework OpenGL")
Note that I use "glfw3" instead of ${GLFW_STATIC_LIBRARIES} in target_link_library. Did not work for me otherwise.
I'm using cmake 3.6.1.
Add this to your CMakeFile,
add_executable(${LOCAL_PROJECT_NAME} )
#openGL Specific
target_link_libraries(${LOCAL_PROJECT_NAME} ${GLFW_STATIC_LIBRARIES})
find_package(glfw3 3.3 REQUIRED)
target_link_libraries(${LOCAL_PROJECT_NAME} glfw)
find_package(OpenGL REQUIRED)
target_link_libraries(${LOCAL_PROJECT_NAME} OpenGL::GL)
also, make sure compiler options are set accordingly.
Steps:
1. sudo port boost
The boost file installed in /opt/local/boost, library files are in /opt/local/lib
2. use XCode to create c++ project
#include <iostream>
#include <boost/asio.hpp>
int main () {
return 0;
}
3. set XCode to find out boost
in "Build Settings" -> "HEADER_SEARCH_PATHS"
in both Debug and Release add path /opt/local/include
4. "Build Settings" -> "LIBRARY_SEARCH_PATHS" --> add /opt/local/lib both for debug and release.
5. build program and failed.
Error Messages,
Undefined symbols for architecture x86_64:
"boost::system::generic_category()", referenced from:
___cxx_global_var_init1 in main.o
___cxx_global_var_init2 in main.o
"boost::system::system_category()", referenced from:
___cxx_global_var_init3 in main.o
boost::asio::error::get_system_category() in main.o
"boost::asio::error::get_netdb_category()", referenced from:
___cxx_global_var_init5 in main.o <br>
"boost::asio::error::get_addrinfo_category()", referenced from:
___cxx_global_var_init6 in main.o <br>
"boost::asio::error::get_misc_category()", referenced from:
___cxx_global_var_init7 in main.o <br>
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Am I wrong in the procedure?
You need to link with Boost.System, which should be in /opt/local/lib/libboost_system (with some suffix, that depends on how you built boost)
Add that to your Xcode project.
select on your "targets"
in "Link Binary with libraries" section under "build phases" tab, add boost library.
if install via MacPort, the boost will be at /opt/local/lib,
if install via brew, the boost will be at /usr/local/Cellar/boost ,
if build by yourself, it will be at /usr/local/lib by default or yourBoostLib/stage/lib