mingw cannot find png.h for libpng on Windows - cmake

I am working on a project that requires me to use CImg which in turn needs libpng. I am using CLion and cmake with MinGW-W64 GCC-8.1.0. I have been following this answer - https://stackoverflow.com/a/41956016/11382155 to get it set up.
This is how my CMakeLists.txt looks
cmake_minimum_required(VERSION 3.15)
project(CImgProject)
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES main.cpp)
add_executable(CImgProject ${SOURCE_FILES})
# You can alter these according to your needs, e.g if you don't need to display images - set(YOU_NEED_X11 0)
set(YOU_NEED_X11 1)
set(YOU_NEED_PNG 1)
if(${YOU_NEED_X11} EQUAL 1)
message(STATUS "Looking for X11...")
find_package(X11 REQUIRED)
include_directories(${X11_INCLUDE_DIR})
target_link_libraries(CImgProject ${X11_LIBRARIES})
else()
target_compile_definitions(CImgProject PRIVATE cimg_display=0)
endif()
if(${YOU_NEED_PNG} EQUAL 1)
message(STATUS "Looking for libpng...")
set(ZLIB_ROOT "CImg283/zlib-1.2.11")
set(ZLIB_LIBRARY "CImg283/zlib-1.2.11")
set(PNG_ROOT "CImg283/lpng1637")
set(PNG_LIBRARY "CImg283/lpng1637")
find_package(PNG REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
target_link_libraries (CImgProject ${PNG_LIBRARY})
target_compile_definitions(CImgProject PRIVATE cimg_use_png=1)
endif()
This is my main.cpp
#include "CImg283/CImg.h"
using namespace cimg_library;
int main() {
CImg<unsigned char> img(640,400,1,3); // Define a 640x400 color image with 8 bits per color component.
img.fill(0); // Set pixel values to 0 (color : black)
unsigned char purple[] = { 255,0,255 }; // Define a purple color
img.draw_text(100,100,"Hello World",purple); // Draw a purple "Hello world" at coordinates (100,100).
img.display("Window Title"); // Display the image in a display window.
img.save_png("test.png"); // Save as PNG to prove we linked correctly
return 0;
}
The problem I have is that when I hit build, I get the following error
====================[ Build | CImgProject | Debug ]=============================
"C:\Program Files\JetBrains\CLion 2019.1\bin\cmake\win\bin\cmake.exe" --build C:\Users\bhave\OneDrive\Desktop\untitled\cmake-build-debug --target CImgProject -- -j 6
Scanning dependencies of target CImgProject
[ 50%] Building CXX object CMakeFiles/CImgProject.dir/main.cpp.obj
In file included from C:\Users\bhave\OneDrive\Desktop\untitled\main.cpp:3:
C:\Users\bhave\OneDrive\Desktop\untitled\CImg283/CImg.h:447:10: fatal error: png.h: No such file or directory
#include "png.h"
^~~~~~~
compilation terminated.
mingw32-make.exe[3]: *** [CMakeFiles\CImgProject.dir\build.make:63: CMakeFiles/CImgProject.dir/main.cpp.obj] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:75: CMakeFiles/CImgProject.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/CImgProject.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: CImgProject] Error 2
I don't know why this error is popping up when cmake is able to find libpng and I checked that png.h definitely exists.

I resolved the problem by getting rid of
set(ZLIB_ROOT "CImg283/zlib-1.2.11")
set(ZLIB_LIBRARY "CImg283/zlib-1.2.11")
set(PNG_ROOT "CImg283/lpng1637")
set(PNG_LIBRARY "CImg283/lpng1637")
and just grabbing the mingw-64 library distribution from https://packages.msys2.org/package/mingw-w64-x86_64-libpng and putting the files in the correct location inside my mingw distribution. Be sure to put it in both mingw folders inside the 64 bit installation.

Related

Crazy error when running a connector c++ program

