cmake simple sub-directory not including files - c++

I have read and tried just about every tutorial/wiki/SO post, page, snippet I could find to get this CMAKE working....
I have a super simple directory structure:
ROOT/
|- CMakeLists.txt
|- main.cpp
|- sub/
|-CMakeLists.txt
|-subx/
|-CMakeLists.txt
|-subx.h
|-subx.cpp
|-suby/
|-CMakeLists.txt
|-suby.h
|-suby.cpp
The main.cpp is a super simple cpp program:
//omitting all unnecessary code
int main() {
subx s;
s.defined_method();
s.another_defined_method(1);
return 0;
}
You can assume, for everyone's sake that the subx and suby definitions are correct and work just fine, because they do when I compile by hand.
When I compile by CMake I get the following error:
"/path/to/cmake" --build /path/to/Debug --target CS220_Project -- -j 4
Linking CXX executable simple_project
Undefined symbols for architecture x86_64:
"subx::defined_method()", referenced from:
_main in main.cpp.o
"subx::another_defined_method(int)", referenced from:
_main in main.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[3]: *** [simple_project] Error 1
make[2]: *** [CMakeFiles/simple_project.dir/all] Error 2
make[1]: *** [CMakeFiles/simple_project.dir/rule] Error 2
make: *** [simple_project] Error 2
The root CMakeLists.txt file looks:
cmake_minimum_required(VERSION 2.8.4)
project(simple_project)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_subdirectory(sub)
add_executable(simple_project ${SOURCE_FILES})
Sub CMakeLists.txt file looks:
add_subdirectory(subx)
add_subdirectory(suby)
subx & suby CMakeLists.txt file looks: (they include their respective distinction)
set(SUBX_SOURCES subx.cpp)
#Add any files in this directory
add_executable(SUBX ${SUBX_SOURCES})
I've tried things like add_library, file (glob), etc. I cannot, for the life of me get files that are in any sub-directory to compile with the main.cpp program.

Depends on what exactly you want the subprojects to be. The way I understand it, subx and suby are libraries, which should be linked to the main executable:
ROOT/CMakeLists.txt
cmake_minimum_required(VERSION 2.8.4)
project(simple_project)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_subdirectory(sub)
add_executable(simple_project ${SOURCE_FILES})
target_link_libraries(simple_project SUBX SUBY)
ROOT/subx/CMakeLists.txt
set(SUBX_SOURCES subx.cpp)
#Add any files in this directory
add_library(SUBX ${SUBX_SOURCES})
(dtto for suby)

Related

Unable to run SFML project with CMake on arm64

