I'm trying to build gl3w from source and link it automatically in my C++ project using CMake. I've added gl3w as a git submodule and have the following in CMakeLists.txt:
# GL3W
set(gl3w_dir "${CMAKE_CURRENT_SOURCE_DIR}/gl3w")
set(gl3w_inc "${gl3w_dir}/include")
set(gl3w_src "${gl3w_dir}/src/gl3w.c")
if (EXISTS ${gl3w_src})
message(STATUS "Found gl3w source files")
else()
execute_process(COMMAND python3 gl3w_gen.py WORKING_DIRECTORY "${gl3w_dir}") # use python or python3
if (NOT EXISTS ${gl3w_src})
message(FATAL_ERROR "Could not generate gl3w source files")
endif()
endif()
add_library(gl3w STATIC "${gl3w_src}")
target_include_directories(gl3w PUBLIC "${gl3w_inc}")
target_link_libraries(main gl3w)
However, this doesn't seem to be working. I get the following error upon building:
[build] Undefined symbols for architecture x86_64:
[build] "_gl3wProcs", referenced from:
[build] _main in main.cpp.o
[build] ld: symbol(s) not found for architecture x86_64
If I instead link gl3w dynamically rather than statically in CMakeLists.txt, I somehow don't get this error - but running the compiled executable results in a segfault.
It turns out that I wasn't calling gl3wInit(); in main, causing my code to segfault whenever it came across calls to OpenGL functions. Now static linking works just fine!
Related
I have the following error during cargo build of a project using cxx with cmake for compiling a C++ library to be callable in rust.
Here is the error from cargo build:
ld: warning: object file (/usr/local/lib/libwhisper.a(ggml.c.o)) was built for newer macOS version (12.6) than being linked (12.0)
ld: warning: object file (/usr/local/lib/libwhisper.a(whisper.cpp.o)) was built for newer macOS version (12.6) than being linked (12.0)
Undefined symbols for architecture x86_64:
"_cxxbridge1$whisper_init", referenced from:
whisper_rust::interop::ffi::whisper_init::hbcdc3c0c1120a6a9 in whisper_rust-2cf5d7323dfcdb42.1p80ceksqm40omuj.rcgu.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This is my code in interop.rs using cxx::bridge macro:
#[cxx::bridge]
pub mod ffi {
unsafe extern "C++" {
type whisper_token;
type whisper_context;
fn whisper_init(path_model: &CxxString) -> *mut whisper_context; // this line causes the error
}
}
the last function declaration is the faulty one, commenting out the line make me build the project successfully but without interacting with the static C++ library this is useless.
That refers to a function decl. in the header:
struct whisper_context * whisper_init(const char * path_model);
Here's my build.rs:
println!("cargo:rerun-if-changed=src/whisper-cpp/*");
let dst = cmake::build("src/whisper-cpp");
println!("cargo:rustc-link-search=native={}", dst.display());
println!("cargo:rustc-link-lib=static=whisper");
And this is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
project(whisper VERSION 0.1.0)
# add compiler flags
set(CMAKE_CC_FLAGS "${CMAKE_CC_FLAGS} -I. -O3 -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I. -O3 -std=c++11 -pthread")
# platform-dependent compiler flags
...
# add source files
aux_source_directory(. SRC_LIST)
# add library
add_library(${PROJECT_NAME} STATIC ${SRC_LIST})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "whisper.h")
# install
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION lib
PUBLIC_HEADER DESTINATION include)
I'm not sure where my problem lies, I guess this is related the compilation step of CMakeLists but can be also generated by a bad build.rs setup.
I've already tried without success:
rebuilding / clean cache and then rebuilt
including the header file in interop.rs
looking for answers here, google, reddit, etc. for hours
changing the version of OSX required by cmake (this still doesn't make any difference shown in the error, makes me wonder...)
I spent way too hours doing this, I'm still learning FFI and I'll be very thankful if you can help me get out of this mess. Thank you.
EDIT: I updated the system, reinstalled cmake and set file in place of include in build.rs, this fixed the problem.
cxx will generate cpp code for your interop.rs in target/cxxbridge but it seems that you didn't include it in your CMakeLists.txt.
For example,
set(CXXBRIDGE ${CMAKE_CURRENT_SOURCE_DIR}/target/cxxbridge)
add_library(whisper SHARED your_cpp_file.cc ${CXXBRIDGE}/your_project_name/src/bridge.rs.cc)
I was recently following a tutorial for Vulkan called vkguide.dev.
I was on Chapter 1 part 2 called Vulkan Intialization Code(https://vkguide.dev/docs/chapter-1/vulkan_init_code/), this tutorial uses a bootstrap library to intialize Vulkan(https://github.com/charles-lunarg/vk-bootstrap/).
However when I use the library
in the VKBootstrapDispatch.h file, on line 2318 clang/cmake are complaining about VkPipelineInfoEXT not being a valid type. It suggests VkPipelineInfoKHR however when I switch the type, my code says that there are undefined symbols for arm64 and all of these functions relate to the library.
I couldn't find anything about this online, so it would be great if you could help. I'll attach some screenshots.
The errors are:
VkPipelineInfoEXT does not exist
VkPipelineInfoKHR works but then it says vulkan functions are undefined symbols.
This is what is says when I use KHR instead of EXT
_vkDestroyDevice", referenced from:
VulkanEngine::Cleanup() in VkEngine.cpp.o
"_vkDestroyImageView", referenced from:
VulkanEngine::Cleanup() in VkEngine.cpp.o
"_vkDestroyInstance", referenced from:
VulkanEngine::Cleanup() in VkEngine.cpp.o
"_vkDestroySurfaceKHR", referenced from:
VulkanEngine::Cleanup() in VkEngine.cpp.o
"_vkDestroySwapchainKHR", referenced from:
VulkanEngine::Cleanup() in VkEngine.cpp.o
ld: symbol(s) not found for architecture arm64
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY) CMAKE_SOURCE_DIR}/build/debu
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "-std=c++17 -O3")
project(Vulkan-Raytracing-Project)
add_executable(Vulkan-Raytracing
${CMAKE_SOURCE_DIR}/src/main.cpp
${CMAKE_SOURCE_DIR}/src/VkEngine.cpp
${CMAKE_SOURCE_DIR}/lib/vkbootstrap/VkBootstrap.cpp
)
find_package(SDL2 REQUIRED)
find_package(Vulkan REQUIRED)
message(STATUS "Found SDL2")
message(STATUS "Found Vulkan")
# target_link_libraries(Vulkan-Raytracing PUBLIC SDL2 ${CMAKE_DL_LIBS})
target_link_libraries(Vulkan-Raytracing ${SDL2_LIBRARIES} $ {VULKAN_LIBRARIES})
# target_link_directories(Vulkan-Raytracing PUBLIC "${CMAKE_SOURCE_DIR}/lib/SDL")
# target_link_libraries(Vulkan-Raytracing PUBLIC libSDL2maind.a)
# target_link_libraries(Vulkan-Raytracing ${CMAKE_SOURCE_DIR}/lib/SDL/libSDL2maind.a)
target_include_directories(Vulkan-Raytracing PRIVATE
${SDL2_INCLUDE_DIRS}
${VULKAN_INCLUDE_DIRS}
"${CMAKE_SOURCE_DIR}/include"
"${CMAKE_SOURCE_DIR}/src"
"/Users/nick/VulkanSDK/1.3.211.0/macOS/include"
)
Sorry for answering my own question, but it turns out that Vulkan was not getting linked properly, and I included the .dylib that came with the sdk and the build worked.
I was trying to generate a shared library for my project using cmake, unfortunately I got this error
Undefined symbols for architecture x86_64:
"_SDL_Init", referenced from:
_main in main.cpp.o
"_SDL_Quit", 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)
If I'm building a static library it works. This is my cmake file :
cmake_minimum_required(VERSION 3.4.1)
project(yanthra_console VERSION 0.1 DESCRIPTION "A 3d Game Engine.")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -fexceptions")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING "Build type selections" FORCE)
set(THIRD_PARTY_DIR "../../third-party")
set(MAIN_SOURCE_DIR "../main/src")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/out)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib )
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib)
include_directories(${THIRD_PARTY_DIR}/SDL/include)
file(GLOB_RECURSE CPP_HEADERS ${MAIN_SOURCE_DIR}/*.hpp)
file(GLOB_RECURSE CPP_SOURCES ${MAIN_SOURCE_DIR}/*.cpp)
add_library(
yanthra
SHARED
${CPP_HEADERS}
${CPP_SOURCES}
)
add_executable(
yanthra_console
${CPP_HEADERS}
${CPP_SOURCES}
)
set_target_properties(
yanthra_console
PROPERTIES
LINK_FLAGS
"-F../Frameworks -framework SDL2 -framework OpenGL"
)
target_link_libraries(yanthra_console PRIVATE yanthra)
I was able to create a static library with executable.Im using Mulit Configuration to build the project.
Looks like a symbol visibility issue.
By default on clang/gcc symbols are hidden.
There is a cppcon talk that talks about this:
https://www.youtube.com/watch?v=m0DwB4OvDXk&list=PL4s9OdsBXD7aXhgqibbEzf8zAM5eiiENs&index=9
Basically either this library doesn't support being built as a shared library.
Or you need to enable that functionality somehow.
Or just force symbol visibility on.
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)
Here's my simple HelloWorld program
#include <boost/python.hpp>
using namespace boost::python;
void greet() {
// do nothing
}
BOOST_PYTHON_MODULE(HelloWorld)
{
def("greet", greet);
}
and here's my CMakeLists.txt file
cmake_minimum_required(VERSION 2.8.4)
project(HW)
find_package(Boost COMPONENTS python3 REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(${Boost_INCLUDE_DIRS} /Library/Frameworks/Python.framework/Versions/3.4/include/python3.4m include)
file(GLOB_RECURSE SRC
HelloWorld.cpp
)
add_library(HelloWorld SHARED ${SRC})
target_link_libraries(HelloWorld ${Boost_LIBRARIES})
However, I have been unable to build this simple program, with this build error
Undefined symbols for architecture x86_64:
"__Py_NoneStruct", referenced from:
boost::python::detail::none() in HelloWorld.cpp.o
boost::python::api::object::object() in HelloWorld.cpp.o
"boost::python::detail::init_module(PyModuleDef&, void (*)())", referenced from:
_PyInit_HelloWorld in HelloWorld.cpp.o
ld: symbol(s) not found for architecture x86_64
What am I missing? Sorry if this looks like a newbie question but I'm actually stuck.
I think you're missing the a link to the Python library (as opposed to the Boost Python library)
Try something like find_package(Python) then target_link_libraries(HelloWorld ${Python_LIBRARY})
Additionally (based on this post https://www.preney.ca/paul/archives/107) the name of the library you're building doesn't match the name given in BOOST_PYTHON_MODULE. Change it to BOOST_PYTHON_MODULE(libHelloWorld) because cmake implicitly adds a lib to the module name.