I am currently building POCO libraries with CMake like this:
cmake -DCMAKE_BUILD_TYPE=Debug -G "NMake Makefiles" -DPOCO_STATIC .
nmake
It all works fine, except for the fact that libraries aren't created with suffix mtd.lib or mdd.lib, just d.lib. Because of this, then my application fails to link to PocoFoundationsmdd.lib since the file doesn't exist.
Is there any keyword to pass in the cmake command so that it builds with the right prefix? I know that from Visual Studio there are configurations like debug_static_md one can select, but is it possible to do it through cmake without modifying the CMakelists.txt?
It was as simple as adding add_definitions( -DPOCO_STATIC -DPOCO_NO_AUTOMATIC_LIBS) to the CMakelists.txt that is consuming the POCO libraries compiled with cmake. That effectively disables the header (*.h) definitions that attempt to link from the code:
#if defined(_MSC_VER)
#if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(Crypto_EXPORTS)
#pragma comment(lib, "PocoXXX" POCO_LIB_SUFFIX)
#endif
#endif
Related
I have been trying to build a cmake c++ project. More specifically I am trying to use the gdal library in this project. In the CMakeLists.txt it says find_library(GDAL gdal) after doing some research i found, that visual studio can open cmake files by default as mention in this thread: https://learn.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=vs-2019.
Moreover, visual studio should also automatically include the gdal library once i have set it up with vcpkg correctly. I've already downloaded the x64-windows version of the library (vcpkg install gdal:x64-windows) in order to build for the right architecture and made it available via vcpkg integrate install on a user-wide scope.
After some trial and error, everything works fine now, the toolchain gets included accordingly and the library is found automatically, resulting in a configuration like that:
However, when trying to include the header files (or anything else; see code snippet), visual studio does not seem to link the library correctly as it will result in the error message: cannot open source file "gdal/gdal.h".
#include <gdal/ogrsf_frmts.h>
#include <gdal/gdal.h>
#include <gdal>
Where should I further investigate?
As others have said vcpkg integrate install and vcpkg.cmake don't work together the reason being:
set_target_properties(${name} PROPERTIES VS_USER_PROPS do_not_import_user.props)
set_target_properties(${name} PROPERTIES VS_GLOBAL_VcpkgEnabled false)
this deactivates the integration. The reason to deactivate the integration is so that you don't write an incomplete CMakeLists.txt (e.g. missing the include directory or not linking all required libraries).
As such replace find_library(GDAL gdal) with find_package(GDAL REQUIRED) and target_link_libraries against the target GDAL::GDAL (https://cmake.org/cmake/help/v3.17/module/FindGDAL.html)
I have been struggling for the last 8 hours to find information on how to reference a library in a C project on Windows built with CMake, specifically cURL.
I have downloaded version 7.67 cURL source from the website, and then went used the visual studio developer command prompt to compile the CMake project into a build folder using the standard method of:
cd winbuild
nmake /f Makefile.vc mode=dll
Which outputs three curl folders, one of them called "libcurl-vc-x86-release-dll-ipv6-sspi-winssl".
In that folder contains a lib, a bin, and an include folder.
I built my C project with CLion and this is the CMake file that is generated.
cmake_minimum_required(VERSION 3.15)
project(hello_world C)
set(CMAKE_C_STANDARD 99)
add_executable(hello_world main.c)
How do I use my compiled CURL in my C project with CMake properly?
I finally solved this issue by creating a cmake folder at the C: directory, and copying in the built curl CMake project folder.
The issue was that there weren't any specific tutorials that I found on how to reference projects on Windows for CMake, specifically the curl project.
Fortunately, I found this post which specified an issue I had in referencing the include folder and .lib directory separately.
How to link shared library *dll with CMake in Windows
cmake_minimum_required(VERSION 3.15)
project(hello_world C)
set(CMAKE_C_STANDARD 99)
include_directories("C:/cmake/libcurl-vc-x86-release-dll-ipv6-sspi-winssl/include")
link_directories("C:/cmake/libcurl-vc-x86-release-dll-ipv6-sspi-winssl/lib")
add_executable(hello_world main.c)
set( LIBS libcurl )
target_link_libraries(hello_world ${LIBS} )
Now the code compiles and runs succesfully.
I don't believe this is the proper method of doing this though, any help would be appreciated.
I am trying to build a program using CMake that depends on a third party library. This third party library contains a CMakeLists.txt file so what I want to do is keep the source code of the third party library within my project directory, and build it using add_subdirectory(path/to/lib), and then link my target against the static library that the third party library generated.
my CMakeLists.txt:
cmake_minimum_version(VERSION 3.10)
project(my_project)
add_subdirectory("${CMAKE_SOURCE_DIR}/extern/somelib")
# my-code:
# somelib CMakeLists.txt file has a project name: SOMELIB
# which lets me access the directory where the files are built
# on windows it builds to /Release, on mac and linux it just builds
# to the binary dir
set(SOMELIB_LIBS "${SOMELIB_BINARY_DIR}/Release")
add_executable(my_program my_main.cpp)
target_link_libraries(my_program "${SOMELIB_LIBS}/SOMELIB.lib" "${SOMELIB_LIBS}/SOMELIBmain.lib")
I then make a build directory and from that directory I do:
cmake -G "Visual Studio 15 2017" ..
cmake --build .
The build command fails with a "LINK : fatal error LNK1181: cannot open input file 'extern/somelib/Release/SOMELIBmain.lib' ..."
My workaround for now has been to comment out the part that says "#my-code", build the somelib dependency first which generates the static libraries, and then uncomment out my-code and build again which then works correctly.
How can I tell CMake to build the subdirectory first, and then link against the static libraries that it generated?
Short answer: tell CMake that there is dependency between its targets.
target_link_libraries(my_program PRIVATE SOMELIB SOMELIBmain)
CMake will evaluate SOMELIBs locations for you and link my_program against SOMELIB and SOMELIBmain[1]. Works for both Debug and Release configurations and also for Linux.
You shouldn't have to worry where CMake places build files[2] and this is what so called "modern CMake" is trying to achieve. I will leave here just brief description but check link on the bottom of answer[3].
Anyway, the key concept is that whenever you create library/executable (target), you list its usage+build requirements and dependencies to other targets. You declare dependencies using target_link_libraries(<your_lib> KEYWORD <dependencies>). Such line will not only make <you_lib> link against listed dependencies, it will inherit their usage requirements (usually, public include directories) and order CMake to build dependent libraries before <your_lib>.
The beauty of it is that even if SOMELIB does not follow modern CMake ideas (does not declare build/usage requirements), you still should be able to do just with this single line.
[1] I assumed that CMake targets are named same as output library names, but it is not mandatory. For OP's case it turned out that static library targets are suffixed with -static, so he had to write SOMELIB-static SOMELIBmain-static
[2] Unfortunately, it is not so easy with shared libraries on Windows (DLLs)
[3] I'd start with this blog entry: https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/
I have successfully built a C++ project using MSYS2 / MinGW64 / CMake tools. Now I would like to edit it and debug it in Visual Studio, as it is a nice IDE and the default development tool in Windows. Sadly, I am not able to build the project in Visual Studio because it cannot find libraries.
Here is the CMakeLists.txt file I'm using where, among other things, I specify where are the include folders, the link files and link directories:
# src/CMakeLists.txt
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
# Project name and current version
project(rascam VERSION 0.1 LANGUAGES CXX)
# Enable general warnings
# See http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
# Use 2014 C++ standard.
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Must use GNUInstallDirs to install libraries into correct locations on all platforms:
include(GNUInstallDirs)
# Pkg_config is used to locate header and files for dependency libraries:
find_package(PkgConfig)
# Defines variables GTKMM_INCLUDE_DIRS, GTKMM_LIBRARY_DIRS and GTKMM_LIBRARIES.
pkg_check_modules(GTKMM gtkmm-3.0)
link_directories( ${GTKMM_LIBRARY_DIRS} )
include_directories( ${GTKMM_INCLUDE_DIRS} )
# Compile files:
add_executable(rascapp
cpp/main.cpp
cpp/main-window.cpp
)
# Add folder with all headers:
target_include_directories(rascapp PRIVATE hpp)
# Link files:
target_link_libraries(rascapp
${GTKMM_LIBRARIES}
)
To set up my environment I installed MSYS2 on a Windows platform, and added all the following packages via pacman:
pacman -S base base-devel net-utils git ruby wget man
pacman -S msys/openssh msys/vim msys/bc nano msys/tmux
pacman -S gzip zip unzip msys/p7zip tar msys/tree
pacman -S msys/winpty msys/ed msys/pwgen msys/zsh
pacman -S mingw64/mingw-w64-x86_64-jq
pacman -S msys/screenfetch
pacman -S mingw-w64-x86_64-toolchain
pacman -S mingw64/mingw-w64-x86_64-cmake
My project is dependent on Gtkmm, so I added the following dependency:
pacman -S mingw64/mingw-w64-x86_64-gtkmm3
Then I added the C:\Msys2\MinGW64\bin to the path.
Then, I switched to the MSYS2/MinGW64 terminal, and fetched my project, created a build folder and built it. As I'm in Windows, the CMake produces Visual Studio files by default. I would be fine with that, if only I could make it work. Running out of ideas, I specified the Unix Makefiles option:
cd /c/where/your/root/folder/is
git clone https://github.com/cpp-tutorial/raspberry-cpp-gtk-opencv.git
cd raspberry-cpp-gtk-opencv
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug -G"Unix Makefiles" ../src/
make
./racapp.exe
And this does build the project. It produces an executable that I can launch from either MinGW64 or a Window Explorer by double clicking on it. I can also gdb it
After checking that the project looks right, I tried to open it in Visual Studio Community 2017 15.9.3 in two different ways:
Use CMake to build a Visual Studio project: Visual studio opens the project and I can see the different targets, but when I launch a debug session it complains that it cannot found Gtk libraries. Looking in the project properties, I can see the that the libraries are taken from the correct path C:\Msys2\MinGW64\bin. And I verified that the library exists, although with a different name: libgtkmm-3.0.dll.a instead of gtkmm-3.0.dll.
Use Visual Studio's Open File feature: Again, project opens, I can see the targets and the source files, but it complains that it doesn't find the include files gtkmm.h. I haven't managed to reach link phase, but my guess is that it wouldn't find libraries.
My question is, what is the correct and standard way to build and debug a MSYS2 / MinGW64 / CMake project in Visual Studio?
As other users commented (thanks, #DavidGrayson), the gcc.exe and g++.exe compilers that are installed in the MSYS2 configuration do not use the format that Visual Studio requires for debug symbols. In consequence, it is not possible to use Visual Studio for debugging executables built with Mingw.
To be able to debug (and build and edit), use some other IDE, more MinGW friendly, like Code::Blocks.
Still, to answer my own question, I describe here the procedure to configure the project in Visual Studio to edit the source files, build and launch the executable. For this procedure, no need to use CMake for anything:
Launch Visual Studio 2017
File -> Open -> Folder...
Select the folder that contains the top CMakeLists.txt.
It should find automatically that this is a CMake project, and try to load it. Maybe it complains about some errors.
CMake -> Change CMake Settings -> Choose your top CMakeLists.txt.
In the dialog, look for Mingw64-Release (actually, there is a *Mingw64-Debug, but you will not be able to debug anyway).
If everything went well, a CMakeSettings.json has appeared on your project, and Visual Studio rebuilds the project, this time without errors.
Choose an executable target.
Launch.
It should build then execute the application.
This is no longer true, you can build and debug projects using MingW gdb by following the steps mentioned below using the latest Visual Studio IDE:
https://devblogs.microsoft.com/cppblog/using-mingw-and-cygwin-with-visual-cpp-and-open-folder/.
I've tried for a bigger project and it works fine apart from the fact that the debugging is not very clean.
I am trying to build PoDoFo Library on my Windows Platform (for use as an API). It is done using CMake. The ReadMe file says the following. Unfortunately I am new to CMake and I can't make out much from it.
Building PoDoFo on Windows
CMake 2.6.x is required for Windows. You can download it from
cmake.org .
On Windows, PoDoFo may be built as either a shared or static library.
Building both is not supported. By default only the shared library
will be built. If you want a static library, just disable generation
of the shared library with the extra argument to cmake:
-DPODOFO_BUILD_SHARED=FALSE
Handling library naming on win32
Especially on Windows it is also common for custom built libraries to
have different names to those you might download as pre-built copies.
CMake won't be able to find them if they're called something else
unless you tell it. Use these variables to tell CMake what names to
look for a library under:
•FREETYPE_LIBRARY_NAMES_DEBUG, FREETYPE_LIBRARY_NAMES_RELEASE and FREETYPE_LIBRARY_NAMES
•TIFF_LIBRARY_NAMES_DEBUG, TIFF_LIBRARY_NAMES_RELEASE and TIFF_LIBRARY_NAMES
•LIBJPEG_LIBRARY_NAMES_DEBUG, LIBJPEG_LIBRARY_NAMES_RELEASE and LIBJPEG_LIBRARY_NAMES
•ZLIB_LIBRARY_NAMES_DEBUG, ZLIB_LIBRARY_NAMES_RELEASE,ZLIB_LIBRARY_NAMES
CMake builds on Windows with MinGW
Once MinGW is set up, make sure that the MinGW "bin" directory is on
your PATH, and be sure to set CMAKE_INCLUDE_PATH and
CMAKE_LIBRARY_PATH such that CMake can find the headers and .lib files
for the libraries PoDoFo requires. The GnuWin32 library packages from
http://gnuwin32.sf.net/ are known to work with PoDoFo, so installing
zlib, freetype, and libjpeg from there should do the trick.
To configure and build PoDoFo with a default GnuWin32 install and with
MinGW already on your PATH:
md ..\podofo-debug
cd ..\podofo-debug
cmake -G "MinGW Makefiles" ..\podofo-src -DCMAKE_INCLUDE_PATH=c:\progra~1\gnuwin32\include -DCMAKE_LIBRARY_PATH=c:\progra~1\gnuwin32\lib -DPODOFO_BUILD_SHARED:BOOL=FALSE mingw32-make
I have installed CMake and downloaded the other libraries mentioned like freetype, zlib, libjpeg. Their header and binary files are in their respective folders.
Now what should DCMAKE_INCLUDE_PATH and DCMAKE_LIBRARY_PATH be? Also what is "MinGW Makefiles"? Do I have to supply any extra parameters?
I'll be grateful if someone can explain in simple steps how I can go about it.
EDIT: error while executing CMAKE:
-- Ensure you cppunit installed version is at least 1.12.0
Cppunit not found. No unit tests will be built.
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPack
ageHandleStandardArgs.cmake:97 (message):
Could NOT find FREETYPE (missing: FREETYPE_LIBRARY FREETYPE_INCLUDE_DIR)
Call Stack (most recent call first):
C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStan
dardArgs.cmake:291 (_FPHSA_FAILURE_MESSAGE)
cmake/modules/FindFREETYPE.cmake:75 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:372 (FIND_PACKAGE)
To build PoDoFo you need installed GnuWin32, CMake, MinGW32 and PoDoFo sources
download GetGnuWin32
install to c:\getgnuwin32
open cmd.exe
cd c:\getgnuwin32
download.bat
install.bat
Then as suggested in #ibizaman answer
cmake -G "MinGW Makefiles" -DCMAKE_INCLUDE_PATH="C:\gnuwin32\include" -DCMAKE_LIBRARY_PATH="C:\gnuwin32\lib" -DPODOFO_BUILD_STATIC=TRUE ..
FreeType should be installed with GnuWin32 packages
If you followed all the instructions, to compile it should normally be enough to do:
cd <podofo root directory (where CMakeLists.txt is)>
mkdir build
cd build
cmake -G "MinGW Makefiles" -DCMAKE_INCLUDE_PATH=<path to headers> -DCMAKE_LIBRARY_PATH=<path to libraries> -DPODOFO_BUILD_SHARED:BOOL=FALSE ..
mingw32-make
Step by step:
First, go to the directory where your podofo sources are. You should see a CMakeLists.txt file lying around.
Second (and third), create (and go into) a directory where the compilation will be done. I call it build but it can be any name. This is a best practice since you can simply delete the build directory and come back to a clean state.
Fourth, ask cmake to create the makefile(s) for mingw:
Specify the PODOFO_BUILD_SHARED like advertised in the manual: build shared or static version.
CMAKE_INCLUDE_PATH and CMAKE_LIBRAY_PATH are used to reference to the packages needed to build podofo. If you downloaded the precompiled packages like you did since you have de headers and the binaries, then you need to give to cmake the path to those headers and binaries. You can specify the variables multiple times if needed, e.g.:
cmake -G "MinGW Makefiles" -DCMAKE_INCLUDE_PATH=/path/to/freetype/include -DCMAKE_LIBRARY_PATH=/path/to/freetype/lib -DCMAKE_INCLUDE_PATH=/path/to/zlib/include -DCMAKE_LIBRARY_PATH=/path/to/zlib/lib -DPODOFO_BUILD_SHARED:BOOL=FALSE ..
The "MinGW Makefiles" tells cmake to create makefiles specific to mingw. Else, by default on windows, it creates makefiles specific to Microsoft Visual Studio.
Finaly reference the CMakeLists.txt in the parent directory with .. at the end.
Last, but not least, compile with the mingw version of make.