I am using MacBook with M1 and I try to create a project with SFML.
I downloaded a snapshot of SFML with files built for arm64
I verified it using file command
Example:
libsfml-graphics.dylib: Mach-O 64-bit dynamically linked shared library arm64
I placed these files in ~/Library/Frameworks along with extlibs directory content.
I set a CMake flag: -DCMAKE_OSX_ARCHITECTURES=arm64
But I still am unable to run this project.
Error:
[ 50%] Linking CXX executable myProject
Undefined symbols for architecture arm64:
"__ZN2sf6StringC1EPKcRKSt6locale", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
make[3]: *** [myProject] Error 1
make[2]: *** [CMakeFiles/myProject.dir/all] Error 2
make[1]: *** [CMakeFiles/myProject.dir/rule] Error 2
make: *** [myProject] Error 2
This is my whole CMakeLists.txt file:
cmake_minimum_required(VERSION 3.19)
project(myProject)
add_executable(myProject main.cpp)
set(CMAKE_CXX_COMPILER "/opt/homebrew/bin/g++-11" CACHE STRING "C++ compiler" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCMAKE_OSX_ARCHITECTURES=arm64")
include_directories(/usr/local/include)
find_package(SFML 2.5 COMPONENTS system window graphics network audio REQUIRED)
include_directories(${SFML_INCLUDE_DIRS})
target_link_libraries(myProject sfml-system sfml-window sfml-graphics sfml-audio sfml-network)
I also tried to use dylib instead of framework, but it was unsuccessful also. I'd be grateful for any help, I can't figure out what I did wrong.

Simple OpenMP-enabled code does not compile: "clang: error: linker command failed with exit code 1"

I tried to test OpenMP on MacOS with the Apple Clang compiler that comes with Xcode.
Code:
#include <iostream>
#include <cmath>
#include </usr/local/opt/libomp/include/omp.h>
int main() {
std::cout << "Hello, World!" << std::endl;
#pragma omp parallel
{
printf("Hello World! \n");
}
return 0;
}
and this is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.19)
project(untitled)
set(CMAKE_CXX_STANDARD 14)
include (FindOpenMP)
if (OPENMP_FOUND)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
message (VERBOSE "OpenML library found")
else()
message (FATAL_ERROR "OpenML library not found (required for multithreading)")
endif ()
add_executable(untitled main.cpp)
This is the compiler's error:
Scanning dependencies of target untitled
[ 50%] Building CXX object CMakeFiles/untitled.dir/main.cpp.o
[100%] Linking CXX executable untitled
Undefined symbols for architecture x86_64:
"___kmpc_fork_call", referenced from:
_main in main.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[3]: *** [untitled] Error 1
make[2]: *** [CMakeFiles/untitled.dir/all] Error 2
make[1]: *** [CMakeFiles/untitled.dir/rule] Error 2
make: *** [untitled] Error 2
The OpenMP is installed using hombrew libomp I also tried adding environment variable LDFLAGS=-L/usr/local/opt/libomp/lib/ and it does not affect the result
UPDATE: COMPILATION WITH VERBOSE=1:
...
[100%] Linking CXX executable untitled
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_link_script CMakeFiles/untitled.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/c++ -Xclang -fopenmp -g -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/usr/local/opt/libomp/lib/ CMakeFiles/untitled.dir/main.cpp.o -o untitled
Undefined symbols for architecture x86_64:
"___kmpc_fork_call", referenced from:
_main in main.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[3]: *** [untitled] Error 1
make[2]: *** [CMakeFiles/untitled.dir/all] Error 2
make[1]: *** [CMakeFiles/untitled.dir/rule] Error 2
make: *** [untitled] Error 2
By using set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") and using set in other places, you are replacing the flags that CMAKE puts. It is better to append in this case rather than replace. You can use add_compile_options(-Wall) here.
As mentioned by #Tsyvarev, it is perhaps better to use imported library. Here are a few other ways you can use target_link_libraries.
For your particular case, it is best to replace
find_package(OpenMP REQUIRED)
where you currently have include (FindOpenMP). Further, remove the if condition as well. Finally, add the following to the end of your CMakeLists.txt file.
target_link_libraries(
untitled
PRIVATE
OpenMP::OpenMP_CXX
)
Here is a good explanation of the difference between PRIVATE and PUBLIC.
Your final CMakeLists.txt file should look like:
cmake_minimum_required(VERSION 3.19)
project(untitled)
set(CMAKE_CXX_STANDARD 14)
find_package(OpenMP REQUIRED)
add_executable(
untitled
main.cpp
)
target_link_libraries(
untitled
PRIVATE
OpenMP::OpenMP_CXX
)
Thanks to Tsyvarev, for helping me with CMake a few months ago. Further, thanks to the answers that Tsyvarev points toward, which my answer is based on (along with my own testing).

Undefined symbols using WxWidgets and Conan

