Building LLVM pass out of source - undefined symbols - cmake

I'm attempting to build an LLVM pass using the instructions here and link it against the copy of LLVM installed by Julia. The pass is currently being compiled successfully, but cmake fails on linking with undefined symbol errors.
[ 50%] Building CXX object VectorizePass/CMakeFiles/VectorizePass.dir/VectorizePass.cpp.o
[100%] Linking CXX shared module libVectorizePass.so
Undefined symbols for architecture x86_64:
"llvm::raw_ostream::write_escaped(llvm::StringRef, bool)", referenced from:
(anonymous namespace)::Hello::runOnFunction(llvm::Function&) in VectorizePass.cpp.o
"llvm::raw_ostream::write(char const*, unsigned long)", referenced from:
llvm::raw_ostream::operator<<(llvm::StringRef) in VectorizePass.cpp.o
There are dozens of undefined symbol errors followed by
"vtable for llvm::Pass", referenced from:
llvm::Pass::Pass(llvm::PassKind, char&) in VectorizePass.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual
member function has no definition.
VectorizePass.cpp
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
bool runOnFunction(Function &F) override {
errs() << "Hello: ";
errs().write_escaped(F.getName()) << "\n";
return false;
}
};
}
char Hello::ID = 0;
static RegisterPass<Hello> X("Hello", "My Hello World Pass", false, false);
This is exactly as it is in the tutorial.
CMakeLists.txt (1)
add_library(VectorizePass MODULE VectorizePass.cpp)
SET(CMAKE_CXX_FLAGS "-std=c++11 -Wall -fno-rtti -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -fPIC")
CMakeLists.txt (2)
project(VectorizePass)
set(LLVM_DIR "/Users/user/julia5/deps/build/llvm-3.7.1/build_Release")
set(LLVM_TOOLS_BINARY_DIR "/Users/user/julia5/deps/build/llvm-3.7.1/build_Release/Release/bin")
include_directories(${LLVM_INCLUDE_DIRS})
include_directories("/Users/user/julia5/deps/build/llvm-3.7.1/build_Release/include")
include_directories("/Users/user/julia5/deps/srccache/llvm-3.7.1/include")
link_directories("/Users/user/julia5/deps/build/llvm-3.7.1/build_Release/Release/lib")
link_directories("/Users/user/julia5/deps/build/llvm-3.7.1/build_Release/lib")
link_directories(${LLVM_LINK_DIRS})
add_definitions(${LLVM_DEFINITIONS})
add_subdirectory(VectorizePass)
Clearly, for some reason CMake isn't finding the appropriate object files even though they are in the directories that I have in the link_directories statements. What am I missing? I'm fairly new to CMake so it may be something obvious.
I've attempted to include(AddLLVM) as suggested here but CMake reports that it cannot find AddLLVM. This Stack post also suggests using a regular Makefile but that does not work when compiling out-of-source passes as all the paths in the regular LLVM Makefile.common/Makefile.config are relative and don't work at all.

Have you read this? You need to use add_llvm_loadable_module() macro to define target for your pass.

Related

Error when compiling a program that uses Assimp with MinGW in CLion

I'm trying to compile a program in CLion that uses the Assimp library using the MinGW compiler. When building the project it gets up to 77% and gives the following error on the file "SMDLoader.cpp.obj":
C:\Dev\AssimpTest\cmake-build-debug\_deps\assimp-src\code\SMDLoader.cpp: In member function 'void Assimp::SMDImporter::GetAnimationFileList(const string&, Assimp::IOSystem*, std::vector<std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)':
C:\Dev\AssimpTest\cmake-build-debug\_deps\assimp-src\code\SMDLoader.cpp:579:47: error: 'strtok_s' was not declared in this scope
tok1 = strtok_s(&buf[0], "\r\n", &context1);
^
_deps\assimp-build\code\CMakeFiles\assimp.dir\build.make:2246: recipe for target '_deps/assimp-build/code/CMakeFiles/assimp.dir/SMDLoader.cpp.obj' failed
This is the CMakeLists.txt file i'm using:
cmake_minimum_required(VERSION 3.13)
project(AssimpTest)
set(CMAKE_CXX_STANDARD 11)
find_package(assimp 4.1.0 QUIET)
if (NOT assimp_FOUND)
include(FetchContent)
FetchContent_Declare(
assimp
URL https://github.com/assimp/assimp/archive/master.tar.gz
)
FetchContent_GetProperties(raylib)
if (NOT assimp_POPULATED)
set(FETCHCONTENT_QUIET NO)
FetchContent_Populate(assimp)
set(CMAKE_BUILD_TYPE release CACHE STRING "" FORCE)
set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "" FORCE)
add_subdirectory(${assimp_SOURCE_DIR} ${assimp_BINARY_DIR})
endif()
endif()
add_executable(AssimpTest main.cpp)
target_link_libraries(${PROJECT_NAME} assimp)
Here's the main file i'm trying to compile, just in case:
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
int main() {
Assimp::Importer importer;
const char* pFile = R"(C:\Dev\raycast\models\teapot.fbx)";
const aiScene* scene = importer.ReadFile( pFile,
aiProcess_CalcTangentSpace |
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType);
if( !scene)
{
printf(importer.GetErrorString());
return -1;
}
printf("Num meshes: %i", scene->mNumMeshes);
return 0;
}
The main reason i'm trying to use Assimp is to import .fbx models into my program, so if there is any way to optimize all of this setup just for that, that would be really helpful!
The information i found about the usage of this library with MinGW on the internet was really scarce.
Anyway thanks for help in advance.
If you don't need the SMD loader, you can simply disable it. Go to File -> Settings -> Build, Execution, Deployment -> CMake and insert "-DASSIMP_BUILD_SMD_LOADER=NO" (without " ") into CMake options
GCC does not implement the _s functions. The solution is to change the #indef condition at the top of the SMDloader.cpp to check agains _MSC_VER instead of _WIN32:
#ifndef _MSC_VER
#define strtok_s strtok_r
#endif
Which mingw- and assimp-version do you use? Mingw is part of the CI-buildchain we are using to test the assimp-code and this issue shall not occur anymore. So if this issue is on our current master we need to fix it.
And which kind of information do you miss when using mingw? I will try to optimize this.
Thanks!