I have a problem with Connector/C++.
I'm using CLion as IDE and want to create a c++ program to interact with mysql database.
this is my CMakeList.txt file which i include c++/connector static and dynamic libraries in it:
cmake_minimum_required(VERSION 3.15)
project(cpp_programming)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(MYSQL_CPPCONN_DIR "C:/Program Files/MySQL/MySQL Connector C++ 8.0")
include_directories(${PROJECT_NAME} PUBLIC ${MYSQL_CPPCONN_DIR}/include)
add_executable(${PROJECT_NAME} main.cpp)
# Static Libraries
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/libcrypto.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/libssl.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn8.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn8-static.lib)
target_link_libraries(${PROJECT_NAME} ${MYSQL_CPPCONN_DIR}/lib64/vs14/mysqlcppconn-static.lib)
# Dynamic Link Libraries
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/libcrypto-1_1-x64.dll)
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/libssl-1_1-x64.dll)
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/mysqlcppconn-7-vs14.dll)
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/mysqlcppconn8-2-vs14.dll)
And i just include xdevapi.h header in my c++ source file like this:
#include <iostream>
#include <mysqlx/xdevapi.h>
using namespace std;
int main()
{
return 0;
}
And i run file in Release mode in clion and i receive these errors:
Error message i see in the clion console
====================[ Build | cpp_programming | Release ]=======================
"C:\Program Files\JetBrains\CLion 2019.3.2\bin\cmake\win\bin\cmake.exe" --build C:\Users\Kianoush\CLionProjects\cpp_programming\cmake-build-release --target cpp_programming -- -j 2
Scanning dependencies of target cpp_programming
[ 50%] Building CXX object CMakeFiles/cpp_programming.dir/main.cpp.obj
[100%] Linking CXX executable cpp_programming.exe
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.text$_ZNK6mysqlx4abi22r05Value5printERSo[_ZNK6mysqlx4abi22r05Value5printERSo]+0x21): undefined reference to `mysqlx::abi2::r0::DbDoc::print(std::ostream&) const'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.text$_ZNK6mysqlx4abi22r05Value5printERSo[_ZNK6mysqlx4abi22r05Value5printERSo]+0x2c): undefined reference to `mysqlx::abi2::r0::common::Value::print(std::ostream&) const'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.text$_ZNK6mysqlx4abi22r08internal14Warning_detail5printERSo[_ZNK6mysqlx4abi22r08internal14Warning_detail5printERSo]+0x87): undefined reference to `mysqlx::abi2::r0::string::Impl::to_utf8[abi:cxx11](mysqlx::abi2::r0::string const&)'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.rdata$_ZTCN6mysqlx4abi22r05ValueE0_NS1_6common5ValueE[_ZTCN6mysqlx4abi22r05ValueE0_NS1_6common5ValueE]+0x20): undefined reference to `mysqlx::abi2::r0::common::Value::print(std::ostream&) const'
CMakeFiles\cpp_programming.dir/objects.a(main.cpp.obj):main.cpp:(.rdata$.refptr._ZTVN6mysqlx4abi22r05DbDocE[.refptr._ZTVN6mysqlx4abi22r05DbDocE]+0x0): undefined reference to `vtable for mysqlx::abi2::r0::DbDoc'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\cpp_programming.dir\build.make:97: recipe for target 'cpp_programming.exe' failed
CMakeFiles\Makefile2:74: recipe for target 'CMakeFiles/cpp_programming.dir/all' failed
CMakeFiles\Makefile2:81: recipe for target 'CMakeFiles/cpp_programming.dir/rule' failed
mingw32-make.exe[3]: *** [cpp_programming.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/cpp_programming.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles/cpp_programming.dir/rule] Error 2
mingw32-make.exe: *** [cpp_programming] Error 2
Makefile:117: recipe for target 'cpp_programming' failed
Do i make mistakes in linking dll files or static files ?
What solution do you suggest ?
please help me, this take me in trouble for many days.
Full screen image
There are a couple of issues here.
You do not need to link all of these different libraries. You really only should require one mysqlcppconn library to be linked. To locate the library, try using find_library(), and use it for linking instead. Your CMake file should reduce to something like this:
cmake_minimum_required(VERSION 3.15)
project(cpp_programming)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(MYSQL_CPPCONN_DIR "C:/Program Files/MySQL/MySQL Connector C++ 8.0")
include_directories(${PROJECT_NAME} PUBLIC ${MYSQL_CPPCONN_DIR}/include)
add_executable(${PROJECT_NAME} main.cpp)
# Find the mysqlcppconn library.
find_library(mysqlcppconn_LIB
mysqlcppconn8
HINTS ${MYSQL_CPPCONN_DIR}/lib/vs14
# Static Libraries
target_link_libraries(${PROJECT_NAME} PUBLIC ${mysqlcppconn_LIB})
I'm not sure if you are using the ssl and crypto libraries, so add those back in if needed.
Your libraries (VisualC++) do not match the compiler (MinGW) you are using. To my knowledge, the MySQL Connector C++ downloads do not provide a MinGW set of libraries; they only provide libraries that are built with the Visual Studio compiler. Thus, you need to switch to use the VisualC++ compiler to use these libraries. Another option would be to download the MySQL source and try to build it with MinGW, but that may be more difficult.
Hope this helps!

Link ncurses in CLion CMake

I'm currently playing around with ncurses. Ncurses is a library I installed, NOT my own file. I already did some stuff but using an IDE is much easier so I decided to use CLion (I'm on Linux so can't use Visual Studio). I got the following CMakeLists.txt:
cmake_minimum_required(VERSION 3.6)
project(ncurses)
set(CMAKE_C_STANDARD "${CMAKE_C_FLAGS} -Wall -Werror -lpdcurses")
set(SOURCE_FILES main.cpp ncurses.h)
add_executable(ncurses ${SOURCE_FILES})
My project is called ncurses I don't know if that'd matter.
I got the following main.cpp
#include <ncurses.h>
int main() {
initscr();
printw("Hello");
refresh();
getch();
endwin();
return 0;
}
However, I get the following errors:
/opt/clion/bin/cmake/bin/cmake --build /home/josh/ClionProjects/ncurses /cmake-build-debug --target all -- -j 4
make[2]: *** No rule to make target 'CMakeFiles/ncurses.dir/build'. Stop.
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/ncurses.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
I don't get what the problem is. I tried -lncurses except of lpdcurses but that doesn't work either. It only gives an error when building but not in the IDEA itself.
in your CMakeLists.txt
just add :
set(CMAKE_CXX_FLAGS "-lncurses")
To tell the compiler to link a library using CMake, you should use the target_link_libraries() function.
Add this in your CMakeLists.txt:
target_link_libraries(${PROJECT_NAME} ncurses)
However, the error code that you have doesn't seem to be caused by linking. Try adding this line: set(CMAKE_CXX_STANDARD 17) before your add_executable(). Replace 17 by whatever C++ version you want. I'm pretty sure that it wont change anything but heh, worth a try. Also, don't forget to reload cmake project and reset the cache.
For me solutions above did not work. However appending the last 4 lines to the code block below worked for me.
(Linux mint 20, Clion 2020.3)
CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
project(<YOUR_PROJECT>)
set(CMAKE_CXX_STANDARD 14)
find_package(Curses REQUIRED)
include_directories(${CURSES_INCLUDE_DIR})
add_executable(<YOUR_PROJECT> main.cpp)
target_link_libraries(<YOUR_PROJECT> ${CURSES_LIBRARIES})
Change <YOUR_PROJECT> to your actual project name.

Cannot get lldb location to resolve

I am attempting to compile and debug from the command line, using cmake and lldb. I'm not sure why this isn't working:
cmake_minimum_required (VERSION 2.6)
project (etest)
include_directories(src)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -g")
add_executable(etest src/m.cpp)
set_property(TARGET etest PROPERTY CXX_STANDARD 14)
set_property(TARGET etest PROPERTY CXX_STANDARD_REQUIRED ON)
Then:
~/Desktop/em2 cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/jbake/Desktop/em2
~/Desktop/em2 make
[ 50%] Building CXX object CMakeFiles/etest.dir/src/m.cpp.o
[100%] Linking CXX executable etest
[100%] Built target etest
~/Desktop/em2 lldb etest
(lldb) target create "etest"
Current executable set to 'etest' (x86_64).
(lldb) b src/m.cpp:7
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) breakpoint list
Current breakpoints:
1: file = 'src/m.cpp', line = 7, locations = 0 (pending)
I thought the -g option was necessary to get debug locations added to the executable for use with lldb, but I've been trying various tweaks for hours and cannot get anything to resolve. What am I missing?
There's a bug in lldb that means you either have to set a breakpoint with JUST the file name, or you have to use the full path as recorded in the debug information. Partial paths should work, but don't at present.
Using full paths is tricky if you have a build system that moves files around or refers to them through symbolic links. Then you have to get the path as spelled to the compiler. You can find this by doing:
(lldb) break set -f JustTheName.cpp -l 10
Then grab the address that the breakpoint was set at, and do:
(lldb) image lookup -v -a <BREAK_ADDRESS>
The file in the CompileUnit part of this output will be the path as spelled in the debug information.