I am trying to adopt the Conan C++ package manager. I have followed along with the getting started have managed to get it working with most projects. However I am having linking issues with WxWidgets that I can't seem to fix.
linker error:
[ 23%] Linking CXX executable ../bin/wx_sample
Undefined symbols for architecture x86_64:
"Frame::onMenuFileQuit(wxCommandEvent&)", referenced from:
__GLOBAL__sub_I_frame.cpp in frame.cpp.o
"Frame::onMenuFileSave(wxCommandEvent&)", referenced from:
__GLOBAL__sub_I_frame.cpp in frame.cpp.o
"Frame::onMenuFileAbout(wxCommandEvent&)", referenced from:
__GLOBAL__sub_I_frame.cpp in frame.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]: *** [bin/wx_sample] Error 1
make[1]: *** [src/CMakeFiles/wx_sample.dir/all] Error 2
make: *** [all] Error 2
conanfile.txt
[requires]
wxwidgets/3.1.4#bincrafters/stable
[generators]
cmake
CmakeFile.txt - project root -
cmake_minimum_required(VERSION 3.17)
project(wx_sample)
set(CMAKE_CXX_STANDARD 17)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
include_directories(src)
add_subdirectory(src)
CmakeFile.txt -- src folder --
set(BINARY ${CMAKE_PROJECT_NAME})
file(GLOB_RECURSE SOURCES LIST_DIRECTORIES true *.h *.cpp)
set(SOURCES ${SOURCES})
add_executable(${BINARY} ${SOURCES})
target_link_libraries(${BINARY} ${CONAN_LIBS})
conan default profile:
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=apple-clang
compiler.libcxx=libc++
compiler.version=12.0
os=Macos
os_build=Macos
I am not sure if I need to include deps into my conanfile, though I thought that Conan manages this automatically? If I remove the offending sections listed in the error, the application links successfully.
EDIT:
You were right on the CONAN_LIBS global. Your CMake structure looks fine. You could try to call conan_basic_setup() from the src CMakeLists.txt.
If that doesn't work the issue might be in your conanfile.py.
https://github.com/bincrafters/conan-wxwidgets/commit/37b6669229ec0e68593065a700c360d23a914bac

Making C++ Project with OpenCV and librealsense

I want to start a computer vision project using an r200 and OpenCV. I'm using the legacy librealsense library and i've ran the examples on it successfully.
Unfortunately i'm new to C++ and Cmake so i'm struggling to import things appropriately.
My project structure looks like:
-Project
-build
-librealsense //this is the directory that contains the code to run the r200
-main.cpp //my main working file
-CMakeLists.txt //what i'm working on
my CMakeLists.txt runs successfully when i execute ../ cmake from the build directory and it looks like this:
cmake_minimum_required(VERSION 3.10)
project(Project)
set(CMAKE_CXX_STANDARD 11)
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_subdirectory(librealsense)
# add the executable
add_executable(Project main.cpp librealsense/examples/example.hpp)
target_link_libraries( Project ${OpenCV_LIBS})
target_link_libraries(Project realsense2)
Note that at the moment i'm just trialing code from the examples and that librealsense/examples/example.hpp is the relative path to one of the example.hpp headers used in the example that i'm copying.
The imports that i'm using in main.cpp are as follows:
#include <librealsense2/rs.hpp>
#include "librealsense/examples/example.hpp"
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
It responds with a very verbose error message that ends with the following:
...
"_rs2_start_processing", referenced from:
void rs2::processing_block::start<rs2::frame_queue>(rs2::frame_queue) in main.cpp.o
"_rs2_stream_to_string", referenced from:
texture::show(rect const&) const in main.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]: *** [Project] Error 1
make[1]: *** [CMakeFiles/Project.dir/all] Error 2
make: *** [all] Error 2
My question is how do I actually import OpenCV and the librealsense libraries!!!
Any direction to good guides for this and CMake would make me forever grateful!

Undefined symbols when building libuv

