I have to run cmake twice for compile the project - c++

I got the following error with the first running of the command
cmake .
But if I run the command again, the compilation succeed. That is, I have to run cmake twice for make the project compiled. Why is it so? How could I fix it?
Error message:
CMakeFiles/exec.dir/Timer.cpp.o: In function `std::thread::thread<Timer::Timer()::{lambda()#1}>(Timer::Timer()::{lambda()#1}&&)':
/usr/include/c++/7/thread:122: undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status
CMakeFiles/exe.dir/build.make:146: recipe for target 'exe' failed
make[2]: *** [exe] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/exe.dir/all' failed
make[1]: *** [CMakeFiles/exe.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -g -std=c++14 -std=c++11 -std=c++17 ")
project(myproject)
set(SOURCE_FILES main.cpp Timer.cpp TimerEntity.cpp)
add_executable(exe ${SOURCE_FILES})

It is not usually noted, but appending compiler flags via
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} <...>")
should be placed after the project() call.
Exactly project() call sets the initial value of CMAKE_CXX_FLAGS variable.
Normally, project() call is issued just after the cmake_minimum_required():
cmake_minimum_required(VERSION 3.10)
project(437_Hw1)
...
Details
In your current code, when you call cmake the first time, your first setting set(CMAKE_CXX_FLAGS ...) is replaced by the value of the following project() call and stored in the CACHE.
When you call cmake the second time, CMAKE_CXX_FLAGS variable is already set (it is loaded from the cache). So, set(CMAKE_CXX_FLAGS ...) sets the variable to correct value. Moreover, following project() doesn't change CMAKE_CXX_FLAGS variable because it finds it already in the cache.

I reworked your CMakeLists.txt to use modern CMake:
cmake_minimum_required(VERSION 3.7)
project(437_Hw1)
# CMake can set the standard in a cross-platform way for you
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE Debug)
set(SOURCE_FILES main.cpp SubTimer.cpp TimerEntity.cpp)
add_executable(exe ${SOURCE_FILES})
# These two lines add the platform-specific magic for the right threading library/headers.
find_package(Threads)
target_link_libraries(exe Threads::Threads)

I suggest you replace the line
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -g -std=c++14 -std=c++11 -std=c++17 ")
with
set(CMAKE_CXX_STANDARD 17)
target_link_libraries(exe pthread)
and see if that helps.

Related

Cross-compiling: Error adding symbols: File in wrong format collect2: error: ld returned 1 exit status

Cross-compiling c++ test application for aarch64 compiler and linking boost library using Cmake files. I keep getting this error that the format of the boost library is not correct. Here is my CMakeList and the error im getting.
CMakeLists.txt:
cmake_minimum_required(VERSION "3.10.2")
project(testapp2)
# Target operating system name.
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
# Name of C compiler.
set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc")
set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
#set(CMAKE_CXX_FLAGS "-m32")
set(BOOST_ROOT "./local/boost_1_73_0") # either set it here or from the command line
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(Boost_INCLUDE_DIRS "./local/boost_1_73_0/boost")
find_package(Boost REQUIRED COMPONENTS system)
add_executable(testapp2 main.cpp)
install(TARGETS testapp2 DESTINATION bin)
install(FILES main.cpp DESTINATION src)
target_include_directories(testapp2 PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(testapp2 ${Boost_LIBRARIES})
Error:
usr/lib/x86_64-linux-gnu/libboost_system.so: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
I've tried to add the -DCMAKE_CXX_FLAGS="m32" and it gave me this error:
CMake Error at /usr/share/cmake-3.10/Modules/CMakeTestCXXCompiler.cmake:45 (message):
The C++ compiler
"/usr/bin/c++"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: /root/testapp2/build/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_3dc9d/fast"
/usr/bin/make -f CMakeFiles/cmTC_3dc9d.dir/build.make CMakeFiles/cmTC_3dc9d.dir/build
make[1]: Entering directory '/root/testapp2/build/CMakeFiles/CMakeTmp'
Building CXX object CMakeFiles/cmTC_3dc9d.dir/testCXXCompiler.cxx.o
/usr/bin/c++ m32 -o CMakeFiles/cmTC_3dc9d.dir/testCXXCompiler.cxx.o -c /root/testapp2/build/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
c++: error: m32: No such file or directory

Compiling a program using <graphviz/gvc.h>: undefined reference to `gvContext'

