I'm trying to compile ffmpeg with h264 support as an external cmake project. But after compile it, I'm getting libavcodec reference errors.
The compile problem is occurring on Ubuntu 18.04 machine. I have installed all dependencies for ffmpeg and also libx264-dev.
Cmake external project
set( proj ffmpeg )
set( SHARED_FFMPEG )
set(BASIC
--extra-ldflags=-L/usr/local/lib
--extra-cflags=-I/usr/local/include
--enable-gpl
--enable-libx264)
option( FFMPEG_GPL "Use a GPL version of FFMPEG" OFF )
set(FFMPEG_INSTALL_DIR ${CMAKE_BINARY_DIR}/INSTALL )
ExternalProject_Add(${proj}
# Set up dirs
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}
INSTALL_DIR ${FFMPEG_INSTALL_DIR}
# get the project
GIT_REPOSITORY "https://github.com/FFmpeg/FFmpeg.git"
GIT_TAG "n3.2.13"
# Build the project
BUILD_IN_SOURCE 1
# Configure step
# DO STH FOR THE ARCHITECTURE...
CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=${FFMPEG_INSTALL_DIR} ${SHARED_FFMPEG} ${FFMPEG_GPL_FLAG} ${BASIC}
# BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} -j${NProcessors}
)
# define the library suffix
if( SUPER_SHARED_LIBS )
if( APPLE )
set(LIBRARY_SUFFIX .dylib)
else( APPLE )
set(LIBRARY_SUFFIX .so)
endif( APPLE )
else( SUPER_SHARED_LIBS )
set(LIBRARY_SUFFIX .a)
endif( SUPER_SHARED_LIBS )
# ADD DIRECTORIES FOR DEPENDENCIES IN Main/CMakeLists.txt
set( FFMPEG_LIBRARYS libavcodec.a
libavformat.a
libavutil.a
libswscale.a
)
include_directories(${FFMPEG_INSTALL_DIR}/include)
set(FFMPEG_LIBRARY_DIRS ${FFMPEG_INSTALL_DIR}/lib/)
link_directories(${FFMPEG_LIBRARY_DIRS})
C++ Where I used the library
extern "C" {
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/mathematics.h"
#include "libswscale/swscale.h"
#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
}
...
fReceiveBuffer = new u_int8_t[DUMMY_SINK_RECEIVE_BUFFER_SIZE];
fReceiveBufferAV = new u_int8_t[DUMMY_SINK_RECEIVE_BUFFER_SIZE+4];
fReceiveBufferAV[0] = 0;
fReceiveBufferAV[1] = 0;
fReceiveBufferAV[2] = 0;
fReceiveBufferAV[3] = 1;
av_init_packet(&avpkt);
avpkt.flags |= AV_PKT_FLAG_KEY;
avpkt.pts = avpkt.dts = 0;
av_init_packet(&avpkt);
avpkt.flags |= AV_PKT_FLAG_KEY;
avpkt.pts = avpkt.dts = 0;
/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
//codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
codec = avcodec_find_decoder(AV_CODEC_ID_H264);
...
Error:
[100%] Linking CXX executable ../../bin/awesom-o
/home/tiburcio/CLionProjects/awesom-o/cmake-build-debug/INSTALL/lib/libavcodec.a(libx264.o): In function `X264_frame':
/home/tiburcio/CLionProjects/awesom-o/cmake-build-debug/ffmpeg/libavcodec/libx264.c:280: undefined reference to `x264_picture_init'
/home/tiburcio/CLionProjects/awesom-o/cmake-build-debug/INSTALL/lib/libavcodec.a(libx264.o): In function `reconfig_encoder':
/home/tiburcio/CLionProjects/awesom-o/cmake-build-debug/ffmpeg/libavcodec/libx264.c:266: undefined reference to `x264_encoder_reconfig'
/home/tiburcio/CLionProjects/awesom-o/cmake-build-debug/INSTALL/lib/libavcodec.a(libx264.o): In function `X264_frame':
/home/tiburcio/CLionProjects/awesom-o/cmake-build-debug/ffmpeg/libavcodec/libx264.c:340: undefined reference to `x264_encoder_encode'
Related
I'm writing a simple proof of concept app that integrates OpenSSL using NDK. Unfortunately, it gives me undefined reference errors during build.
What I did:
Cross-compiled OpenSSL for Android (x86_64 is shown, and similarly for other ABIs):
openssl-1.1.1q $ ./Configure android-x86_64
openssl-1.1.1q $ make
openssl-1.1.1q $ cp libssl.a <path_to_project_cpp_dir>/libs/x86_64/
openssl-1.1.1q $ cp -r ./include/openssl <path_to_project_cpp_dir>/libs/include/
Added the following CMakeLists.txt into project's cpp dir:
cmake_minimum_required(VERSION 3.18.1)
project("ndk-poc")
add_library(
# Sets the name of the library.
ndk-poc
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
ndk-poc.cpp)
find_library(
# Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that you want CMake to locate.
log)
add_library(libssl STATIC IMPORTED)
set_target_properties(
# Specifies the target library.
libssl
# Specifies the parameter you want to define.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libssl.a )
include_directories(${CMAKE_SOURCE_DIR}/libs/include/)
target_link_libraries(
# Specifies the target library.
ndk-poc
# Links the target library to the log library
# included in the NDK.
libssl
${log-lib})
And this is my test ndk-poc.cpp:
#include <jni.h>
#include <string>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
extern "C" JNIEXPORT jstring JNICALL
Java_com_techyourchance_android_screens_home_HomeFragment_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
/* Testing OPENSSL prime generation and BigNum. */
BIGNUM *prime1 = NULL;
int bits = 16; /* Number of bits for the generated prime. */
int safe = 0;
prime1 = BN_new();
if (prime1 == NULL) {
printf("Out of memory.\n");
} else if (BN_generate_prime_ex(prime1, bits, safe, NULL, NULL, NULL)) {
printf("Success!\n");
int len;
len = BN_num_bytes(prime1);
unsigned char* buffer;
buffer = static_cast<unsigned char*>(malloc(len));
if (!buffer) {
printf("Out of memory allocating buffer.\n");
} else {
int wlen;
wlen = BN_bn2bin(prime1, buffer);
printf("Wrote %d bytes.\n", wlen);
int i;
for(i=0;i<wlen;++i) {
printf("Byte %d of buffer = %d.\n", i, buffer[i]);
}
free(buffer);
char* st;
st = BN_bn2dec(prime1);
printf("Prime = %s.\n", st);
OPENSSL_free(st);
}
} else {
printf("Error generating prime.\n");
}
std::string result = "Test completed!";
return env->NewStringUTF(result.c_str());
}
Results:
I don't see any errors inside Android Studio, but when I try building the project, all usages of OpenSSL's APIs in my test code result in unresolved reference errors:
...
C:/Users/Vasiliy/projects/ndk-poc/app/src/main/cpp/ndk-poc.cpp:38: error: undefined reference to 'BN_bn2dec'
C:/Users/Vasiliy/projects/ndk-poc/app/src/main/cpp/ndk-poc.cpp:40: error: undefined reference to 'CRYPTO_free'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
What did I miss?
OpenSSL consists of (at least) two libraries: libcrypto which has the general-purpose cryptographic functions; and libssl which is a TLS implementation built on top of libcrypto.
So in your case libcrypto would be the appropriate library to link against.
I'm working with a slam system, i've install dso, which the code can be seen here::
https://github.com/JakobEngel/dso
Everything works fine, I manage to compile and run without errors. But know I want to parallelize the code, using CUDA. I'm having lot's of trouble adapting it's CMakeLists.txt in order to be able to use CUDA. The original CMakeLists from dso is available here:
dso CMakeLists.txt
I'm trying to adapt it basing my changes on this implementation of another author on another SLAM system:
ORB SLAM 2 CMakeLists.txt using CUDA
Right now my CMakeLists, with my changes (not working), is like this:
SET(PROJECT_NAME DSO)
PROJECT(${PROJECT_NAME})
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
#set(CMAKE_VERBOSE_MAKEFILE ON)
set(BUILD_TYPE Release)
#set(BUILD_TYPE RelWithDebInfo)
set(EXECUTABLE_OUTPUT_PATH bin)
set(LIBRARY_OUTPUT_PATH lib)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
# required libraries
#SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "/usr/include")
find_package(SuiteParse REQUIRED)
find_package(Eigen3 REQUIRED)
find_package(Boost)
# optional libraries
find_package(LibZip QUIET)
find_package(Pangolin 0.2 QUIET)
find_package(OpenCV QUIET)
#find_package(OpenACC)
# flags
add_definitions("-DENABLE_SSE")
set(CMAKE_CXX_FLAGS
"${SSE_FLAGS} -O3 -g -std=c++11"
)
set(CMAKE_C_FLAGS
"${SSE_FLAGS} -O3 -g -std=c++11"
)
#LIST(APPEND CMAKE_C_FLAGS "-Wall -Wextra -DUSE_NVTX") <<<< Error: doesn't recognize -Wall -Wextra
#LIST(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -DUSE_NVTX") << Error: doesn't recognize -Wall -Wextra
find_package(CUDA REQUIRED)
set(CUDA_PROPAGATE_HOST_FLAGS OFF)
SET(CUDA_HOST_COMPILER /usr/bin/g++)
LIST(APPEND CUDA_NVCC_FLAGS "--compiler-options -fno-strict-aliasing -use_fast_math -ccbin gcc-5")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -std=c++11")
if (MSVC)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
endif (MSVC)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY lib)
cuda_include_directories(
${CUDA_TOOLKIT_ROOT_DIR}/samples/common/inc
)
# Sources files
set(dso_SOURCE_FILES
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystem.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystemOptimize.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystemOptPoint.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystemDebugStuff.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/FullSystemMarginalize.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/Residuals.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/CoarseTracker.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/CoarseInitializer.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/ImmaturePoint.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/HessianBlocks.cpp
${PROJECT_SOURCE_DIR}/src/FullSystem/PixelSelector2.cpp
${PROJECT_SOURCE_DIR}/src/OptimizationBackend/EnergyFunctional.cpp
${PROJECT_SOURCE_DIR}/src/OptimizationBackend/AccumulatedTopHessian.cpp
${PROJECT_SOURCE_DIR}/src/OptimizationBackend/AccumulatedSCHessian.cpp
${PROJECT_SOURCE_DIR}/src/OptimizationBackend/EnergyFunctionalStructs.cpp
${PROJECT_SOURCE_DIR}/src/util/settings.cpp
${PROJECT_SOURCE_DIR}/src/util/Undistort.cpp
${PROJECT_SOURCE_DIR}/src/util/globalCalib.cpp
)
include_directories(
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/thirdparty/Sophus
${PROJECT_SOURCE_DIR}/thirdparty/sse2neon
${EIGEN3_INCLUDE_DIR}
)
# decide if we have pangolin
if (Pangolin_FOUND)
message("--- found PANGOLIN, compiling dso_pangolin library.")
include_directories( ${Pangolin_INCLUDE_DIRS} )
set(dso_pangolin_SOURCE_FILES
${PROJECT_SOURCE_DIR}/src/IOWrapper/Pangolin/KeyFrameDisplay.cpp
${PROJECT_SOURCE_DIR}/src/IOWrapper/Pangolin/PangolinDSOViewer.cpp)
set(HAS_PANGOLIN 1)
else ()
message("--- could not find PANGOLIN, not compiling dso_pangolin library.")
message(" this means there will be no 3D display / GUI available for dso_dataset.")
set(dso_pangolin_SOURCE_FILES )
set(HAS_PANGOLIN 0)
endif ()
# decide if we have openCV
if (OpenCV_FOUND)
message("--- found OpenCV, compiling dso_opencv library.")
include_directories( ${OpenCV_INCLUDE_DIRS} )
set(dso_opencv_SOURCE_FILES
${PROJECT_SOURCE_DIR}/src/IOWrapper/OpenCV/ImageDisplay_OpenCV.cpp
${PROJECT_SOURCE_DIR}/src/IOWrapper/OpenCV/ImageRW_OpenCV.cpp)
set(HAS_OPENCV 1)
else ()
message("--- could not find OpenCV, not compiling dso_opencv library.")
message(" this means there will be no image display, and image read / load functionality.")
set(dso_opencv_SOURCE_FILES
${PROJECT_SOURCE_DIR}/src/IOWrapper/ImageDisplay_dummy.cpp
${PROJECT_SOURCE_DIR}/src/IOWrapper/ImageRW_dummy.cpp)
set(HAS_OPENCV 0)
endif ()
# decide if we have ziplib.
if (LIBZIP_LIBRARY)
message("--- found ziplib (${LIBZIP_VERSION}), compiling with zip capability.")
add_definitions(-DHAS_ZIPLIB=1)
include_directories( ${LIBZIP_INCLUDE_DIR_ZIP} ${LIBZIP_INCLUDE_DIR_ZIPCONF} )
else()
message("--- not found ziplib (${LIBZIP_LIBRARY}), compiling without zip capability.")
set(LIBZIP_LIBRARY "")
endif()
# compile main library.
include_directories( ${CSPARSE_INCLUDE_DIR} ${CHOLMOD_INCLUDE_DIR})
cuda_add_library(dso SHARED ${dso_SOURCE_FILES} ${dso_opencv_SOURCE_FILES} ${dso_pangolin_SOURCE_FILES}
${PROJECT_SOURCE_DIR}/src/teste.cu
)
#set_property( TARGET dso APPEND_STRING PROPERTY COMPILE_FLAGS -Wall )
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # OSX
set(BOOST_THREAD_LIBRARY boost_thread-mt)
else()
set(BOOST_THREAD_LIBRARY boost_thread)
endif()
# build main executable (only if we have both OpenCV and Pangolin)
if (OpenCV_FOUND AND Pangolin_FOUND)
message("--- compiling dso_dataset.")
add_executable(dso_dataset ${PROJECT_SOURCE_DIR}/src/main_dso_pangolin.cpp)
target_link_libraries(dso_dataset dso boost_system cxsparse ${BOOST_THREAD_LIBRARY} ${LIBZIP_LIBRARY} ${Pangolin_LIBRARIES} ${OpenCV_LIBS})
else()
message("--- not building dso_dataset, since either don't have openCV or Pangolin.")
endif()
unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
So, 'main_dso_pangolin.cpp' is my main file. At this point, with only this changes the code compiles. But i wanted to try if i was able to make some CUDA code. In order to do this I created a 'teste.cu' file, that has the same code as one of the cuda samples, like this:
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
// CUDA runtime
#include </usr/local/cuda-9.0/include/cuda_runtime.h>
#include <cuda.h>
// helper functions and utilities to work with CUDA
#include </usr/local/cuda-9.0/samples/common/inc/helper_functions.h>
#include </usr/local/cuda-9.0/samples/common/inc/helper_cuda.h>
__global__ static void timedReduction(const float *input, float *output, clock_t *timer)
{
// __shared__ float shared[2 * blockDim.x];
extern __shared__ float shared[];
const int tid = threadIdx.x;
const int bid = blockIdx.x;
if (tid == 0) timer[bid] = clock();
// Copy input.
shared[tid] = input[tid];
shared[tid + blockDim.x] = input[tid + blockDim.x];
// Perform reduction to find minimum.
for (int d = blockDim.x; d > 0; d /= 2)
{
__syncthreads();
if (tid < d)
{
float f0 = shared[tid];
float f1 = shared[tid + d];
if (f1 < f0)
{
shared[tid] = f1;
}
}
}
// Write result.
if (tid == 0) output[bid] = shared[0];
__syncthreads();
if (tid == 0) timer[bid+gridDim.x] = clock();
}
#define NUM_BLOCKS 64
#define NUM_THREADS 256
void xx(int argc, char** argv){
printf("CUDA Clock sample\n");
// This will pick the best possible CUDA capable device
int dev = findCudaDevice(argc, (const char **)argv);
float *dinput = NULL;
float *doutput = NULL;
clock_t *dtimer = NULL;
clock_t timer[NUM_BLOCKS * 2];
float input[NUM_THREADS * 2];
for (int i = 0; i < NUM_THREADS * 2; i++)
{
input[i] = (float)i;
}
checkCudaErrors(cudaMalloc((void **)&dinput, sizeof(float) * NUM_THREADS * 2));
checkCudaErrors(cudaMalloc((void **)&doutput, sizeof(float) * NUM_BLOCKS));
checkCudaErrors(cudaMalloc((void **)&dtimer, sizeof(clock_t) * NUM_BLOCKS * 2));
checkCudaErrors(cudaMemcpy(dinput, input, sizeof(float) * NUM_THREADS * 2, cudaMemcpyHostToDevice));
timedReduction<<<NUM_BLOCKS, NUM_THREADS, sizeof(float) * 2 *NUM_THREADS>>>(dinput, doutput, dtimer);
checkCudaErrors(cudaMemcpy(timer, dtimer, sizeof(clock_t) * NUM_BLOCKS * 2, cudaMemcpyDeviceToHost));
checkCudaErrors(cudaFree(dinput));
checkCudaErrors(cudaFree(doutput));
checkCudaErrors(cudaFree(dtimer));
long double avgElapsedClocks = 0;
for (int i = 0; i < NUM_BLOCKS; i++)
{
avgElapsedClocks += (long double) (timer[i + NUM_BLOCKS] - timer[i]);
}
avgElapsedClocks = avgElapsedClocks/NUM_BLOCKS;
printf("Average clocks/block = %Lf\n", avgElapsedClocks);
}
And in my main, the first thing i do is to call this function. This time, when i do 'cmake' and 'make i get errors like:
/home/cesar/Documents/dso/src/teste.cu:18:21: error: ‘threadIdx’ was not declared in this scope
const int tid = threadIdx.x;
/home/cesar/Documents/dso/src/teste.cu:19:21: error: ‘blockIdx’ was not declared in this scope
const int bid = blockIdx.x;
I've install CUDA Toolkit correctly, but here is the version:
cesar#cesar-X550JX:/usr/local/cuda/bin$ /usr/local/cuda/bin/nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Sep__1_21:08:03_CDT_2017
Cuda compilation tools, release 9.0, V9.0.176
What do you think i'm doing wrong or i'm missing? I'm having many difficulties adapting CMakeLists.txt due to its complexity and well defined structure.
--- EDIT ---
Running with make -j VERBOSE=1 i get this messages which tells me that a regular c++ compiler is being used:
/usr/bin/c++ -fPIC -O3 -g -std=c++11 -D_FORCE_INLINES -shared -Wl,-soname,libdso.so -o lib/libdso.so CMakeFiles/dso.dir/src/FullSystem/FullSystem.cpp.o CMakeFiles/dso.dir/src/FullSystem/FullSystemOptimize.cpp.o CMakeFiles/dso.dir/src/FullSystem/FullSystemOptPoint.cpp.o CMakeFiles/dso.dir/src/FullSystem/FullSystemDebugStuff.cpp.o CMakeFiles/dso.dir/src/FullSystem/FullSystemMarginalize.cpp.o CMakeFiles/dso.dir/src/FullSystem/Residuals.cpp.o CMakeFiles/dso.dir/src/FullSystem/CoarseTracker.cpp.o CMakeFiles/dso.dir/src/FullSystem/CoarseInitializer.cpp.o CMakeFiles/dso.dir/src/FullSystem/ImmaturePoint.cpp.o CMakeFiles/dso.dir/src/FullSystem/HessianBlocks.cpp.o CMakeFiles/dso.dir/src/FullSystem/PixelSelector2.cpp.o CMakeFiles/dso.dir/src/OptimizationBackend/EnergyFunctional.cpp.o CMakeFiles/dso.dir/src/OptimizationBackend/AccumulatedTopHessian.cpp.o CMakeFiles/dso.dir/src/OptimizationBackend/AccumulatedSCHessian.cpp.o CMakeFiles/dso.dir/src/OptimizationBackend/EnergyFunctionalStructs.cpp.o CMakeFiles/dso.dir/src/util/settings.cpp.o CMakeFiles/dso.dir/src/util/Undistort.cpp.o CMakeFiles/dso.dir/src/util/globalCalib.cpp.o CMakeFiles/dso.dir/src/IOWrapper/OpenCV/ImageDisplay_OpenCV.cpp.o CMakeFiles/dso.dir/src/IOWrapper/OpenCV/ImageRW_OpenCV.cpp.o CMakeFiles/dso.dir/src/IOWrapper/Pangolin/KeyFrameDisplay.cpp.o CMakeFiles/dso.dir/src/IOWrapper/Pangolin/PangolinDSOViewer.cpp.o CMakeFiles/dso.dir/src/dso_generated_teste.cu.o /usr/local/cuda/lib64/libcudart_static.a -lpthread -ldl -lrt
[ 96%] Building CXX object CMakeFiles/dso_dataset.dir/src/main_dso_pangolin.cpp.o
/usr/bin/c++ -DENABLE_SSE -DHAS_ZIPLIB=1 -I/usr/include/opencv -I/home/cesar/Documents/dso/src -I/home/cesar/Documents/dso/thirdparty/Sophus -I/home/cesar/Documents/dso/thirdparty/sse2neon -I/usr/include/eigen3 -I/home/cesar/Documents/Pangolin/include -I/home/cesar/Documents/Pangolin/build/src/include -I/usr/local/include -I/usr/include/suitesparse -I/usr/local/cuda/include -O3 -g -std=c++11 -D_FORCE_INLINES -o CMakeFiles/dso_dataset.dir/src/main_dso_pangolin.cpp.o -c /home/cesar/Documents/dso/src/main_dso_pangolin.cpp
I also tried to separate .cpp files from .cu files, used add_library for .cpp and cuda_add_library for .cu files, like this:
add_library(dso ${dso_SOURCE_FILES} ${dso_opencv_SOURCE_FILES} ${dso_pangolin_SOURCE_FILES})
cuda_add_library(my_cuda_lib ${PROJECT_SOURCE_DIR}/src/teste.cu)
And then use my_cuda_lib in target_link_libraries, like this:
target_link_libraries(dso_dataset dso boost_system cxsparse ${BOOST_THREAD_LIBRARY} ${LIBZIP_LIBRARY} ${Pangolin_LIBRARIES} ${OpenCV_LIBS} ${CUDA_LIBRARIES} my_cuda_lib)
But still got the same errors.
-- EDIT: MCVE ---
To demonstrate my error i created a simple example. I have 2 simple files, my main which is a .cpp and my cuda file .cu. My main just calls the function on the other file, looks like this:
#include <iostream>
#include "hello_world.cu"
using namespace std;
int main()
{
teste();
return 0;
}
And my .cu file looks like this:
#include <stdio.h>
#include <iostream>
// CUDA runtime
#include </usr/local/cuda-9.0/include/cuda_runtime.h>
// helper functions and utilities to work with CUDA
#include </usr/local/cuda-9.0/samples/common/inc/helper_functions.h>
#include </usr/local/cuda-9.0/samples/common/inc/helper_cuda.h>
__global__ void kernel (void){
extern __shared__ float shared[];
const int tid = threadIdx.x;
const int bid = blockIdx.x;
}
int teste( void ) {
kernel<<<1,1>>>();
printf( "Hello, World!\n" );
return 0;
}
My CMakeLists.txt that i made to compile this looks like this:
cmake_minimum_required(VERSION 2.8)
set(CUDA_HOST_COMPILER /usr/bin/g++-5)
find_package(CUDA QUIET REQUIRED)
# Pass options to NVCC
set(
CUDA_NVCC_FLAGS
${CUDA_NVCC_FLAGS};
-O3
)
# For compilation ...
# Specify target & source files to compile it from
cuda_add_executable(
helloworld
hello_world.cu
teste.cpp
)
After making cmake and running with "cmake --build ." (i don't know why it has to be this command, normally i just do make -j, but in this example only this works) i get the same errors as in my project, ‘threadIdx’ was not declared in this scope, same for 'blockIdx' etc..
Since you are including hello_world.cu file in your main code, then you want to have it compiled with nvcc compiler. To achieve this change name of teste.cpp file to teste.cu (otherwise g++ will be used).
Also remove 'hello_world.cu' from CMakeLists.txt (it is included already in teste file) to have something like this:
cuda_add_executable(
helloworld
teste.cu
)
Then it should work.
-- EDIT: Additional question --
If you want to keep your .cpp file then you need kind of separation between what g++ can do for you and what nvcc should. So you can introduce to your project additional hello_world.h file:
#ifndef HELLO_WORLD_H
#define HELLO_WORLD_H
int teste();
#endif
include it in your teste.cpp:
#include <iostream>
#include "hello_world.h"
using namespace std;
int main()
{
teste();
return 0;
}
and then your CMakeLists.txt looks like in your original example:
...
cuda_add_executable(
helloworld
teste.cpp
hello_world.cu
)
In such a case hello_world.cu will be compiled with nvcc, and then compilling and linking of teste.cpp will be done by g++ (which will be possible in that case since there is no CUDA code in teste.cpp).
I am using ROS Kinetic and trying to write a program that would read two videos and publish them on two different topics. But I think I've made some mistake in linking OpenCV libraries. I am getting the following errors.
CMakeFiles/src.dir/src/src.cpp.o: In function `main':
src.cpp:(.text+0x3fd): undefined reference to `cv_bridge::CvImage::toImageMsg() const'
src.cpp:(.text+0x56d): undefined reference to `cv_bridge::CvImage::toImageMsg() const'
collect2: error: ld returned 1 exit status
MultiCamImages/CMakeFiles/src.dir/build.make:165: recipe for target 'MultiCamImages/src' failed
make[2]: *** [MultiCamImages/src] Error 1
CMakeFiles/Makefile2:1089: recipe for target 'MultiCamImages/CMakeFiles/src.dir/all' failed
make[1]: *** [MultiCamImages/CMakeFiles/src.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j4 -l4" failed
This is my source file:
#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <image_transport/image_transport.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char** argv){
ros::init(argc, argv, "PublishMultiCamImages");
ros::NodeHandle nh;
image_transport::ImageTransport it(nh);
image_transport::Publisher pub1 = it.advertise("/camera/image_raw1", 1);
image_transport::Publisher pub2 = it.advertise("/camera/image_raw2", 1);
cv::Mat im;
cv::String Path1("/home/akanksha/COSLAM_Dataset/EA-01/grayscale/*.jpg");
cv::String Path2("/home/akanksha/COSLAM_Dataset/EA-02/grayscale/*.jpg");
//time = ros::Time::now();
vector<cv::String> fn1;
vector<cv::String> fn2;
cv::glob(Path1,fn1, true); // recurse
cv::glob(Path2,fn2, true);
ros::Rate r(50);
int l1 = fn1.size();
int l2 = fn2.size();
int count1 = 0, count2 = 0;
bool flag;
while(ros::ok()){
flag = true;
if(count1 < l1){
cv::Mat image1 = cv::imread(fn1[count1]);
sensor_msgs::ImagePtr msg1 = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image1).toImageMsg();
pub1.publish(msg1);
count1++;
flag = false;
}
if(count2 < l2){
cv::Mat image2 = cv::imread(fn2[count2]);
sensor_msgs::ImagePtr msg2 = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image2).toImageMsg();
pub2.publish(msg2);
count2++;
flag = false;
}
if(flag)
break;
r.sleep();
}
ros::shutdown();
return 0;
}
This is my CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(MultiCamImages)
find_package(catkin REQUIRED COMPONENTS
roscpp
image_transport
OpenCV
)
# find_package(OpenCV REQUIRED)
set(OpenCV_LIBS opencv_core opencv_imgproc opencv_calib3d opencv_video opencv_features2d opencv_ml opencv_highgui opencv_objdetect)
add_executable(src src/src.cpp)
target_link_libraries(src ${catkin_LIBRARIES} ${OpenCV_LIBS})
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES MultiCamImages
# CATKIN_DEPENDS roscpp
# DEPENDS system_lib
)
include_directories(
${catkin_INCLUDE_DIRS}
)
And this is my pakage.xml
<?xml version="1.0"?>
<package>
<name>MultiCamImages</name>
<version>0.0.0</version>
<description>The MultiCamImages package</description>
<maintainer email="akanksha#todo.todo">akanksha</maintainer>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<run_depend>roscpp</run_depend>
<build_depend>sensor_msgs</build_depend>
<run_depend>sensor_msgs</run_depend>
<build_depend>cv_bridge</build_depend>
<run_depend>cv_bridge</run_depend>
</package>
If you could point out the problem that would be a great help. Thanks!
It doesn't look like you are linking cv_bridge in the cmake file. Maybe you want this:
find_package(catkin REQUIRED COMPONENTS
cv_bridge
roscpp
image_transport
OpenCV
)
Actually the way Joseph uses OpenCV libraries for linking is not right, since OpenCV does not belong to the standard package of ROS as with cv_bridge. In this case, you need to separately use find_package for OpenCV as with boost like this:
find_package(OpenCV REQUIRED)
# Or you may add specific major portion of OpenCV version, e.g., OpenCV3
find_package(OpenCV 3 REQUIRED)
I am using the cmakelists.txt below, that exists in the top folder of my project, and I am trying to connect mpg123 and ao to my project. In one .cpp file of the source folder I added a code with mpg123 and ao to play a song. This code can be compiled with this line:
g++ mpg.cpp -lmpg123 -lao -o mpg
I also added this line:
target_link_libraries(emotime ${LIBAO_LIBRARIES} ${MPG123_LIBRARIES})
in the cmakelists that exists in my source folder. When I am running make I get errors like "undefined reference to ao_initialize'" and "undefined reference tompg123_init'" in this piece of code:
int playaudio(int trackid)
{
char * traklink="";
int tid=trackid;
if (tid==1){
traklink= "/home/mixa/tutti_frutti.wav";
}
else if (tid==2){
traklink= "/home/mixa/karavi.wav";
}
else if (tid==3){
traklink= "/home/mixa/timon.wav";
}
else if (tid==4){
traklink= "/home/mixa/hippo.wav";
}
else{
traklink= "/home/mixa/nanourisma.wav";
}
mpg123_handle *mh;
unsigned char *buffer;
size_t buffer_size;
size_t done;
int err;
int driver;
ao_device *dev;
ao_sample_format format;
int channels, encoding;
long rate;
/* if(argc < 2)
exit(0);
*/
/* initializations */
ao_initialize();
driver = ao_default_driver_id();
mpg123_init();
mh = mpg123_new(NULL, &err);
buffer_size = mpg123_outblock(mh);
buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char));
/* open the file and get the decoding format */
//mpg123_open(mh,traklink);
mpg123_open(mh,traklink);
mpg123_getformat(mh, &rate, &channels, &encoding);
/* set the output format and open the output device */
format.bits = mpg123_encsize(encoding) * BITS;
format.rate = rate;
format.channels = channels;
format.byte_format = AO_FMT_NATIVE;
format.matrix = 0;
dev = ao_open_live(driver, &format, NULL);
/* decode and play */
while (mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK)
//ao_play(dev, buffer, done);
ao_play(dev, (char*)buffer, done);
/* clean up */
free(buffer);
ao_close(dev);
mpg123_close(mh);
mpg123_delete(mh);
mpg123_exit();
ao_shutdown();
//system("mpg123 -q traklink");
// return 0;
}
void *threading (void *trackid)
{
long tid=(long)trackid;
cout<<"sound plays on:Thread id, "<<tid<<endl;
playaudio(tid);
pthread_exit(NULL);
}
cmakelists:
cmake_minimum_required(VERSION 2.8)
project(emotime)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
FIND_PATH( MPG123_INCLUDE_DIR1
NAMES mpg123.h
PATH_SUFFIXES include
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
extern/mpg123/ports/MSVC++
extern/mpg123/ports/Xcode
)
IF( MPG123_INCLUDE_DIR1 )
SET( MPG123_INCLUDE_DIRS ${MPG123_INCLUDE_DIRS} ${MPG123_INCLUDE_DIR1} )
ENDIF( MPG123_INCLUDE_DIR1 )
# Include dir (May not be necessary on all platforms)
FIND_PATH( MPG123_INCLUDE_DIR2
NAMES mpg123.h.in
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
extern/mpg123/src/libmpg123
)
IF( MPG123_INCLUDE_DIR2 )
SET( MPG123_INCLUDE_DIRS ${MPG123_INCLUDE_DIRS} ${MPG123_INCLUDE_DIR2} )
ENDIF( MPG123_INCLUDE_DIR2 )
#MESSAGE( "MPG123_INCLUDE_DIR1: " ${MPG123_INCLUDE_DIR1} )
#MESSAGE( "MPG123_INCLUDE_DIR2: " ${MPG123_INCLUDE_DIR2} )
#MESSAGE( "MPG123_INCLUDE_DIRS: " ${MPG123_INCLUDE_DIRS} )
FIND_LIBRARY( MPG123_LIBRARIES
NAMES mpg123 libmpg123.lib
HINTS
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64 Release Debug
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw
/opt/local
/opt/csw
/opt
extern/mpg123/ports/MSVC++/2005
extern/mpg123/ports/MSVC++/2008
extern/mpg123/ports/MSVC++/2008clr
extern/mpg123/ports/MSVC++/2010
)
SET( MPG123_FOUND 0 )
IF( MPG123_LIBRARIES AND MPG123_INCLUDE_DIRS )
SET( MPG123_FOUND 1 )
MESSAGE( STATUS "mpg123 found!" )
ELSE( MPG123_LIBRARIES AND MPG123_INCLUDE_DIRS )
MESSAGE( STATUS "mpg123 not found..." )
ENDIF( MPG123_LIBRARIES AND MPG123_INCLUDE_DIRS )
FIND_PATH(LIBAO_INCLUDE_DIR ao.h /usr/include/ao /usr/local/include/ao)
FIND_LIBRARY(LIBAO_LIBRARIES NAMES ao PATH /usr/lib /usr/local/lib)
IF (LIBAO_INCLUDE_DIR AND LIBAO_LIBRARIES)
SET(LIBAO_FOUND TRUE)
ENDIF (LIBAO_INCLUDE_DIR AND LIBAO_LIBRARIES)
IF (LIBAO_FOUND)
IF (NOT LIBAO_FIND_QUIETLY)
MESSAGE(STATUS "Found libao: ${LIBAO_LIBRARIES}")
ENDIF (NOT LIBAO_FIND_QUIETLY)
ELSE (LIBAO_FOUND)
IF (LIBAO_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find libao")
ENDIF (LIBAO_FIND_REQUIRED)
ENDIF (LIBAO_FOUND)
include_directories(${LIBAO_INCLUDE_DIR} ${MPG123_INCLUDE_DIRS})
set(ASSETDIR "${emotime_SOURCE_DIR}/assets" )
set(HEADERDIR "${emotime_SOURCE_DIR}/include" )
set(SRCDIR "${emotime_SOURCE_DIR}/src" )
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
add_subdirectory(src
)
In CMake you achieve linking to those libraries using the following commands (don't add the libraries to CXX_FLAGS!):
include_directories(${LIBAO_INCLUDE_DIR} ${MPG123_INCLUDE_DIRS})
target_link_libraries(target_name ${LIBAO_LIBRARIES} ${MPG123_LIBRARIES})
were target_name needs to be replaced by your actual target's name.
I'm using Ubuntu 12 64 bit, installed fftw library version 2.1.5.
I have a c++ project with use CMake to build the make file. This is my cmakelist.text:
project(MP)
cmake_minimum_required(VERSION 2.8)
if(TYPE STREQUAL "Debug")
set(CMAKE_BUILD_TYPE "Debug")
else()
set(CMAKE_BUILD_TYPE "Release")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
add_definitions( -std=c++11 )
endif()
find_package(GLUT REQUIRED)
find_package(OpenGL REQUIRED)
find_library(GLUI libglui.a ./vendor/lib)
include_directories(${OPENGL_INCLUDE_DIR}
./vendor/include)
LINK_DIRECTORIES(/usr/local/lib)
LINK_DIRECTORIES(/usr/lib)
LINK_DIRECTORIES(/usr/bin)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} GL GLU glut ${GLUI})
When I tried running the make file create by Cmake, i got this problem:
CMakeFiles/SciVis.dir/Simulation.cc.o: In function `Simulation::init_simulation(unsigned long)':
Simulation.cc:(.text+0x2d5): undefined reference to `rfftw2d_create_plan'
Simulation.cc:(.text+0x2ee): undefined reference to `rfftw2d_create_plan'
CMakeFiles/SciVis.dir/Simulation.cc.o: In function `Simulation::solve()':
Simulation.cc:(.text+0x881): undefined reference to `rfftwnd_one_real_to_complex'
Simulation.cc:(.text+0x891): undefined reference to `rfftwnd_one_real_to_complex'
Simulation.cc:(.text+0xa7f): undefined reference to `rfftwnd_one_complex_to_real'
Simulation.cc:(.text+0xa8f): undefined reference to `rfftwnd_one_complex_to_real'
CMakeFiles/SciVis.dir/Simulation.cc.o: In function `Simulation::FFT(int, void*)':
Simulation.cc:(.text+0x390): undefined reference to `rfftwnd_one_complex_to_real'
Simulation.cc:(.text+0x3a0): undefined reference to `rfftwnd_one_real_to_complex'
collect2: error: ld returned 1 exit status
make[2]: *** [SciVis] Error 1
make[1]: *** [CMakeFiles/SciVis.dir/all] Error 2
make: *** [all] Error 2
In my Simulation.cc file:
#include <fftw.h>
void Simulation::init_simulation(size_t n)
{
//Allocate data structures
size_t dim = n * 2 * (n / 2 + 1);
vx = new fftw_real[dim];
vy = new fftw_real[dim];
vx0 = new fftw_real[dim];
vy0 = new fftw_real[dim];
fx = new fftw_real[n * n];
fy = new fftw_real[n * n];
rho = new fftw_real[n * n];
rho0 = new fftw_real[n * n];
plan_rc = rfftw2d_create_plan(n, n, FFTW_REAL_TO_COMPLEX, FFTW_IN_PLACE);
plan_cr = rfftw2d_create_plan(n, n, FFTW_COMPLEX_TO_REAL, FFTW_IN_PLACE);
// Initialize data structures to 0
for (size_t i = 0; i < n * n; i++)
{
vx[i] = vy[i] = vx0[i] = vy0[i] = fx[i] = fy[i] = rho[i] = rho0[i] = 0.0f;
}
}
void Simulation::FFT(int direction,void* vx)
{
if(direction==1) rfftwnd_one_real_to_complex(plan_rc,(fftw_real*)vx,(fftw_complex*)vx);
else rfftwnd_one_complex_to_real(plan_cr,(fftw_complex*)vx,(fftw_real*)vx);
}
I dont know where I were wrong, can someone please help me ?
Thank you very much.
You're not linking against FFTW, you need to make CMake find the library and link against it first, put this file in your project's directory under a new folder "CMakeModules".
FindFFTW.cmake
# - Find FFTW
# Find the native FFTW includes and library
#
# FFTW_INCLUDES - where to find fftw3.h
# FFTW_LIBRARIES - List of libraries when using FFTW.
# FFTW_FOUND - True if FFTW found.
if (FFTW_INCLUDES)
# Already in cache, be silent
set (FFTW_FIND_QUIETLY TRUE)
endif (FFTW_INCLUDES)
find_path (FFTW_INCLUDES fftw3.h)
find_library (FFTW_LIBRARIES NAMES fftw3)
# handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE if
# all listed variables are TRUE
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (FFTW DEFAULT_MSG FFTW_LIBRARIES FFTW_INCLUDES)
mark_as_advanced (FFTW_LIBRARIES FFTW_INCLUDES)
Next, add this line to the top of your CMakeLists.txt:
project(MP)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules" ${CMAKE_MODULE_PATH})
Now try this:
find_package(FFTW REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR} ${FFTW_INCLUDES}
./vendor/include)
...
target_link_libraries(${PROJECT_NAME} GL GLU glut ${GLUI} ${FFTW_LIBRARIES})