How to specify files that depend on other files

I am pretty new to cmake and here is my CMakeLists.txt file on my project's root directory
cmake_minimum_required (VERSION 2.6)
project (Tools C)
set(CMAKE_C_FLAGS "-ansi -pedantic -Wall -Werror")
include_directories("include")
SET_SOURCE_FILES_PROPERTIES(lib/xstr.c PROPERTIES
OBJECT_DEPENDS "lib/xalloc.c")
SET_SOURCE_FILES_PROPERTIES(lib/counter.c PROPERTIES
OBJECT_DEPENDS "lib/xstr.c")
SET_SOURCE_FILES_PROPERTIES(lib/dynamic_array.c PROPERTIES
OBJECT_DEPENDS "lib/xalloc.c")
SET_SOURCE_FILES_PROPERTIES(lib/list.c PROPERTIES
OBJECT_DEPENDS "lib/xalloc.c")
add_executable(cat cat.c lib/xalloc.c lib/xfopen.c)
add_executable(counter counter.c lib/counter.c)
add_executable(darr dynamic_array.c lib/dynamic_array.c)
add_executable(linked list.c lib/list.c)
I keep c files that contains a main() function on my root directory. I keep other c files on {project_root}/lib directory.
My problem is that I am getting following error:
[ 33%] Built target cat
mingw32-make.exe[2]: *** No rule to make target 'lib/xstr.c', needed by 'CMakeFi
les/counter.dir/lib/counter.c.obj'. Stop.
CMakeFiles\Makefile2:94: recipe for target 'CMakeFiles/counter.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/counter.dir/all] Error 2
Makefile:75: recipe for target 'all' failed
mingw32-make.exe: *** [all] Error 2
What I want to achieve is to link{project_root}/cat.c with {project_root}/lib/xstr.c and {project_root}/lib/xalloc.c etc.
How can I achieve that?
You are taking cmake far too complicated! You have to set dependencies within targets, not source files. In your specific case, I suggest you add a few intermediate libraries. You can have them static so that the executable linking to them will not have problems in retrieving the linked library at runtime (the executable will integrate all the symbols and definitions he needs from the library).
Your code can be reduced as follow:
cmake_minimum_required (VERSION 2.8) # <<--2.6 is very outdated
project (Tools C)
set(CMAKE_C_FLAGS "-ansi -pedantic -Wall -Werror")
include_directories("include")
add_library(xalloc STATIC lib/xalloc.c)
add_library(xstr STATIC lib/xstr.c)
add_executable(cat cat.c lib/xfopen.c)
add_executable(counter counter.c lib/counter.c)
add_executable(darr dynamic_array.c lib/dynamic_array.c)
add_executable(linked list.c lib/list.c)
target_link_libraries(cat xalloc)
target_link_libraries(counter xstr xalloc) #xstr needs stuff from xalloc
target_link_libraries(darr xalloc)
target_link_libraries(linked xalloc)
Note: Are you sure you need darr and linked as executables? They look very much like a library... Also, having a file called counter.c and one lib/counter.c does not seem very safe (same for dynamic_array and list).
Some useful links:
http://www.cmake.org/cmake/help/v3.0/command/add_library.html
http://www.cmake.org/cmake/help/v3.0/command/target_link_libraries.html