io_service_open_extended link failure

I'm compiling a code using xcode. IOKit is already included in the "Link Binary with Libraries", but I still get the following errors:
Undefined symbols for architecture x86_64:
"_io_connect_method_scalarI_scalarO"
"_io_service_open_extended"
_main in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
Although those two functions are defined within the program using the following code:
extern "C" kern_return_t io_service_open_extended
(
mach_port_t service,
task_t owningTask,
uint32_t connect_type,
NDR_record_t ndr,
io_buf_ptr_t properties,
mach_msg_type_number_t propertiesCnt,
kern_return_t *result,
mach_port_t *connection
);
extern "C" kern_return_t io_connect_method_scalarI_scalarO(
io_connect_t conn, uint32_t selector,
io_scalar_inband64_t scalar_input,
mach_msg_type_number_t scalar_inputCnt,
io_struct_inband_t inband_output,
mach_msg_type_number_t *inband_outputCnt
);
But those functions can be found in Apple's API reference, and can also be googled.
try this:
set the Build Active Architecture only to NO.

CMake adds -Dlibname_EXPORTS compile definition

CMake adds the following compile definition to all source code files automatically when simply compiling a target:
-Dlibname_EXPORTS
Why is this done and how can I disable it?
cmake add <libname>_EXPORTS macros only for shared libraries. It's useful when exporting API's in Windows DLL.
#if defined(_WINDOWS) && defined(testlib_EXPORTS)
# define API_DLL extern "C" __declspec(dllexport)
#else
# define API_DLL
#endif
API_DLL void foo();
It could be disabled by setting the DEFINE_SYMBOL property of target to empty.
# disable the <libname>_EXPORTS
set_target_properties(sharedlib
PROPERTIES
DEFINE_SYMBOL ""
)
Reference
http://www.cmake.org/cmake/help/v3.0/prop_tgt/DEFINE_SYMBOL.html

Error when declaring a __block variable, "Undefined symbols for architecture x86_64"

Here's a simple program using __block variables:
typedef void (^incrementBlock)(void);
__block int incrementMe = 0;
incrementBlock add_one = ^{
incrementMe++;
};
incrementBlock add_two = ^{
incrementMe++;
incrementMe++;
};
add_one();
add_two();
printf("%d", incrementMe);
When I compile this, I get this error:
Undefined symbols for architecture x86_64: "___objc_personality_v0",
referenced from:
_main in test-b0a9a6.o
Dwarf Exception Unwind Info (__eh_frame) in test-b0a9a6.o ld: symbol(s) not found for architecture x86_64 clang: error: linker
command failed with exit code 1 (use -v to see invocation)
It definitely is a problem with declaring incrementMeas a __block int, when I comment it out it works.
I tried compiling with gcc and it also didn't work.
I got this example more or less straight from a book so it should work.
Is my declaration deprecated? Should I be declaring a mutable block variable differently?
Your code is fine, you just need to make sure to link with the Objective-C runtime library. Add -lobjc to your linker command line and you should be good.

Why do static functions eliminate undefined symbols in Xcode?

I am attempting to use I/O kit and have linked to I/O kit properly.
When I use a function in I/O kit and don't call it within a static function, I get the following error Undefined symbols for architecture x86_64.
Here is an example to suppress the error
static void test(void)
{
if (IORegisterForSystemPower(...))
{
}
}
Here is an example that will cause the error.
void test(void)
{
if (IORegisterForSystemPower(...))
{
}
}
Any suggestions as to why this is happening?
EDIT:
Here are the exact error messages:
Undefined symbols for architecture x86_64:
"_IORegisterForSystemPower", referenced from:
_registerNotificaitonUsingIOKit in AppDelegate.o
"_IONotificationPortGetRunLoopSource", referenced from:
_registerNotificaitonUsingIOKit in AppDelegate.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Okay I got one scenario when this can happen. If the static function is never called, you won't get that link time error.
For example, I wrote a simple c file with this function, and undef_foobar is not defined:
static int foobar (void)
{
undef_foobar ();
}
Now, if foobar() is called from my main(), I get the error:
Undefined symbols for architecture x86_64:
"_undef_foobar", referenced from:
If the function isn't called at all from within this c file, there are no linker errors.