I am working on some parts of a fairly large project that involves using GraphViz on C++, but I can't seem to use the GraphViz functions. My code is intended to generate a .png from .dot files automatically, but I keep getting "undefined reference" to 'functionName' (all functions that are related to the gvc.h include) when I try to compile it. I highly suspect that something is not linking during compilation, but I can't figure out what to do with the CMakeLists.txt and what I should link in the first place. I did, however, notice that there was a gv.cpp file in my /usr/include/graphviz folder, but I don't know if I'm supposed to somehow link that file or if it's something completely different.
/usr/bin/ld: CMakeFiles/ag_gen.dir/src/main.cpp.o: in function `save_image_gv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
main.cpp:(.text+0xf07): undefined reference to `gvContext'
/usr/bin/ld: main.cpp:(.text+0xf27): undefined reference to `agread'
/usr/bin/ld: main.cpp:(.text+0xf3c): undefined reference to `gvLayout'
/usr/bin/ld: main.cpp:(.text+0xfc8): undefined reference to `gvRender'
/usr/bin/ld: main.cpp:(.text+0xfef): undefined reference to `gvFreeLayout'
/usr/bin/ld: main.cpp:(.text+0xff7): undefined reference to `agclose'
/usr/bin/ld: main.cpp:(.text+0xfff): undefined reference to `gvFreeContext'
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/ag_gen.dir/build.make:460: ag_gen] Error 1
make[2]: *** [CMakeFiles/Makefile2:156: CMakeFiles/ag_gen.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:163: CMakeFiles/ag_gen.dir/rule] Error 2
make: *** [Makefile:164: ag_gen] Error 2
Here is the problematic part of my code in main.cpp:
#include <graphviz/gvc.h>
bool save_image_gv(std::string filename){
GVC_t *gvc;
Agraph_t *g;
FILE *fp;
gvc = gvContext();
fp = fopen((filename).c_str(), "r");
g = agread(fp, 0);
gvLayout(gvc, g, "dot");
gvRender(gvc, g, "png", fopen((filename+".png").c_str(), "w"));
gvFreeLayout(gvc, g);
agclose(g);
return (gvFreeContext(gvc));
}
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
# Uncomment for gcc
# set(CMAKE_C_COMPILER "gcc-8")
# set(CMAKE_CXX_COMPILER "g++-8")
project(ag_gen)
set_source_files_properties(
mem.c
PROPERTIES
COMPILE_DEFINITIONS UNIT_TEST=1
)
# Common compiler options among built types
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
# Specific compiler options for Debug or Release builds
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -ggdb -Wall -fopenmp -pedantic")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -Wall -fopenmp -pedantic -O1")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O1 -fopenmp")
set(PostgreSQL_TYPE_INCLUDE_DIR "9.5")
set(PostgreSQL_ADDITIONAL_VERSIONS "10.1" "10" "9.5")
find_program(LSB_RELEASE lsb_release)
execute_process(COMMAND ${LSB_RELEASE} -is
OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
include_directories("/usr/include/postgresql")
# Apple has a different openssl directory when using brew
if(APPLE)
set(BISON_EXECUTABLE "/usr/local/opt/bison/bin/bison")
set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl")
endif()
set(ENV{PKG_CONFIG_PATH} "/usr/local/lib/pkgconfig")
find_package(PkgConfig REQUIRED)
find_package(PostgreSQL REQUIRED)
find_package(OpenMP)
find_package(BISON 2.4 REQUIRED)
find_package(FLEX REQUIRED)
find_package(Boost REQUIRED)
find_package(OpenSSL)
find_package(Doxygen)
pkg_check_modules(CMOCKA cmocka)
pkg_check_modules(CPPREDIS cpp_redis)
if(OpenSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR})
endif()
# Enable thread-level parallelization if OpenMP is found.
if(OpenMP_CXX_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
if(DOXYGEN_FOUND)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile #ONLY)
add_custom_target(doc ALL ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM)
endif(DOXYGEN_FOUND)
include_directories("${CMAKE_SOURCE_DIR}/src/")
file(GLOB ag_gen_src "${CMAKE_SOURCE_DIR}/src/ag_gen/*.cpp")
file(GLOB utils_src "${CMAKE_SOURCE_DIR}/src/util/*.c" "${CMAKE_SOURCE_DIR}/src/util/*.cpp")
########################
### Network Model Parser
########################
BISON_TARGET(nm_parser "${CMAKE_SOURCE_DIR}/src/parser/nm-parser/nm_parser.yy"
"${CMAKE_CURRENT_BINARY_DIR}/nm_parser.c"
DEFINES_FILE "${CMAKE_CURRENT_BINARY_DIR}/nm_parser.tab.h")
FLEX_TARGET(nm_scanner "${CMAKE_SOURCE_DIR}/src/parser/nm-parser/nm_scanner.l"
"${CMAKE_CURRENT_BINARY_DIR}/nm_scanner.c"
COMPILE_FLAGS "-Pnm")
ADD_FLEX_BISON_DEPENDENCY(nm_scanner nm_parser)
#add_executable(nm_test ${FLEX_nm_scanner_OUTPUTS} ${BISON_nm_parser_OUTPUTS} ${utils_src})
#target_include_directories(nm_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_SOURCE_DIR}/src/compiler/nm-parser")
##########################
### Exploit Pattern Parser
##########################
BISON_TARGET(xp_parser "${CMAKE_SOURCE_DIR}/src/parser/xp-parser/xp_parser.yy"
"${CMAKE_CURRENT_BINARY_DIR}/xp_parser.c"
DEFINES_FILE "${CMAKE_CURRENT_BINARY_DIR}/xp_parser.tab.h")
FLEX_TARGET(xp_scanner "${CMAKE_SOURCE_DIR}/src/parser/xp-parser/xp_scanner.l"
"${CMAKE_CURRENT_BINARY_DIR}/xp_scanner.c"
COMPILE_FLAGS "-Pxp")
ADD_FLEX_BISON_DEPENDENCY(xp_scanner xp_parser)
#add_executable(xp_test ${FLEX_xp_scanner_OUTPUTS} ${BISON_xp_parser_OUTPUTS} ${utils_src})
#target_include_directories(xp_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_SOURCE_DIR}/src/compiler/xp-parser")
####################
### Main application
####################
add_executable(ag_gen "${CMAKE_SOURCE_DIR}/src/main.cpp"
${FLEX_nm_scanner_OUTPUTS} ${BISON_nm_parser_OUTPUTS}
${FLEX_xp_scanner_OUTPUTS} ${BISON_xp_parser_OUTPUTS}
${ag_gen_src} ${utils_src})
target_link_libraries(ag_gen ${PostgreSQL_LIBRARIES})
add_executable(decode "${CMAKE_SOURCE_DIR}/src/tools/decode.cpp"
${ag_gen_src} ${utils_src})
target_link_libraries(decode ${PostgreSQL_LIBRARIES})
if(CPPREDIS_FOUND)
#include_directories("${CPPREDIS_INCLUDE_DIRS}")
link_directories("${CPPREDIS_LIBRARY_DIRS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DREDIS")
target_link_libraries(ag_gen cpp_redis tacopie)
target_link_libraries(decode cpp_redis tacopie)
endif()
################
### Unit Testing
################
if(CMOCKA_FOUND)
add_executable(dynstr_test ${CMAKE_SOURCE_DIR}/src/util/mem.c ${CMAKE_SOURCE_DIR}/src/tests/mem_test.c)
target_link_libraries(dynstr_test ${CMOCKA_LIBRARIES})
endif()
# Files to be added to build directory
configure_file("config.ini" "config.ini" COPYONLY)
if(CPPREDIS_FOUND)
add_custom_command(TARGET ag_gen PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/redis_scripts $<TARGET_FILE_DIR:ag_gen>/redis_scripts)
endif()
Link libgvc.so with your binary as follows:
target_link_libraries(ag_gen PUBLIC gvc)
Using Botje's answer and this Stack Overflow question, I was able to solve the problem. Here's what I did to my CMakeLists.txt:
I added cgraph and gvc in target_link_libraries.
target_link_libraries(ag_gen ${PostgreSQL_LIBRARIES} cgraph gvc)
And, voila! After this simple change, compilation was a success!

Why is main not found when building a project that includes gtest with cmake?

I have a very small project to which I created some unit testing with GTest.
To build it, I'm using CMake. It compiles just fine, but it's giving me the error shown below. I include all make output just in case.
Scanning dependencies of target trace
[ 33%] Building C object CMakeFiles/trace.dir/trace/system_trace.c.o
[ 33%] Built target trace
Scanning dependencies of target data-test
[ 66%] Building CXX object CMakeFiles/data- test.dir/data_testsuite.cpp.o
[100%] Linking CXX executable data-test
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
CMakeFiles/data-test.dir/build.make:86: recipe for target 'data-test' failed
make[2]: *** [data-test] Error 1
CMakeFiles/Makefile2:72: recipe for target 'CMakeFiles/data-test.dir/all' failed
make[1]: *** [CMakeFiles/data-test.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
And I have no idea why is not finding main. Main is part of GTest which I'm including as it can be seen on the CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
set (CMAKE_CXX_STANDARD 11)
project(data-test C CXX)
set(CMAKE_C_FLAGS_DEBUG "-g3 -Og -Wall")
set(CMAKE_CXX_FLAGS_DEBUG "-g3 -Og -Wall")
set(CMAKE_C_FLAGS_RELEASE "-g0 -O3 -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O3 -Wall")
include(GoogleTest)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
find_package(GTest REQUIRED)
include_directories(cfg)
include_directories(system)
include_directories(system/include)
include(trace/CMakeLists.txt)
add_executable(data-test
$<TARGET_OBJECTS:trace>
data_testsuite.cpp
)
target_link_libraries(data-test Threads::Threads GTest::GTest)
gtest_discover_tests(data-test)
And as you can see from the make command output, it is compiling just fine.
Do you know what is going on?
The libraries defined by the target GTest::Gtest doesn't contain main function definition. For obtain definition of main you need link with GTest::Main. This is written in documentation.
target_link_libraries(data-test Threads::Threads GTest::Main)

cmake link xlib directories c++

I'm trying to compile a c++ program that uses xlib with cmake. However, I'm having a problem including and linking xlib libraries in cmake file.
This is the error that I'm getting.
main.cpp:378: undefined reference to `XClearWindow'
collect2: error: ld returned 1 exit status
CMakeFiles/project1.dir/build.make:94: recipe for target 'project1' failed
make[2]: *** [project1] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/project1.dir/all' failed
make[1]: *** [CMakeFiles/project1.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
And when I use just the command line to compile, it works just fine.
I use this command (g++ main.cpp -L/usr/X11R6/lib -lX11)
and this is my cmake file.
cmake_minimum_required(VERSION 3.6)
project(project1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
link_directories(/usr/X11R6/lib)
include_directories(/usr/share/X11)
set(SOURCE_FILES main.cpp)
add_executable(project1 ${SOURCE_FILES})
In your case, you forgot to specify the libraries that cmake should use to link your application (target_link_libraries or link_libraries).
But, why not just let cmake find the required path, libraries and includes by itself? I suggest you to use find_package(X11). In your case, you can try:
cmake_minimum_required(VERSION 3.6)
project(project1)
set(CMAKE_CXX_STANDARD 11) # for c++11
find_package(X11 REQUIRED)
link_libraries(${X11_LIBRARIES})
include_directories(${X11_INCLUDE_DIR})
set(SOURCE_FILES main.cpp)
add_executable(project1 ${SOURCE_FILES})
I won't be able to explain why (if you have some idea, don't hesitate to comment my answer), but, in my case, I had to link X11 library using this command:
target_link_libraries( DisplayImage "-lX11" )
It works, at least, for the 3.5.1 version of cmake.

CMAKEList leap motion

I am trying to build a cmakelist file from makefile of leap motion, I can compile in a specific directory, I need to copy /include/ and /lib/x64/ directories . The makefile is the follow:
LEAP_LIBRARY := ./lib/x64/libLeap.so -Wl,-rpath,./lib/x64
Sample: Sample.cpp
$(CXX) -Wall -g -I include Sample.cpp -o Sample $(LEAP_LIBRARY)
I have tried to build a cmakelist file as follows:
cmake_minimum_required(VERSION 2.8)
project(Sample)
INCLUDE_DIRECTORIES(/include/)
LINK_DIRECTORIES(/lib/x64/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g -I /include/ -Wl,-rpath,./lib/x64")
add_executable(Sample Sample.cpp )
target_link_libraries(Sample libLeap.so)
But I always get the same error:
Linking CXX executable Sample
/usr/bin/ld: can't find -lLeap
collect2: error: ld returned 1 exit status
make[2]: *** [Sample] Error 1
make[1]: *** [CMakeFiles/Sample.dir/all] Error 2
make: *** [all] Error 2
Thanks and regards.
I could solve with following lines:
cmake_minimum_required(VERSION 2.8)
project(Sample)
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
INCLUDE_DIRECTORIES(../include/)
LINK_DIRECTORIES(../lib/x64/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g")
add_executable(Sample Sample.cpp )
target_link_libraries(Sample -lLeap)
This solution has warnings but works:
CMake Warning (dev) at CMakeLists.txt:5 (LINK_DIRECTORIES):
This command specifies the relative path
../lib/x64
as a link directory.
Policy CMP0015 is not set: link_directories() treats paths relative to the
source dir. Run "cmake --help-policy CMP0015" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Configuring done
-- Generating done
-- Build files....
Two way to delete this warning:
cmake_minimum_required(VERSION 2.8)
project(Sample)
cmake_policy(SET CMP0015 NEW)
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
INCLUDE_DIRECTORIES(../include/)
LINK_DIRECTORIES(lib/x64/)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g")
add_executable(Sample Sample.cpp )
target_link_libraries(Sample -lLeap)
Or use cmake .. -Wno-dev