I have installed zlib-1.2.3.exe.
I have the following settings in CLion 2020.1:
I have the following lines in my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.16)
project(ZLIB__test)
set(CMAKE_CXX_STANDARD 11)
set(ZLIB_LIBRARY "C:/Program Files (x86)/GnuWin32")
set(ZLIB_INCLUDE_DIR "C:/Program Files (x86)/GnuWin32/include")
include_directories(${ZLIB_INCLUDE_DIR})
add_executable(ZLIB__test main.cpp)
I have the following source code in main.cpp:
#include <cstdio>
#include <zlib.h>
// Demonstration of zlib utility functions
unsigned long file_size(char *filename) {
FILE *pFile = fopen(filename, "rb");
fseek(pFile, 0, SEEK_END);
unsigned long size = ftell(pFile);
fclose(pFile);
return size;
}
int decompress_one_file(char *infilename, char *outfilename) {
gzFile infile = gzopen(infilename, "rb");
FILE *outfile = fopen(outfilename, "wb");
if (!infile || !outfile) return -1;
char buffer[128];
int num_read = 0;
while ((num_read = gzread(infile, buffer, sizeof(buffer))) > 0) {
fwrite(buffer, 1, num_read, outfile);
}
gzclose(infile);
fclose(outfile);
}
int compress_one_file(char *infilename, char *outfilename) {
FILE *infile = fopen(infilename, "rb");
gzFile outfile = gzopen(outfilename, "wb");
if (!infile || !outfile) return -1;
char inbuffer[128];
int num_read = 0;
unsigned long total_read = 0, total_wrote = 0;
while ((num_read = fread(inbuffer, 1, sizeof(inbuffer), infile)) > 0) {
total_read += num_read;
gzwrite(outfile, inbuffer, num_read);
}
fclose(infile);
gzclose(outfile);
printf("Read %ld bytes, Wrote %ld bytes,Compression factor %4.2f%%\n",
total_read, file_size(outfilename),
(1.0 - file_size(outfilename) * 1.0 / total_read) * 100.0);
}
int main(int argc, char **argv) {
compress_one_file(argv[1], argv[2]);
decompress_one_file(argv[2], argv[3]);
}
and, the above source code is generating the following error:
====================[ Clean | Debug ]===========================================
"C:\Program Files\JetBrains\CLion 2020.1.3\bin\cmake\win\bin\cmake.exe" --build C:\Users\pc\CLionProjects\ZLIB__test\cmake-build-debug --target clean
Clean finished
====================[ Build | all | Debug ]=====================================
"C:\Program Files\JetBrains\CLion 2020.1.3\bin\cmake\win\bin\cmake.exe" --build C:\Users\pc\CLionProjects\ZLIB__test\cmake-build-debug --target all
Scanning dependencies of target ZLIB__test
[ 50%] Building CXX object CMakeFiles/ZLIB__test.dir/main.cpp.obj
In file included from C:\Users\pc\CLionProjects\ZLIB__test\main.cpp:2:
In file included from C:\PROGRA~2\GnuWin32\include\zlib.h:34:
C:\PROGRA~2\GnuWin32\include/zconf.h(289,12): fatal error: 'unistd.h' file not found
# include <unistd.h> /* for SEEK_* and off_t */
^~~~~~~~~~
1 error generated.
NMAKE : fatal error U1077: 'C:\PROGRA~1\LLVM\bin\clang-cl.exe' : return code '0x1'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\bin\HostX64\x64\nmake.exe"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\bin\HostX64\x64\nmake.exe"' : return code '0x2'
Stop.
How can I fix this?
A big rule of thumb in CMake is that if you are using a library with native CMake support, then you should be using either find_package() + target_link_libraries() or add_subdirectory() + target_link_libraries(). Manually adding header search paths and linking against libraries for these kinds of dependencies is almost always wrong.
Doing things the CMake-way will normally lead to things getting configured correctly for a reasonably-made library (which zlib certainly is).
Option A: find_package() + target_link_libraries()
This requires zlib to be installed in a findable place on your system.
cmake_minimum_required(VERSION 3.16)
project(ZLIB__test)
set(CMAKE_CXX_STANDARD 11)
find_package(zlib REQUIRED)
add_executable(ZLIB__test main.cpp)
target_link_libraries(ZLIB__test ZLIB::ZLIB)
Option B: add_subdirectory() + target_link_libraries()
This one assumes that a copy of zlib's source code is located at third_party/zlib relative to the CMakeLists.txt.
cmake_minimum_required(VERSION 3.16)
project(ZLIB__test)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory("third_party/zlib")
add_executable(ZLIB__test main.cpp)
target_link_libraries(ZLIB__test ZLIB::ZLIB)
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.
This is c++ code to get IP address (main.cpp) (project -> Prueba2 ).
#include <iostream>
#include <windows.h>
#include <wininet.h>
std::string real_ip() {
HINTERNET net = InternetOpen("IP retriever",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0);
HINTERNET conn = InternetOpenUrl(net,
"http://myexternalip.com/raw",
NULL,
0,
INTERNET_FLAG_RELOAD,
0);
char buffer[4096];
DWORD read;
InternetReadFile(conn, buffer, sizeof(buffer)/sizeof(buffer[0]), &read);
InternetCloseHandle(net);
return std::string(buffer, read);
}
int main() {
std::cout << real_ip() << std::endl;
return 0;
}
CMakeLists.txt file for compiling.
cmake_minimum_required(VERSION 3.22)
project(Prueba2)
set(CMAKE_CXX_STANDARD 20)
add_executable(Prueba2 main.cpp)
I have to link this library but i don't know how, this error appears. I know how to compile it with g++ adding the library with -lwininet and it works correctly, i'm trying to do it with cmake now. Thank you for your help
undefined reference to `__imp_InternetOpenA'
C:\Program Files\JetBrains\CLion 2022.1.3\bin\mingw\bin/ld.exe: C:/Users/JAVIER/CLionProjects/Prueba2/main.cpp:13: undefined reference to `__imp_InternetOpenUrlA'
C:\Program Files\JetBrains\CLion 2022.1.3\bin\mingw\bin/ld.exe: C:/Users/JAVIER/CLionProjects/Prueba2/main.cpp:23: undefined reference to `__imp_InternetReadFile'
C:\Program Files\JetBrains\CLion 2022.1.3\bin\mingw\bin/ld.exe: C:/Users/JAVIER/CLionProjects/Prueba2/main.cpp:24: undefined reference to `__imp_InternetCloseHandle'
You can use target_link_libraries:
...
add_executable(Prueba2 main.cpp)
target_link_libraries(Prueba2 wininet)
I compiled the FFMPEG source file myself and got the header and library files in an include and bin folder respectively, the target platform is Windows 10. I also setup my cmakelist.txt to find and include both the library and header files. The application finds the path or so it seems because during compilation I get a "LNK2019 error unresolved external symbol avformat_alloc_context referenced in function main". Below is an extract from my cmake list; I will like to note that I got the .lib and .dll versions of the library hence the approach below based on the book "professional cmake" and other stackflow examples.
ProjectDir/AudMan/cmakelist.txt
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};PATH-TO-INCLUDES;PATH-TO-LIBRARY)
find_path(AVFORMAT_INCLUDE_DIR libavformat/avformat.h)
find_library(AVFORMAT_LIBRARY avformat)
add_library(ffmpegHeaders INTERFACE)
target_include_directories(ffmpegHeaders INTERFACE ${AVFORMAT_INCLUDE_DIR})
ProjectDir/cmakelist.txt
set(Rapid_Prefix PATH-TO-LIBRARY)
add_library(AVformat SHARED IMPORTED)
set_target_properties(AVformat PROPERTIES IMPORTED_LOCATION ${Rapid_Prefix}/avformat-59.dll IMPORTED_IMPLIB ${AVFORMAT_LIBRARY})
target_link_libraries(App_target PRIVATE AVformat)
A sample of the codes is this
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}
int main()
{
AVFormatContext* format = avformat_alloc_context();
if (avformat_open_input(&format, R"(\test.m4a)", NULL, NULL) != 0) {
fprintf(stderr, "Could not open file '%s'\n", R"(\test.m4a)");
return -1;
}
if (avformat_find_stream_info(format, NULL) < 0) {
fprintf(stderr, "Could not retrieve stream info from file '%s'\n", R"(test.m4a)");
return -1;
}
return 0;
}
I have been at it for about five days and will appreciate any help I can get.
OS: Windows 8 64-bit
Compiler: Visual Studio 2012
Problem Description: When I try to compile codes with "dirent.h" in "x64", error occurs. No matter dirent.h is used or not. The error won't occur if the codes were compile under "win32" setting.
Error MSG: C:\Program Files (x86)\Windows Kits\8.0\Include\um\winnt.h(146): fatal error C1189: #error : "No Target Architecture"
EXAMPLE:
#include stdio.h
#include sys/types.h
#include dirent.h
int main(int argc, char* argv[])
{
const char *name = ".";
DIR *dirp;
struct dirent *dp;
dirp = opendir(name);
if (dirp != NULL) {
printf("opendir %s succeed!\n", name);
}
closedir(dirp);
return 0;
}
I had the same problem... Try to go PROJECT-> PROPERTIES -> Configuration Properties -> C/C++ -> Preprocessor, and in Preprocessor Definitions add AMD64. It works for me. PS put underscore before and after AMD64.
I am using Microsoft Visual Studio 2010, and i am working on open source Clamav, my code is given below which is generating an error
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <clamav.h>
int main(int argc, char **argv)
{
int fd, ret;
unsigned long int size = 0;
unsigned int sigs = 0;
long double mb;
const char *virname;
struct cl_engine *engine;
if(argc != 2) {
printf("Usage: %s file\n", argv[0]);
return 2;
}
if((fd = open(argv[1], O_RDONLY)) == -1) {
printf("Can't open file %s\n", argv[1]);
return 2;
}
if((ret = cl_init(CL_INIT_DEFAULT)) != CL_SUCCESS) {
printf("Can't initialize libclamav: %s\n", cl_strerror(ret));
return 2;
}
if(!(engine = cl_engine_new())) {
printf("Can't create new engine\n");
return 2;
}
/* load all available databases from default directory */
if((ret = cl_load(cl_retdbdir(), engine, &sigs, CL_DB_STDOPT)) != CL_SUCCESS) {
printf("cl_load: %s\n", cl_strerror(ret));
close(fd);
cl_engine_free(engine);
return 2;
}
printf("Loaded %u signatures.\n", sigs);
/* build engine */
if((ret = cl_engine_compile(engine)) != CL_SUCCESS) {
printf("Database initialization error: %s\n", cl_strerror(ret));;
cl_engine_free(engine);
close(fd);
return 2;
}
/* scan file descriptor */
if((ret = cl_scandesc(fd, &virname, &size, engine, CL_SCAN_STDOPT)) == CL_VIRUS) {
printf("Virus detected: %s\n", virname);
} else {
if(ret == CL_CLEAN) {
printf("No virus detected.\n");
} else {
printf("Error: %s\n", cl_strerror(ret));
cl_engine_free(engine);
close(fd);
return 2;
}
}
close(fd);
/* free memory */
cl_engine_free(engine);
/* calculate size of scanned data */
mb = size * (CL_COUNT_PRECISION / 1024) / 1024.0;
printf("Data scanned: %2.2Lf MB\n", mb);
return ret == CL_VIRUS ? 1 : 0;
}
the following error is generated
LINK : fatal error LNK1181: cannot open input file 'libclamav.lib'
kindly guide me
You get an LNK1181 error in Visual Studio when the .lib or .obj files that are specified during linking are not found in the current directory, any of the directories that are specified by the LIBPATH linker option, or any of the directories that are specified in the LIB environment variable.
You may add the directory that contains libclamav.lib library file to the LIBPATH to resolve the problem (this instructions may vary a bit depending on your Visual Studio version):
In Solution Explorer, right-click the project, and then click Properties.
In the Property Pages dialog box, expand Linker, and then click General.
In the Additional Library Directories field, specify the path where libclamav.lib resides.
The error can also happen when the LIBPATH contains spaces. If that's the case, move the library to a path without spaces or put quotation marks around the path.
You can also fix it by specifying the library path in DOS "8.3" format.
To get the 8.3 form, do (at the command line):
DIR /AD /X
recursively through every level of the directories.