I need to use libuv with my library. Since I cannot link it two static libraries I decided to include the source for libuv along with my code. I have a .cmake file that downloads libuv, checks out the right tag and adds the source files to a variable:
include(DownloadProject.cmake)
download_project(PROJ libuv
GIT_REPOSITORY https://github.com/libuv/libuv.git
GIT_TAG v1.10.0
${UPDATE_DISCONNECTED_IF_AVAILABLE}
)
exec_program(COMMAND "./autogen.sh" WORKING_DIRECTORY ${libuv_SOURCE_DIR})
exec_program(COMMAND "./configure" WORKING_DIRECTORY ${libuv_SOURCE_DIR})
include_directories(${LIBUVDIR}/include ${LIBUVDIR}/src)
set(LIBUV_SOURCES
${LIBUVDIR}/include/uv.h
${LIBUVDIR}/include/tree.h
${LIBUVDIR}/include/uv-errno.h
${LIBUVDIR}/include/uv-threadpool.h
${LIBUVDIR}/include/uv-version.h
${LIBUVDIR}/src/fs-poll.c
${LIBUVDIR}/src/heap-inl.h
${LIBUVDIR}/src/inet.c
${LIBUVDIR}/src/queue.h
${LIBUVDIR}/src/threadpool.c
${LIBUVDIR}/src/uv-common.c
${LIBUVDIR}/src/uv-common.h
${LIBUVDIR}/src/version.c
)
etc.
I then add add the list of libuv source files to the list of source files for my project and link the library with its dependencies:
include(libuv.cmake)
# Build library
set(SOURCE_FILES
<my sources>
${LIBUV_SOURCES})
add_library(databaseclient STATIC ${SOURCE_FILES})
set(CMAKE_THREAD_PREFER_PTHREAD 1)
set(THREADS_PREFER_PTHREAD_FLAG 1)
include(FindThreads)
target_link_libraries(databaseclient PUBLIC Threads::Threads)
But when I run make I get the following error:
Undefined symbols for architecture x86_64:
"_pthread_barrier_destroy", referenced from:
_uv_barrier_destroy in libdatabaseclient.a(thread.c.o)
"_pthread_barrier_init", referenced from:
_uv_barrier_init in libdatabaseclient.a(thread.c.o)
"_pthread_barrier_wait", referenced from:
_uv_barrier_wait in libdatabaseclient.a(thread.c.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]: *** [tests/unit_tests] Error 1
make[1]: *** [tests/CMakeFiles/unit_tests.dir/all] Error 2
make: *** [all] Error 2
unit_tests is my unit tests executable.
I think there's something I'm not linking against, just don't know what. Any clues?
Hi I just ran into this same problem, it seems pthread_barrier primitives are not implemented on MacOS despite it's claims of POSIX compliance. LibUV implements it's own versions using other threading primitives. If you add ${LIBUVDIR}/src/unix/pthread-barrier.c to your list of libuv c files it should link correctly.
Here is what I have in CMakeLists.txt for libuv
set(LIBUVDIR libuv)
include_directories(${LIBUVDIR}/include ${LIBUVDIR}/src)
set(SOURCES
${LIBUVDIR}/src/fs-poll.c
${LIBUVDIR}/src/inet.c
${LIBUVDIR}/src/threadpool.c
${LIBUVDIR}/src/uv-common.c
${LIBUVDIR}/src/version.c)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
add_definitions(-D_GNU_SOURCE)
set(SOURCES ${SOURCES}
${LIBUVDIR}/src/unix/linux-syscalls.c
${LIBUVDIR}/src/unix/linux-core.c
${LIBUVDIR}/src/unix/linux-inotify.c)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
add_definitions(-D_DARWIN_USE_64_BIT_INODE=1 -D_DARWIN_UNLIMITED_SELECT=1)
set(SOURCES ${SOURCES}
${LIBUVDIR}/src/unix/darwin.c
${LIBUVDIR}/src/unix/darwin-proctitle.c
${LIBUVDIR}/src/unix/fsevents.c
${LIBUVDIR}/src/unix/kqueue.c
${LIBUVDIR}/src/unix/pthread-barrier.c
${LIBUVDIR}/src/unix/proctitle.c)
endif()
include_directories(${LIBUVDIR}/src/unix)
set(SOURCES ${SOURCES}
${LIBUVDIR}/src/unix/async.c
${LIBUVDIR}/src/unix/core.c
${LIBUVDIR}/src/unix/dl.c
${LIBUVDIR}/src/unix/fs.c
${LIBUVDIR}/src/unix/getaddrinfo.c
${LIBUVDIR}/src/unix/getnameinfo.c
${LIBUVDIR}/src/unix/loop-watcher.c
${LIBUVDIR}/src/unix/loop.c
${LIBUVDIR}/src/unix/pipe.c
${LIBUVDIR}/src/unix/poll.c
${LIBUVDIR}/src/unix/process.c
${LIBUVDIR}/src/unix/signal.c
${LIBUVDIR}/src/unix/stream.c
${LIBUVDIR}/src/unix/tcp.c
${LIBUVDIR}/src/unix/thread.c
${LIBUVDIR}/src/unix/timer.c
${LIBUVDIR}/src/unix/tty.c
${LIBUVDIR}/src/unix/udp.c)
add_library(uv STATIC ${SOURCES})
target_link_libraries(uv pthread)