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.
Related
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'm trying to set up a project project in Xcode with allegro. I installed allegro5 using homebrew. My CMakeLists.txt is as below:
set(SOURCE_FILES "main.cpp")
add_executable(core ${SOURCE_FILES})
if(WIN32)
# TODO.
else(APPLE)
set(ALLEGRO_INCLUDE "/usr/local/include")
set(ALLEGRO_LIB "/usr/local/lib")
set(ALLEGRO_DYLIB, "/usr/local/lib/*.dylib")
set(ALLEGRO_LINK_FLAGS "-lallegro -lallegro_main")
endif()
include_directories(${ALLEGRO_INCLUDE})
link_directories(${ALLEGRO_LIB})
file(GLOB LIBRARIES ${ALLEGRO_DYLIB})
target_link_libraries(core ${LIBRARIES} ${ALLEGRO_LINK_FLAGS})
However, I keep getting the error: ld: library not found for -lallegro
EDIT:
Edited CMakeLists.txt file:
set(SOURCE_FILES "main.cpp")
add_executable(core ${SOURCE_FILES})
if(WIN32)
# TODO.
else(APPLE)
set(ALLEGRO_INCLUDE "/usr/local/include")
set(ALLEGRO_LIB "/usr/local/lib")
set(ALLEGRO_DYLIB, "/usr/local/lib/*.dylib")
endif()
include_directories(${ALLEGRO_INCLUDE})
link_directories(${ALLEGRO_LIB})
file(GLOB LIBRARIES ${ALLEGRO_DYLIB})
target_link_libraries(core ${LIBRARIES} ${ALLEGRO_DYLIB})
And now I'm getting the error:
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
(maybe you meant: __al_mangled_main)
ld: symbol(s) not found for architecture x86_64
You misunderstood target_link_libraries, you don't set the link flags here, but you indicate the list of libraries you want to target, so that would be:
target_link_libraries(core ${LIBRARIES} ${ALLEGRO_DYLIB})
Otherwise you will get flags like -l-lallegro.
I'm trying to build a C++ executable that uses a Boost library. Building with CMake.
CMake snippet:
find_package(Boost REQUIRED system)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(main src/cpp/main.cpp)
target_link_libraries(main ${BOOST_LIBRARIES})
Getting following CMake build error message:
Undefined symbols for architecture x86_64:
"boost::system::system_category()", referenced from:
...
Why am I getting the error and how can I fix it?
The variables created by the find_package(Boost ...) call you are using are case sensitive, i.e.
${BOOST_LIBRARIES}
will be empty and you need to make sure you are using it like this:
${Boost_LIBRARIES}
The same goes for Boost_INCLUDES which you have used (read: copy-pasted) correctly here:
include_directories(${Boost_INCLUDE_DIRS})
To complete seeekr's answer, you should consider using imported target instead of Boost_ variables:
find_package(Boost REQUIRED system)
add_executable(main ...)
target_link_libraries(main Boost::system)
The imported target will handle linkage, include directories, compile definitions, and all needed stuff with a single call.
I installed boost as well as boost-python, and boost-build using homebrew on my Mac with OS X 10.11.6. I am running Python 3.5.2. boost is set up correctly and works in C++ projects. Both, user-config.jam and the jamfile located in my python extension project directory are ok. I tried to compile a shared library from the following source
#include <iostream>
#include <boost/python.hpp>
using namespace std;
void say_hello() {
std::cout << "HELLO!!!!!";
}
BOOST_PYTHON_MODULE(hello) {
using namespace boost::python;
def ("say_hello", say_hello);
}
using the b2 interpreter. It issues the following command:
"g++" -dynamiclib -Wl,-single_module -install_name "hello.so" -L"/usr/local/lib/python3.5" -o "bin/darwin-4.2.1/release/hello.so" "bin/darwin-4.2.1/release/say_hello.o" -lpython3.5 -headerpad_max_install_names -Wl,-dead_strip -no_dead_strip_inits_and_terms
, which crash with
darwin.link.dll bin/darwin-4.2.1/release/hello.so
Undefined symbols for architecture x86_64:
"typeinfo for boost::python::objects::py_function_impl_base", referenced from:
[...long trace back ...]
"boost::python::detail::init_module(PyModuleDef&, void (*)())", referenced from:
_PyInit_hello in say_hello.o ld: symbol(s) not found for architecture x86_64
I am very aware of all the question concerning similar problems, but unfortunately none of them provides a working answer.
What do I have to do I order to get this simple code working as an Python extension module?
You should link it with boost python library as well( as boost.python is not header only). Here is how boost libraries are include in the build command(paths as I have on my machine):
-L/usr/lib/libpython2.7.dylib /usr/local/lib/libboost_system-mt.dylib /usr/local/lib/libboost_python-mt.dylib /usr/lib/libpython2.7.dylib -Wl,-rpath,/usr/lib/libpython2.7.dylib
I assume you can do without libboost_system library. (Such output I get when run make VERBOSE=1 as I'm not running make explicitly.)
Regarding cmake, here is a simple CMakeLists.txt you can use to build a project with Boost.Python:
cmake_minimum_required(VERSION 2.8)
set(LIBRARY_NAME "ext") # ext for extension
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -ggdb")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(SOURCES
python_interface.cpp
main.cpp
)
set(CMAKE_MACOSX_RPATH ON)
# Get Boost
find_package(Boost COMPONENTS
system
python REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
# Get Python
find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
link_directories(${PYTHON_LIBRARIES})
add_library(${LIBRARY_NAME} SHARED ${SOURCES})
target_link_libraries(${LIBRARY_NAME}
${Boost_LIBRARIES}
${PYTHON_LIBRARIES}
)
I'm testing the CLion IDE, and I'm attempting to write a minimal C++ program. Here's my code:
in main.cpp:
#include "classings.h"
int main() {
classings s;
s.doSomething();
return 0;
}
in classings.h:
class classings {
public:
void doSomething();
};
in classings.cpp:
#include <string>
#include <iostream>
#include "classings.h"
void classings::doSomething() {
std::cout << "hei" << std::endl;
}
I have no clue why this gives me this error:
Undefined symbols for architecture x86_64:
"classings::doSomething()", 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)
I'm on OSX 10.10.
I think that your source files classings.h and classings.cpp are not included within your CMakeLists.txt.
If you open CMakeLists.txt, it should look something like this:
Incomplete CMakeLists.txt
cmake_minimum_required(VERSION 2.8.4)
project(untitled)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp) # your other source files aren't listed
add_executable(my-program ${SOURCE_FILES})
You can fix the problem by including the new source files
Correct CMakeLists.txt
cmake_minimum_required(VERSION 2.8.4)
project(untitled)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp classings.hpp classings.cpp) # manually listing all sources
add_executable(my-program ${SOURCE_FILES})
FYI, you can save yourself the hassle of editing the CMakeLists.txt every time you add/remove a new source file by using the file() or aux_source_directory() command. Here's an example:
set(SOURCE_DIRECTORY "src")
file(GLOB_RECURSE SOURCE_FILES "${SOURCE_DIRECTORY}/*.c" "${SOURCE_DIRECTORY}/*.h"
"${SOURCE_DIRECTORY}/*.cc" "${SOURCE_DIRECTORY}/*.hh"
"${SOURCE_DIRECTORY}/*.cpp" "${SOURCE_DIRECTORY}/*.hpp"
"${SOURCE_DIRECTORY}/*.cxx" "${SOURCE_DIRECTORY}/*.hxx")
add_executable(my-program ${SOURCE_FILES})
Or
aux_source_directory("src" SOURCE_FILES)
add_executable(my-program ${SOURCE_FILES})