I've been learning C++ and have decided to try to create a simple file reader using libzip on archive files (e.g. Word).
I’ve recently installed libzip on my Macbook using brew but I seem to keep on getting the following issue whenever I try to compile a program that uses libzip:
Undefined symbols for architecture x86_64:
"_zip_fopen", referenced from:
_main in main-918bfa.o
"_zip_open", referenced from:
_main in main-918bfa.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: *** [a.exe] Error 1
The command I use to compile:
g++ -g main.cpp -std=c++11 -I/usr/local/Cellar/libzip/0.11.2/include -I/usr/local/Cellar/libzip/0.11.2/lib/libzip/include -L/usr/local/Cellar/libzip/0.11.2/lib -o ../a.exe
main.cpp:
#include <iostream>
#include <fstream>
#include <zip.h>
#include <zlib.h>
using namespace std;
int numArgs = 2;
int main(int argc, char** argv){
// Parse command line arguments
if(argc != numArgs){
std::cout << "Incorrect number of arguments provided.\n";
std::cout << "Command line syntax: fileReader.exe inputFile" << endl;
exit(0);
}
// Try out libzip functionality
std::string inputDocument(argv[1]);
int err = 0;
zip* z = zip_open(inputDocument.c_str(), 0, &err);
if(z == NULL) {
printf("Could not read docx file. Error code: %d", err);
exit(-1);
}
zip_file* contentTypes = zip_fopen(z, "[Content_Types].xml", ZIP_FL_UNCHANGED);
exit(0);
}
Doesn't look like your including the libzip library in the compilation command. Try adding -lzip to your g++ command
Related
This question already has answers here:
gcc compiles libavformat code, but g++ does not [duplicate]
(1 answer)
Undefined reference, using FFMpeg-library (AvCodec) on Ubuntu, 64-bits system
(1 answer)
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 1 year ago.
I write to test ffmpeg and call ffmpeg function, but it alwasy tell me link err: can not found ffmpeg function:
this is my code:
#ifdef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#ifndef INT64_C
#define INT64_C(c) (c ## LL)
#define UINT64_C(c) (c ## ULL)
#endif
#include <libavutil/imgutils.h>
#include <libavutil/samplefmt.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
static const char *src_filename = NULL;
static const char *video_dst_filename = NULL;
static const char *audio_dst_filename = NULL;
static AVFormatContext *fmt_ctx = NULL;
int main(int argc, char **argv) {
int ret = 0;
if (argc != 4) {
fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
"API example program to show how to read frames from an input file.\n"
"This program reads frames from a file, decodes them, and writes decoded\n"
"video frames to a rawvideo file named video_output_file, and decoded\n"
"audio frames to a rawaudio file named audio_output_file.\n",
argv[0]);
exit(1);
}
// src_filename = argv[1];
src_filename = "/tmp/a.mp4";
video_dst_filename = argv[2];
audio_dst_filename = argv[3];
/* open input file, and allocate format context */
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
fprintf(stderr, "Could not open source file %s\n", src_filename);
exit(1);
}
avformat_close_input(&fmt_ctx);
}
the follow is build command:
clang++ -I /usr/local/apps/homebrew/Cellar/ffmpeg/4.4_1/include/ -L/usr/local/apps/homebrew/Cellar/ffmpeg/4.4_1/lib -lavformat main.cpp
and the terminal output:
Undefined symbols for architecture x86_64:
"avformat_open_input(AVFormatContext**, char const*, AVInputFormat*, AVDictionary**)", referenced from:
_main in main-f2a6f0.o
"avformat_close_input(AVFormatContext**)", referenced from:
_main in main-f2a6f0.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
then Who can tell me why.
I am trying to run a program that opens a window. the purpose is to get the program started opening a window is the start of all programs right?
But when I run my code for some reason I get this error:
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
However, in my code I do have the main() function so why am I getting this error?
This is my code:
#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>
#include <SDL2_ttf/SDL_ttf.h>
#include <stdio.h>
int main(){
if(SDL_Init( SDL_INIT_EVERYTHING ) < 0){
std::cout << "error 1\n";
std::cout << SDL_GetError();
std::cout << "\n";
return -1;
}
if(TTF_Init() < 0){
std::cout << "error 2\n";
std::cout << TTF_GetError();
std::cout << "\n";
return -1;
}
SDL_Window* window = SDL_CreateWindow("test", 0, 0, 500, 500, 0);
if(!window){
std::cout << "error 3\n";
std::cout << SDL_GetError();
std::cout << "\n";
return -1;
}
int windowid = SDL_GetWindowID(window);
SDL_Renderer* Renderer = SDL_CreateRenderer(window, -1, 0);
running = true;
SDL_Event event;
while(running){
while(SDL_PollEvent(&event)){
if(event.type == SDL_WindowEvent){
if(event.window.windowID == windowid){
if(event.window.type == SDL_WindowClose){
Destroywindow(window);
running = false;
}
}
}
}
}
return 0;
}
my make file looks like this:
#!/bin/bash
brew update
brew install sdl2
g++ -o /Users/mikahshattuck/noneproject/none2019-05-0909-22-
14:2:/none.app/Contents/MacOS/mainrun.cpp -I /Library/Frameworks -l
SDL2
exit 0
this is the full out:
Already up-to-date.
Warning: sdl2 2.0.9_1 is already installed and up-to-date
To reinstall 2.0.9_1, run `brew reinstall sdl2`
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
thank you in advance
When using SDL on macOS or Windows, you need to add -Dmain=SDL_main to your compile flags and -lSDL2main to your link flags. Since you're using Homebrew, you can make it easier and just use pkg-config to get the correct flags. Use this compiler command as a template and adapt it to your needs:
g++ $(pkg-config --cflags sdl2) -I /Library/Frameworks source.cpp -o output_executable $(pkg-config --libs sdl2)
However, it seems you are also using SDL_ttf, not just plain SDL. In this case, you should probably use SDL2_ttf instead of sdl2 as the package argument of pkg-config:
g++ $(pkg-config --cflags SDL2_ttf) -I /Library/Frameworks source.cpp -o output_executable $(pkg-config --libs SDL2_ttf)
The SDL2_ttf package depends on the sdl2 package, so using SDL2_ttf will also emit the needed flags for sdl2.
The names of the pkg-config packages correspond to *.pc files installed by Homebrew into /usr/local/lib/pkgconfig.
I get this error from testing JNI:
Undefined symbols for architecture x86_64:
"_JNI_CreateJavaVM", referenced from:
_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)
Here is c++ code:
#include <jni.h>
#include <iostream>
using namespace std;
int main()
{
int res;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
JavaVM *jvm;
JNIEnv *env;
jmethodID mid;
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.class.path = /Users/stephen/course/test/Test";
options[2].optionString = "-verbose:NONE";
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 3;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
res = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
if(res == JNI_ERR){
cout << "Error invoking the JVM";
return 1;
}
cout <<"create JVM successfully!"<<endl;
jclass cls = env->FindClass("/Users/stephen/course/Qt-project/test/Test");
if(cls != 0){
cout<<"find class successfully!" << endl;
}
mid = env->GetMethodID(cls,"sayHello","stephen");
if(mid != 0){
cout<<"Invoke method successfully!" << endl;
}
jvm->DestroyJavaVM();
return 0;
}
Here is java code:
public class Test
{
public static void sayHello(String s){
System.out.print("hello I am" + s + "\n");
}
}
I add the include path of " jdk/include; jdk/include/darwin" the project, also I add lib path of " jdk/jre/lib/server" to the project to get the libjvm.dylib. The c++ standard library of my project is libstdc++(gnu c++ standard library.
But I can't solve this problem as expected.
Take a look here for a sample code where JVM library is linked with your project:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo028
Take a look at Makefile. Especially, here:
main: recipeNo028_main.o
ld -o lib/recipeNo028_main -L${JAVA_HOME}/jre/lib/server/ \
-ljvm \
$(MAC_OS_FLAGS) \
lib/recipeNo028_main.o
where jvm lib is linked with the code, and here:
CC=llvm-gcc
MAC_OS_FLAGS=-rpath ${JAVA_HOME}/jre/lib/server -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -demangle -dynamic -arch x86_64 -macosx_version_min 10.12.0 -lSystem
where all required libs are added to your code as well. It should work. Try to compile sample code. You can find more samples here: http://jnicookbook.owsiak.org
Update
How to use arbitrary JDK version for compilation.
First, take a look at all installations you have
/usr/libexec/java_home -V
This will produce something like this
/usr/libexec/java_home -V
Matching Java Virtual Machines (4):
9, x86_64: "Java SE 9" /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home
1.8.0_144, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
1.8.0_111, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home
1.7.0_80, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home
Then, before running make, simply set JAVA_HOME to whatever you like
export JAVA_HOME=$(/usr/libexec/java_home -v 9)
Now, your code will use version that you have chosen.
I'm new to open cv. At the moment I'm trying to test if I could run a simple file.
// Example showing how to read and write images
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cvaux.h>
int main(int argc, char** argv)
{
IplImage * pInpImg = 0;
// Load an image from file - change this based on your image name
pInpImg = cvLoadImage("bear.jpg", CV_LOAD_IMAGE_UNCHANGED);
if(!pInpImg)
{
fprintf(stderr, "failed to load input image\n");
return -1;
}
// Write the image to a file with a different name,
// using a different image format -- .png instead of .jpg
if( !cvSaveImage("my_image_copy.png", pInpImg) )
{
fprintf(stderr, "failed to write image file\n");
}
// Remember to free image memory after using it!
cvReleaseImage(&pInpImg);
return 0;
}
I compiled it:
g++ `pkg-config –cflags opencv` cv.cpp -o cv `pkg-config –libs opencv`
I got this error:
Undefined symbols for architecture x86_64:
"_cvLoadImage", referenced from:
_main in cv-zQ5X30.o
"_cvReleaseImage", referenced from:
_main in cv-zQ5X30.o
"_cvSaveImage", referenced from:
_main in cv-zQ5X30.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 lost here, any help would be very much appreciated.
Thank you.
i think the problem might be using "-libs" and "-cflags" instead of "--libs" and "--cflags", use this instead:
g++ `pkg-config --cflags opencv` cv.cpp -o cv `pkg-config --libs opencv`
I am getting the following error when trying to compile....
Undefined symbols for architecture x86_64:
"_png_sig_cmp", referenced from:
RenderUtils::isValidPng(std::istream&) in RenderUtils.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
my code is as follows:
//called from here
ifstream s;
s.open("/Users/tmg06qyu/Desktop/texture_512.png", ios::binary);
if(!RenderUtils::isValidPng(s)){
throw 20;
}
//header
class RenderUtils{
public:
static bool isValidPng(std::istream &source);
};
//implementation
#include <iostream>
#include "RenderUtils.h"
#include "png.h"
#define PNGSIGSIZE 8
using namespace std;
bool RenderUtils::isValidPng(std::istream &source){
//Allocate a buffer of 8 bytes, where we can put the file signature.
png_byte pngsig[PNGSIGSIZE];
int is_png = 0;
//Read the 8 bytes from the stream into the sig buffer.
source.read((char*)pngsig, PNGSIGSIZE);
//Check if the read worked...
if (!source.good()) return false;
//Let LibPNG check the sig. If this function returns 0, everything is OK.
is_png = png_sig_cmp(pngsig, 0, PNGSIGSIZE);
return (is_png == 0);
}
My guess is that you built a 32-bit version of libpng, but now you are trying to link 64-bit code with it. Try file * or otool -L * to check (from memory)
Sorry everyone....stupid me. I needed to link against zlib.....note to self.....always read the readme....(well not always!)