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
.
.
.
.
Related
I am making a game in SDL2 and C++. I use a makefile with mingw32 in visual stuido code. Because I am using SDL2 I want to use the SDL2 dll's. It works with all the dll's in the main project directory but not if I put them in the folder they are supposed to be in.
This is my make file:
all:
g++ -o main main.cpp entity.cpp entity.hpp player.cpp player.hpp -Isrc/Include -Lsrc/lib -lmingw32 -lSDL2main -lSDL2 -lSDL2_image
When I open the .exe that was made with the make command:
I do not get any errors when I make the .exe, but when I try to open it this is what I get. As stated above, these problems do not affect me if I have all the dll's in the main directory.
If I change the makefile to contain the directory of the dll's I get errors when trying to make the exe.:
g++ -o main main.cpp entity.cpp entity.hpp player.cpp player.hpp -Isrc/Include -Lsrc/lib -lmingw32 -lsrc/lib/SDL2main -lsrc/lib/SDL2 -lsrc/lib/SDL2_image
D:/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lsrc/lib/SDL2main
D:/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lsrc/lib/SDL2
D:/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lsrc/lib/SDL2_image
collect2.exe: error: ld returned 1 exit status
make: *** [all] Error 1
Before anything, I just want to say I am very new to CMAKE, almost never used it but now forced to...
I am trying to include snmp features in a previous project, using Net-SNMP library. But first, I wrote a minimalistic code just to test my functions. According to the library tutorial, this is how I must compile the code:
First, I must create object file:
gcc -I. `net-snmp-config --cflags` -c -o tfsnmpset.o tfsnmpset.c
Then, I must generate the executable:
gcc -o tfsnmpset tfsnmpset.o `net-snmp-config --libs`
By doing this, the program compiles perfectly and everything is fine.
Now the project in which I want to incorporate that piece of code uses CMakeLists.txt to generate its makefile.
My question is, how do I include the following flags in my CMakeLists.txt?
When creating object files: `net-snmp-config --cflags`
When generating executable: `net-snmp-config --libs`
I actually tried to build a library out of my code that uses Net-SNMP that I could just use in my main project:
cmake_minimum_required(VERSION 3.12)
project(snmp_daemon C)
set(CMAKE_C_STANDARD 99)
SET(CMAKE_C_COMPILER /usr/bin/gcc)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I. `net-snmp-config --cflags`" )
add_library(tfsnmpset tfsnmp.c tfsnmp.h)
add_executable(snmp_daemon main.c ./tfsnmp.h)
target_link_libraries(snmp_daemon tfsnmpset)
The errors:
/media/user/xtra/apps/clion-2018.2.1/bin/cmake/linux/bin/cmake --build /home/fabrice/projects/snmp-daemon/cmake-build-debug --target snmp_daemon -- -j 2
[ 25%] Linking C static library libtfsnmpset.a
[ 50%] Built target tfsnmpset
[ 75%] Linking C executable snmp_daemon
libtfsnmpset.a(tfsnmp.c.o): In function `tfsnmpset':
/home/user/projects/snmp-daemon/tfsnmp.c:121: undefined reference to `snmp_parse_args'
/home/user/projects/snmp-daemon/tfsnmp.c:147: undefined reference to `snmp_get_do_debugging'
/home/user/projects/snmp-daemon/tfsnmp.c:147: undefined reference to `debugmsgtoken'
/home/user/projects/snmp-daemon/tfsnmp.c:147: undefined reference to `debugmsg'
/home/user/projects/snmp-daemon/tfsnmp.c:147: undefined reference to `debugmsgtoken'
/home/user/projects/snmp-daemon/tfsnmp.c:147: undefined reference to `debugmsg'
/home/user/projects/snmp-daemon/tfsnmp.c:194: undefined reference to `snmp_open'
/home/user/projects/snmp-daemon/tfsnmp.c:199: undefined reference to `snmp_sess_perror'
/home/user/projects/snmp-daemon/tfsnmp.c:207: undefined reference to `snmp_pdu_create'
/home/user/projects/snmp-daemon/tfsnmp.c:210: undefined reference to `snmp_parse_oid'
/home/user/projects/snmp-daemon/tfsnmp.c:211: undefined reference to `snmp_perror'
/home/user/projects/snmp-daemon/tfsnmp.c:214: undefined reference to `snmp_add_var'
/home/user/projects/snmp-daemon/tfsnmp.c:216: undefined reference to `snmp_perror'
/home/user/projects/snmp-daemon/tfsnmp.c:222: undefined reference to `snmp_close'
/home/user/projects/snmp-daemon/tfsnmp.c:230: undefined reference to `snmp_synch_response'
/home/user/projects/snmp-daemon/tfsnmp.c:236: undefined reference to `print_variable'
/home/user/projects/snmp-daemon/tfsnmp.c:239: undefined reference to `snmp_errstring'
/home/user/projects/snmp-daemon/tfsnmp.c:247: undefined reference to `fprint_objid'
/home/user/projects/snmp-daemon/tfsnmp.c:257: undefined reference to `snmp_sess_perror'
/home/user/projects/snmp-daemon/tfsnmp.c:262: undefined reference to `snmp_free_pdu'
/home/user/projects/snmp-daemon/tfsnmp.c:263: undefined reference to `snmp_close'
collect2: error: ld returned 1 exit status
CMakeFiles/snmp_daemon.dir/build.make:84: recipe for target 'snmp_daemon' failed
make[3]: *** [snmp_daemon] Error 1
CMakeFiles/Makefile2:72: recipe for target 'CMakeFiles/snmp_daemon.dir/all' failed
make[2]: *** [CMakeFiles/snmp_daemon.dir/all] Error 2
CMakeFiles/Makefile2:84: recipe for target 'CMakeFiles/snmp_daemon.dir/rule' failed
make[1]: *** [CMakeFiles/snmp_daemon.dir/rule] Error 2
Makefile:118: recipe for target 'snmp_daemon' failed
make: *** [snmp_daemon] Error 2
You should link to snmp libraries
find_library(NETSNMPAGENT "netsnmpagent")
find_library(NETSNMPMIBS "netsnmpmibs")
find_library(NETSNMP "netsnmp")
target_link_libraries(snmp_daemon tfsnmpset ${NETSNMPAGENT} ${NETSNMPMIBS} ${NETSNMP})
I would liket to add ffmpeg to Clion but I have some problems with it.
My MakeLists.txt looks liek this:
cmake_minimum_required(VERSION 3.10)
project(ffmpeg)
set(CMAKE_CXX_STANDARD 11)
include_directories(libs/ffmpeg/)
include_directories(libs/ffmpeg/include/libavutil/)
include_directories(libs/ffmpeg/include/libaccodec/)
include_directories(libs/ffmpeg/include/libavdevice/)
include_directories(libs/ffmpeg/include/libavfilter/)
include_directories(libs/ffmpeg/include/libavformat/)
include_directories(libs/ffmpeg/include/)
link_directories(libs/ffmpeg/lib/)
set(SOURCE_FILES main.cpp)
add_executable(ffmpeg main.cpp)
target_link_libraries(
ffmpeg
avcodec
avdevice
avfilter
avformat
avresample
avutil
postproc
swresample
swscale
)
I am not sure if I added the libraries and includes in the right way, beacause in my simple main.cpp it can't resolve avcodec_configuration().
My project layout looks as follows:
ffmpeg
-libs
-include
-libavcodec
.
.
.
-lib
-avcodec.lib
-main.cpp
EDIT:
Now all includes are found by the compiler. BUt if I compile I get following error:
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lavresample
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[2]: *** [ffmpeg.exe] Error 1
mingw32-make.exe[1]: *** [CMakeFiles/ffmpeg.dir/all] Error 2
mingw32-make.exe: *** [all] Error 2
CMakeFiles\ffmpeg.dir\build.make:96: recipe for target 'ffmpeg.exe' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/ffmpeg.dir/all' failed
Makefile:82: recipe for target 'all' failed
I don't recommend to hardcode paths to the headers/libraries in your CMakeLists.txt; this is not portable.
Search for a ready FindFFmpeg.cmake (maybe this one will work?),
add it to your project directory (e.g. into a cmake/ subdirectory),
and connect it to CMAKE_MODULE_PATH. E.g. list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake").
Then refer to ${FFMPEG_LIBRARIES}, ${FFMPEG_INCLUDE_DIRS} and ${FFMPEG_DEFINITIONS}.
Sometimes you have to fix up the FindXXX.cmake modules.
I was able to include the precompiled ffmpeg library to cmake project by creating find cmake scripts and including them in main CMakeLists.txt.
Full example is here : https://github.com/tomkordic/Java-native-HTTP/tree/master/src/main/cpp
In my project a FFMPEG_INCLUDE_DIRECTORY and FFMPEG_LIB_DIRECTORY are passed by gradle build script you can set these manually or discover them in some other way.
FFMPEG_INCLUDE_DIRECTORY is a path to ffmpeg installation include directory, in my case:
/mnt/7fab2260-fb19-41a7-ac7c-816bab2f3b92/install/ffmpeg_build/include
FFMPEG_LIB_DIRECTORY is a path to ffmpeg installation lib directory, in my case:
/mnt/7fab2260-fb19-41a7-ac7c-816bab2f3b92/install/ffmpeg_build/lib
Make sure to set CMAKE_MODULE_PATH to the directory where your find cmake scripts are located.
Build system is for ubuntu 18.04.
I was trying to convert an existed c++ project to CMake. The existed worked well with makefile, and i have converted similar one successfully. but when i try to convert this one, some confusing errors occurred, as below:
18:22:10: Running steps for project encryption...
18:22:10: Starting: "/export/opt/cmake-3.2.2/bin/cmake" --build . --target all
Linking CXX executable dist/Debug_64/GNU-Linux-x86/encryption
CMakeFiles/encryption.dir/encryption.cc.o: In function `main':
/export1/chao/nanos/nano_clean/nano_clean/src/encryption/encryption.cc:33: undefined reference to `stlp_std::cout'
...
/export1/chao/nanos/nano_clean/nano_clean/lib/STLport/stlport/stl/_string.c:604: undefined reference to `stlp_std::__stl_throw_out_of_range(char const*)'
...
At first i think it can't find iostream, so i include iostream at /export1/chao/nanos/nano_clean/nano_clean/lib/STLport/stlport/ by using 'INCLUDE_DIRECTORIES', but it did not work. Could you please give me some advices?
My CMakeLists.txt as below:
include_directories(/export1/chao/nanos/nano_clean/nano_clean/lib/STLport/stlport)
include_directories(/export1/chao/nanos/nano_clean/nano_clean/lib/STLport/stlport/h/using)
include_directories(/export1/chao/nanos/nano_clean/nano_clean/lib/boost/1.49.0/boost/tr1/tr1)
link_directories(
../common/dist/${CONF}/GNU-Linux-x86
/export2/chao/nanos/nano_built/lib/tiburonda/dist/include
)
aux_source_directory(. SRC_LIST)
include_directories(../common/include
)
add_executable(encryption ${SRC_LIST})
target_link_libraries(encryption libcommon.a)
According to original makefile, i found this project use source file encryption.cc at ./, header files: encryption.h at ./ and others at ../common/include.
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