CMake Why cannot use .exe for custom target

Here is the CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project("cmake_oneoneone")
add_executable(main src/main.cpp)
set(library_name liba CACHE string "This variable is the library name")
add_library(${library_name} STATIC src/liba.cpp)
target_link_libraries(main ${library_name})
include_directories(include)
add_custom_target(run_main
COMMAND ./main
DEPENDS main
)
The output is:
~/workspace/cmake_test/build$ make run_main
[ 50%] Built target liba
[100%] Built target main
Hello world!
[100%] Built target run_main
but if I change executable to .exe
cmake_minimum_required(VERSION 2.8)
project("cmake_oneoneone")
add_executable(main.exe src/main.cpp)
set(library_name liba CACHE string "This variable is the library name")
add_library(${library_name} STATIC src/liba.cpp)
target_link_libraries(main.exe ${library_name})
include_directories(include)
add_custom_target(run_main
COMMAND ./main.exe
DEPENDS main.exe
)
~/workspace/cmake_training/build$ make run_main
make[3]: *** No rule to make target `../main.exe', needed by `CMakeFiles/run_main'. Stop.
make[2]: *** [CMakeFiles/run_main.dir/all] Error 2
make[1]: *** [CMakeFiles/run_main.dir/rule] Error 2
make: *** [run_main] Error 2
I tried either Linux and Windows on both the CMake behaves the same.
If you check the documentation of the ADD_EXECUTABLE command, you can figure out that CMake automatically adds the extension .exe to your executable in case that you are generating it in a Windows environment. If you are in Linux, obviously generate a .exe has no sense:
Adds an executable target called to be built from the source files listed in the command invocation. The corresponds to the logical target name and must be globally unique within a project. The actual file name of the executable built is constructed based on conventions of the native platform (such as .exe or just ).
So you do not have to add the .exe at the end of the name of your executable.