Netcdf Undefined symbols for architecture x86_64 - linker

I am running into the famous while using the netcdf library
Undefined symbols for architecture x86_64:
"NcVar::get(double*, long const*) const", referenced from:
Reader<itk::Image<double, 3u> >::Read() 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 have installed the library using homebrew:
$brew doctor
Your system is ready to brew.
$brew info netcdf
netcdf: stable 4.3.0
http://www.unidata.ucar.edu/software/netcdf
/usr/local/Cellar/netcdf/4.3.0 (53 files, 4.5M) *
Built from source with: --enable-cxx-compat
From: https://github.com/homebrew/homebrew-science/commits/master/netcdf.rb
==> Dependencies Required: hdf5 ✔
the library is in /usr/local/lib (where it is supposed to be). and I assume this path is in the library include path.
$ls /usr/local/lib/|grep netcdf
libnetcdf.7.dylib
libnetcdf.a
libnetcdf.dylib
libnetcdf_c++.4.dylib
libnetcdf_c++.a
libnetcdf_c++.dylib
libnetcdf_c++4.1.dylib
libnetcdf_c++4.a
libnetcdf_c++4.dylib
and my code used to link, until it didn't.
#include <iostream>
#include <exception>
#include <netcdfcpp.h>
std::string _filename="blabla.nc", _varname="variableName";
int _dim;
long* _sizeArray;
long _sizeFlat;
double* _data;
// Read netCDF
void Read()
{
// Open the file.
NcFile file( _filename.c_str(), NcFile::ReadOnly, NULL, 0, NcFile::Offset64Bits);
NcVar* var = file.get_var( _varname.c_str() );
if( var->is_valid() )
{
_sizeFlat = var->num_vals();
_sizeArray = var->edges();
/*
_dim = var->num_dims();
std::cout<< _dim<<std::endl;
for (int i=0; i<_dim; i++)
std::cout<<_sizeArray[i]<<"\t";
std::cout<<"\t"<<_sizeFlat<<std::endl;
// */
_data = new PixelType[_sizeFlat];
try
{
var->get(_data, _sizeArray);
}
catch(std::exception& a)
{
a.what();
//free mem
delete[] _data;
file.close();
_sizeArray = NULL;
var = NULL;
//quit
std::cout<<"Could not read variable :"<<_varname<<std::endl;
exit(EXIT_FAILURE);
}
//free mem
file.close();
}
else
{
//free mem
file.close();
var = NULL;
//quit
std::cout<<"Could not find variable :"<<_varname<<std::endl;
exit(EXIT_FAILURE);
}
}
int main(void)
{
Read();
return 0;
}
I know that I am using old legacy code ( http://www.unidata.ucar.edu/software/netcdf/examples/programs/ ) but the methods I am using are those I found when opening the /usr/local/include/netcdfcpp.h
I am using Cmake to compile, here is the CMakeLists.txt, if it can help
cmake_minimum_required ( VERSION 2.6 )
#set project name
set( Version_Major 3 )
set( Version_Minor 0 )
set( ProjectName supercellDetection_v${Version_Major}.${Version_Minor} )
project ( ${ProjectName} )
if( COMMAND CMAKE_POLICY )
cmake_policy( SET CMP0012 NEW )
cmake_policy( SET CMP0009 NEW )
endif()
#set output path
set( EXECUTABLE_OUTPUT_PATH /absolute/path )
#generate source files list
file(
GLOB_RECURSE
source_files
src/*pp
)
#create output executable
add_executable( ${ProjectName} ${source_files} )
#look for itk
find_package( ITK REQUIRED )
include( ${ITK_USE_FILE} )
include_directories( ${ITK_INCLUDE_DIRS} )
#try for vtk
if ( ITKVtkGlue_LOADED )
find_package( VTK REQUIRED )
include( ${VTK_USE_FILE} )
endif()
#linker settings
#target_link_libraries( ${ProjectName} ITKCommon ITKIO ITKBasicFilters ITKReview )
target_link_libraries( ${ProjectName} ${ITK_LIBRARIES} )
# compilation options
add_definitions( "-Wall -std=c++11 -g" )
################################################################
#Generate list of header files
include_directories( "/opt/X11/include/" )
include_directories( "/usr/local/include/" )
#add libraries
file(
GLOB_RECURSE
x11Lib_files
/opt/X11/lib/*.dylib
)
target_link_libraries( ${ProjectName} ${x11Lib_files} )
I do not know how to solve this linker problem. Could you please help me?

Related

A C language ffmpeg project organized with CMakeLists, encounters errors in the Windows MinGW64 environment

Project Structure
ffmpeg-tutorial
include
libavcodec
libavdevice
libavfilter
libavformat
libavutil
libswresample
libswscale
lib
pkgconfig
libavcodec.a
libavdevice.a
libavfilter.a
libformat.a
libavutil.a
libswresample.a
libswscale.a
CMakeLists.txt
main.c
CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(ffmpeg_tutorial)
set(CMAKE_C_STANDARD 11)
include_directories(include)
link_directories(lib)
add_executable(ffmpeg_tutorial main.cpp)
target_link_libraries(ffmpeg_tutorial
avformat
avcodec
avutil
swscale
swresample
z
bz2
iconv
ws2_32
schannel
kernel32
advapi32
kernel32
user32
gdi32
winspool
shell32
ole32
oleaut32
uuid
comdlg32
advapi32
)
main.c
#include <stdio.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
int main() {
std::cout << "Hello, World!" << std::endl;
std::cout << av_version_info() << std::endl;
printf("ffmpeg version is %s\n", av_version_info());
// Open input file
AVFormatContext *inputContext = nullptr;
if (avformat_open_input(&inputContext, "input.mp3", nullptr, nullptr) != 0) {
printf("Couldn't open input file\n");
return -1;
}
// Read input stream
if (avformat_find_stream_info(inputContext, nullptr) < 0) {
printf("Couldn't find stream information\n");
return -1;
}
// Get audio stream index
int audioStream = -1;
for (int i = 0; i < inputContext->nb_streams; i++) {
if (inputContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
audioStream = i;
break;
}
}
if (audioStream == -1) {
printf("Couldn't find audio stream\n");
return -1;
}
}
IDE
clion
ERRORS
[ 50%] Building CXX object CMakeFiles/ffmpeg_tutorial.dir/main.cpp.obj
[100%] Linking CXX executable ffmpeg_tutorial.exe
D:/Msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: G:/cywen_private/cpp_projects/ffmpeg-tutorial/lib/libavformat.a(tls_schannel.o): in function `tls_write':
D:\Msys64\usr\src\ffmpeg/libavformat/tls_schannel.c:563: undefined reference to `EncryptMessage'
D:/Msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: G:/cywen_private/cpp_projects/ffmpeg-tutorial/lib/libavformat.a(tls_schannel.o): in function `tls_read':
D:\Msys64\usr\src\ffmpeg/libavformat/tls_schannel.c:441: undefined reference to `DecryptMessage'
D:/Msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: G:/cywen_private/cpp_projects/ffmpeg-tutorial/lib/libavcodec.a(mfenc.o):mfenc.c:(.rdata$.refptr.IID_ICodecAPI[.refptr.IID_ICodecAPI]+0x0): undefined reference to `IID_ICodecAPI'
D:/Msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: G:/cywen_private/cpp_projects/ffmpeg-tutorial/lib/libavcodec.a(tiff.o): in function `tiff_uncompress_lzma':
D:\Msys64\usr\src\ffmpeg/libavcodec/tiff.c:577: undefined reference to `lzma_stream_decoder'
D:/Msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\Msys64\usr\src\ffmpeg/libavcodec/tiff.c:582: undefined reference to `lzma_code'
D:/Msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\Msys64\usr\src\ffmpeg/libavcodec/tiff.c:583: undefined reference to `lzma_end'
D:/Msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: G:/cywen_private/cpp_projects/ffmpeg-tutorial/lib/libavutil.a(random_seed.o): in function `av_get_random_seed':
D:\Msys64\usr\src\ffmpeg/libavutil/random_seed.c:127: undefined reference to `BCryptOpenAlgorithmProvider'
D:/Msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\Msys64\usr\src\ffmpeg/libavutil/random_seed.c:130: undefined reference to `BCryptGenRandom'
D:/Msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\Msys64\usr\src\ffmpeg/libavutil/random_seed.c:131: undefined reference to `BCryptCloseAlgorithmProvider'
collect2.exe: error: ld returned 1 exit status
mingw32-make[3]: *** [CMakeFiles\ffmpeg_tutorial.dir\build.make:95: ffmpeg_tutorial.exe] Error 1
mingw32-make[2]: *** [CMakeFiles\Makefile2:82: CMakeFiles/ffmpeg_tutorial.dir/all] Error 2
mingw32-make[1]: *** [CMakeFiles\Makefile2:89: CMakeFiles/ffmpeg_tutorial.dir/rule] Error 2
mingw32-make: *** [Makefile:123: ffmpeg_tutorial] Error 2
What is the way I compile ffmpeg
downlaod msys2
install mingw64
pacman -S mingw-w64-x86_64-toolchain
install make,diffutils,nasm,yasm,pkg-config
pacman -S base-devl yasm nasm pkg-config
download ffmpeg 5.1
compile
cd ffmpeg
./configure --disable-shared --enable-static --arch=x86_64 --target-os=mingw32 --cross-prefix=x86_64-w64-mingw32- --pkg-config-flags=--static --prefix=../ffmpeg-build
make -j $(nproc)
make install
Project Repoistory
https://github.com/joinwen/learn_ffmpeg.git
Expectation
How to solve errors
In CMakeLists target_link_libraries's parameters is too much, Can I make it short
some advices on the project

How to compile a simple MLT example in C?

I am trying to compile an example code from the MLT Framework website that shows how consumer/producer work. The code is as follows:
#include <stdio.h>
#include <unistd.h>
#include <framework/mlt.h>
int main( int argc, char *argv[] )
{
// Initialise the factory
if ( mlt_factory_init( NULL ) == 0 )
{
// Create the default consumer
mlt_consumer hello = mlt_factory_consumer( NULL, NULL );
// Create via the default producer
mlt_producer world = mlt_factory_producer( NULL, argv[ 1 ] );
// Connect the producer to the consumer
mlt_consumer_connect( hello, mlt_producer_service( world ) );
// Start the consumer
mlt_consumer_start( hello );
// Wait for the consumer to terminate
while( !mlt_consumer_is_stopped( hello ) )
sleep( 1 );
// Close the consumer
mlt_consumer_close( hello );
// Close the producer
mlt_producer_close( world );
// Close the factory
mlt_factory_close( );
}
else
{
// Report an error during initialisation
fprintf( stderr, "Unable to locate factory modules\n" );
}
// End of program
return 0;
}
The file name is player.c.
I cannot use make to compile it with make player as it does not find include files.
I am using the following command to compile with gcc:
# gcc -I /usr/include/mlt -l libmltcore -o player player.c
/usr/bin/ld: cannot find -llibmltcore
collect2: error: ld returned 1 exit status
As you can see the linker cannot find the mlt library. OS is Fedora 32 and I have installed mlt-devel and I am sure I have the following libs in /usr/lib64/mlt:
libmltavformat.so libmltlinsys.so libmltqt.so libmltvidstab.so
libmltcore.so libmltmotion_est.so libmltresample.so libmltvmfx.so
libmltdecklink.so libmltnormalize.so libmltrtaudio.so libmltvorbis.so
libmltfrei0r.so libmltoldfilm.so libmltsdl2.so libmltxml.so
libmltgtk2.so libmltopengl.so libmltsdl.so
libmltjackrack.so libmltplusgpl.so libmltsox.so
libmltkdenlive.so libmltplus.so libmltvideostab.so
What am I doing wrong?
My second question is why does GCC not find the include files and libraries in the first place so that I have to specify them manually?
regarding:
gcc -I /usr/include/mlt -l libmltcore -o player player.c`
The linker handles things in the order they are listed on the command. So when the linker encounters -l libmitcore there are no unresolved external references so nothing is included so in the end the link step will fail. Suggest:
gcc player.c -o player -I /usr/include/mlt -l libmltcore
regarding:
/usr/bin/ld: cannot find -llibmltcore
if the libmltcore is not on one of the 'standard' library directories, it will not be found, UNLESS the command also includes the library path. Suggest including the following parameter, before the library name:
-L /usr/lib64/mlt

Trying to add SDL2_mixer and SDL2 as ExternalProject's in CMake

I am currently trying to fetch SDL2 and SDL2_mixer as external projects in my CMake project.
SDL2 seems to work fine, but I cannot make SDL2_mixer compile. It fails when trying to link the playwav binary. The problem are the CFLAGS and LDFLAGS variables in the ExternalProject_Add. The same problem occurs when adding these variables while building from the command line without CMake.
Here is my code so far:
cmake_minimum_required(VERSION 2.8)
include(ExternalProject)
project(sdl2_test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(LIBS_DIR ${PROJECT_BINARY_DIR}/libs)
set(SDL2_VER "2.0.8")
set(SDL2_MIXER_VER "2.0.2")
# SDL library
ExternalProject_Add(sdl2_project
URL http://www.libsdl.org/release/SDL2-${SDL2_VER}.tar.gz
PREFIX ${LIBS_DIR}/SDL2
INSTALL_COMMAND ""
)
ExternalProject_Get_Property(sdl2_project SOURCE_DIR)
ExternalProject_Get_Property(sdl2_project BINARY_DIR)
set(SDL2_SRC ${SOURCE_DIR})
set(SDL2_BIN ${BINARY_DIR})
file(GLOB SDL2_INCLUDE "${SDL2_SRC}/include/*")
file(COPY ${SDL2_INCLUDE} DESTINATION ${SDL2_BIN}/include/)
# SDL_mixer library
ExternalProject_Add(sdl2_mixer_project
URL https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-${SDL2_MIXER_VER}.tar.gz
DEPENDS sdl2_project
PREFIX ${LIBS_DIR}/SDL2_mixer
CONFIGURE_COMMAND
SDL2_CONFIG=${SDL2_BIN}/sdl2-config
CFLAGS=-I${SDL2_BIN}/include
LDFLAGS=-L${SDL2_BIN}
#LIBS=-ldl
<SOURCE_DIR>/configure
--prefix=<INSTALL_DIR>
--enable-shared=no
#--with-sdl-prefix=${SDL2_BIN}
--disable-sdltest
BUILD_COMMAND make
INSTALL_COMMAND ""
)
#file(GLOB SDL2_INCLUDE "${SDL2_SRC}/include/*")
#file(COPY ${SDL2_INCLUDE} DESTINATION ${SDL2_BIN}/include/)
ExternalProject_Get_Property(sdl2_mixer_project SOURCE_DIR)
ExternalProject_Get_Property(sdl2_mixer_project BINARY_DIR)
set(SDL2_MIXER_SRC ${SOURCE_DIR})
set(SDL2_MIXER_BIN ${BINARY_DIR})
include_directories(${SDL2_SRC}/include)
include_directories(${SDL2_MIXER_SRC}/include)
set(SOURCE sdl2test.cc)
add_executable(sdl_test ${SOURCE})
add_dependencies(sdl_test sdl2_project sdl2_mixer_project)
target_link_libraries(sdl_test ${SDL2_BIN}/libSDL2.a)
The file sdl2test.cc is just a dummy file:
#include <iostream>
int main()
{
std::cout << "Hooray" << std::endl;
return 0;
}

C - Cmake compiling program with libcurl

I'm trying to use some curl code to test the lib but I can't compile it :(
I'm using Clion (Cmake + gcc) and I've got a libcurl.a, a libcurl.dll and a libcurl.dlla
What am I suppose to do with those 3 files ?
This is my CmakeLists.txt :
cmake_minimum_required(VERSION 3.10)
project(curl_test2 C)
set(CMAKE_C_STANDARD 99)
ADD_DEFINITIONS( -DCURL_STATICLIB )
include_directories( "include" )
set(SRCS"
srcs/main.c")
set(HEADERS
"include/curl/curl.h"
"include/curl/easy.h")
link_directories("lib")
add_executable(curl_test2 ${SRCS} ${HEADERS})
target_link_libraries(curl_test2 "curl")
this is my project:
include
--curl
--curl.h
srcs
--main.c
lib
--libcurl.a
(--dlls
--libcurl.dll
--libcurl.dlla) <- i'm not using them for now
this is my main.c (just a libcurl example, not really important - i'm just trying to compile):
#include <stdio.h>
#include "curl/curl.h"
int main(void)
{
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://postit.example.com/moo.cgi");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
res = curl_easy_perform(curl);
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
When I'm trying to build the compiler drop this error : "undefined reference to `_imp__curl_global_init'" (and all other curl function calls)
Can you help me ? I'm a bit lost - I did not really use Cmake before..
Thank you !
You link with static curl library (libcurl.a) which required CURL_STATICLIB definition. Add this in your CMakeLists.txt between "project" and "add_executable" commands:
add_definitions( -DCURL_STATICLIB )
Moreover, your file .dlla is not .dll.a ? In that case, .dll.a file is (I think) generated by MinGW toolchain and is required only if you link dynamically with curl library (as .dll file).
I downloaded the sources of cURL library here and compiled it (with Visual Compiler 2015). It produces shared libraries (libcurl.dll and libcurl_imp.lib) that I move in the lib directory (I should rename libcurl_imp.lib to curl.lib). I move also the include directory.
Then, I used this CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)
project(curl_test2 C)
set(CMAKE_C_STANDARD 99)
set(SRCS "srcs/main.c")
set( CURL_LIBRARY ${CMAKE_SOURCE_DIR}/lib )
set( CURL_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include )
find_package( CURL )
include_directories( ${CURL_INCLUDE_DIRS} )
link_directories( ${CURL_LIBRARIES} )
add_executable(curl_test2 ${SRCS})
target_link_libraries(curl_test2 curl)
With it, your project compiles and the execution works.
I also tried with cURL static library (for that, if you use CMake to compile cURL, add -DCURL_STATICLIB=ON in cmake command line). And I moved the produced library libcurl.lib to lib\curl.lib.
I used this CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)
project(curl_test2 C)
set(CMAKE_C_STANDARD 99)
set(SRCS "srcs/main.c")
add_definitions( -DCURL_STATICLIB )
set( CURL_LIBRARY ${CMAKE_SOURCE_DIR}/lib )
set( CURL_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include )
find_package( CURL )
include_directories( ${CURL_INCLUDE_DIRS} )
link_directories( ${CURL_LIBRARIES} )
add_executable(curl_test2 ${SRCS})
target_link_libraries(curl_test2 curl wldap32 ws2_32)
And it works too.

Why does cmake give undefined references for netcdf with cygwin on windows?

I am trying to set up some model code on multiple operating systems using clion 2016.3-1 and its bundled cmake 3.6.2.
On Windows I am using the cygwin environment but I ran into a linking issue I can not resolve. Here is a minimum example of my code:
#include <stdlib.h>
#include <stdio.h>
#include <netcdf.h>
#define ERRCODE 2
#define ERR(e) {printf("Error: %s\n", nc_strerror(e)); exit(ERRCODE);}
int main() {
int ncid, varid, dimid, retval;
size_t nlat;
char filepath[] = "minimumExample.nc";
char dimname[64];
double *latitudes;
// open nc file
if ((retval = nc_open(filepath, NC_NOWRITE, &ncid))) ERR(retval);
// find variable IDs
if ((retval = nc_inq_varid(ncid, "latitude", &varid))) ERR(retval);
// find dimension bounds
if ((retval = nc_inq_vardimid(ncid, varid, &dimid))) ERR(retval);
if ((retval = nc_inq_dim(ncid, dimid, dimname, &nlat))) ERR(retval);
// allocate data array
latitudes = malloc(sizeof(double) * nlat);
// get data
if ((retval = nc_get_var_double(ncid, varid, &latitudes[0]))) ERR(retval);
// close nc file
if ((retval = nc_close(ncid))) ERR(retval);
// free data array
free(latitudes);
return(0);
}
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.3)
project(test_examples)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lnetcdf")
include_directories("/usr/include")
link_directories("/usr/lib")
set(SOURCE_FILES main.c)
add_executable(test_examples ${SOURCE_FILES})
However I get a lot of error messages similar to:
undefined reference to `nc_open'
The binaries and include files are all present in the cygwin environment at the respective folders.
What am I missing?
The errors are saying that linker could not find code for that functions: in other words the library is not reachable.
You should use the CMake target_link_libraries function to link netcdf lib.
remove
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lnetcdf")
and add
target_link_libraries (test_examples netcdf)

Resources