CMake: Depending on Visual Studio projects - visual-c++

My project currently depends upon a library (PJSIP) that is distributed with Autotools build scripts for *NIX and Visual Studio project files for Windows.
My project currently uses the CMake build system. The current script is Linux-specific: it assumes that PJSIP has been installed as a prerequisite (in a system-wide library location, managed by the package manager) and only specifies target_link_libraries(pj pjnath pjlib-util). This is canonical for Linux software.
I would like to make my project also work for Visual Studio. What is the canonical Windows way to set up this dependency? Should it be configured in some global Visual Studio setting? Or should PJSIP be in a subdirectory, and CMake told to invoke the correct build system itself?

To find dependent 3rd Party libraries, follow the CMake guide, http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
Generally speaking, CMake prefers absolute paths. During my evaluation of CMake, I found that it does not have a canonical way to reference dependent libraries in Visual Studio. Their message is that CMake should be run on every developer system in order to set up the build environment for that specific target station. Therefore I could never create a solution file directly from CMake that could be versioned because the paths would be absolute. It would be possible but only after modifying the CMake project files after creation.
I had labored over this issue many times as CMake software needed to be approved on our developer stations before the build system was created.
In the end, I had versioned modified CMakeLists.txt files for all our dependent projects that finds the correct canonical paths to locations and had the caveat that anyone that built (these were for dependent 3rd party libraries that only get built on version changes) must have CMake installed.

Related

Difference between popular CMake build system and genproj tool for OpenCASCADE

While exploring about the platform setup for OpenCASCADE, I came to know about WOK commands which arent needed for CMake build system to use with OpenCASCADE
However another option of genproj tool (for which I havent yet found any exe but DLLs..) to be used with MSVC+ in built compiler so that we dont need any gcc installation
Whats the difference between the twos and which one is better and easier??
Also suggest me how to download and install and setup genproj on windows
OCCT project provided the following build systems:
CMake. This is the main building system since OCCT 7.0.0.
It allows building OCCT for almost every supported target platform.
WOK. This was an in-house building system used by OCCT before 7.0.0 release.
The tool handled classes defined in CDL (CAS.CADE definition language) files (WOK generated C++ header files from CDL) and supported building in a distributed environment (e.g. local WOK setup builds only modified source files and reused unmodified binary / object files from local network). WOK support has been discontinued since OCCT 7.5.0 and unlikely will be able building up-to-date OCCT sources (although project structure remains compatible with WOK).
genproj. This is a Tcl script allowing to generate project for building OCCT using Visual Studio (2010+), Code::Blocks, XCode and Qt Creator. This script has been initially extracted from WOK package (where it was implemented as command wgenproj in it's shell) and now maintained independently from it.
qmake. Experimental adm/qmake solution can be opened directly from QtCreator without CMake plugin (the project files will be generated recursively by qmake). Although header files generation (filling in inc folder) still should be done using genproj (qmake scripting capabilities were found too limited for this staff).
genproj doesn't require any DLLs or EXE files - it comes with OCCT itself and requires Tcl interpreter. On Windows platform it can be executed with genconf.bat and genproj.bat batch scripts in the root of OCCT source code folder. At first launch it will ask to put a path to tclsh.exe.
While CMake is the main building tool for OCCT project, genproj remains maintained and used by (some) developers - mostly due to personal habits and hatred to CMake. They differences of genproj from CMake that could be considered as advantages in some cases:
Generated project files can be moved to another location / computer without necessity to re-generate them.
Simplified 3rd-party dependency search tool genconf with GUI based on Tcl/Tk.
Batch-script environment/configuration files (env.bat and custom.bat), although CMake script in OCCT emulates similar files.
Generated Visual Studio solution contains Debug+Release and 32bit/64bit configurations.
Running Draw Harness and regression tests can be started directly from Visual Studio (without building any INSTALL target).
No problems with CMakeCache.txt.
Limitations of genproj:
No CMake configuration files. Other CMake-based projects would not be able re-using configuration files to simplify 3rd-party setup.
Regeneration of project files should be called explicitly.
Out-of-source builds are not supported (however, each configuration is put into dedicated sub-folder).
No INSTALL target.
No PCH (pre-compiler header file) generation.
It should be noted, that several attempts have been done to make compiler / linker flags consistent between CMake and genproj, but in reality they may be different.

Is Intel_MKL supposed to populate the include folders, etc, on MSVC

I've installed Intel MKL and it shows in dropdown menu of VS 2017 and VS 2019. Everything seems fine, except I have to manually type in the locations of include and library files. Did I misconfigure something?
What works for me is to explicitly add the include folder
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019.4.245\windows\mkl\include
and library folder
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019.4.245\windows\mkl\lib\intel64_win
However, I do note that MKL_ROOT is not defined as an environment variable by "default". If I run
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019.4.245\windows\mkl\bin\mklvars.bat intel64
then after that MKL_ROOT is defined and the PATH includes the library locations and, I guess, if I then launch MSVC from the commmand line then it should probably work. But I was hoping this would all be automated, somehow. Advice?
Tunneller,
The ease of MKL setup in Visual Studio depends on how you installed it. This article explains how to do manual linking of MKL to VS if you did not install the integration component. And this article explains how to invoke the automatic linking if you did install the integration component.
The above articles refer to the Intel Parallel Studio installation. It may differ if you install MKL as a standalone component or via Intel System Studio.
I hope this helps.
Pamela

Application deployment with 3rd-party dependencies for both Linux and Windows, using CMake and Conan

I'm working on a project, which targets both Windows and Linux (and possible in the future MacOS). It consists of some applications with several shared libraries. It is written in modern C++ and modern CMake. It also uses 3rd-party libraries like Qt, OpenCV, Boost, GraphicsMagick, samplerate, sndfile. Those dependencies are handled through Conan package manager. I'm building both on Linux (Ubuntu 18.04, GCC 8.1) and Windows (via WSL - also Ubuntu 18.04, MinGW-w64 8.1). I'm using fairly recent versions of 3rd-party libraries with custom built options (strictly speaking - different versions than available on Ubuntu's APT, e.g. Qt v5.11.3, or custom built of GraphicsMagick)
I'm using CPack. On Windows I'm building NSIS installer, but on Linux I would like to use DEB generator (may be other if needed). All of my targets (written apps and shared libs) have appropriate CMake's INSTALL configurations, so they are copied correctly into the generated installers (component based installation). The real problem comes with packaging of 3rd-party dependencies.
Problem
Strictly speaking, I have no idea, how to do it well using CMake+CPack+Conan, both on Linux and Windows. I've read a lot of articles and posts, but I'm stucked. I would like to have something, that automatically bundles into the installer all 3rd party libraries used by project with needed plugins and, what is the most important, with needed system/compiler libraries (libgomp, libstdc++ and so on).
Possible solution
To my surprise, on Windows, this task is fairly easy, because every DLL used by app (my libs, 3rd-party libs and system/compiler libs) needs to be located where executable is. I'm engaging Conan into this, by importing all used DLLs into bin directory. In the end, in most naive way of packaging, I will just copy the bin directory into the installer and it should work. But I'm not sure, if this approach is OK.
On Linux, things are more complicated. First, there is arleady a package manager. Unfortunately, libraries/compilers available there are too old for me (e.g. on APT there is only Qt 5.9.6 ) and are built using different compile options. So, the only way for me is to ship them with my software (like in Windows). There are also issues with searching for dynamic libraries by ld, RPATH handling and so on. At the moment, the only solution I see is to write something like 'launcher' for my app, which sets LD_LIBRARY_PATH before program starts. After that, in this case we can just copy bin or lib directory to the DEB installer and this should work. But still, I don't know if this is correct approach.
Other solutions
I've also looked into other solutions. One of them was BundleUtilities from CMake. It doesn't work for me. It has a lot of problems in recognizing, whether some library is system or local one. Especially in WSL, where it stucked in processing dependencies to USER32.dll, KERNEL32.dll. BundleUtilities in Windows worked for me only with MSYS, but in MSYS I've failed to compile some 3rd-party libraries (GraphicsMagicks via Conan) and that's the reason, why I'm using WSL.
Summary
I'm looking for good and verified method of packaging C++ projects with multiple apps, libs and shipped 3rd-party libs, both for Windows and Linux. How are you doing things like this? Are you just copying bin and/or lib dirs to the installers? How (in terms of CMake/CPack code) are you doing that? INSTALL(DIRECTORY ...), or similar? I'm not sure, but I think that this problem should be already solved in the industry. ;)
Thanks for all suggestions.
First, Conan is a package manager for development, not for distribution, that's why you didn't find an easy way to solve your problem. Second, most of discussions are made at Conan issue, including bugs and questions. There you will find a big community + Conan devs which are very helpful.
with needed system/compiler libraries
This is not part of Conan. Why you don't use static linkage for system libraries?
Talking about CPack, we have an open discussion about it usage with Conan: https://github.com/conan-io/conan/issues/5655
Please, join us.
I see few options for your case:
on package method, run self.copy and all dependencies from self.cpp_deps, which includes all libraries, so you can run Cpack
Use Conan deploy generator to deploy all artifacts, and using a hook you can run cpack or any other installer tool
Out friend SSE4 is writing a new blog post about Deployment + Conan, I think it can help you a lot. You can read a preview here.
Regards!

How to run wxWidgets applications on other machines?

I have downloaded wxWidgets-3.1.0.zip and extracted it to D:\wxWidgets-3.1.0. MY OS: Windows 7 Professional 64 Bit. I am using visual Studio 2015.
I build the library through running: D:\wxWidgets-3.1.0\build\msw\wx_vc14.sln, It was OK. So I can build the projects in samples.
The thing that matters I cannot run this application on another machines where wxWidgets is not installed there. I Don't know Which dlls I must Copy side-by-side my application.
How Can I Also build statically my application so I don not have to copy Dlls?
Can any one add a useful tutorial step by step on how to build on both: Static and dynamic?.
If you open the D:\wxWidgets-3.1.0\samples\minimal\minimal.sln you will be able to see what options you should set. Also, by default, the solution is set to build statically build executable. You can also try to change the "C/C++ -> Code Generation -> RunTime library" in order to statically link the CRT.
If you still need/want the DLL build, at the very least you will need "base" and "core" libraries from D:\wxWidgets-3.1.0\lib\vc_dll folder. And you will also need the CRT libraries. Every time you run the binary, you will get an error on screen that "library such-and-such can't be found". Just copy the library to the same folder where the executable is located.
The other thing - you should've build the library with "Build->Batch Build...->Select All->Build".
HTH.
MSVS 2015 doesn't support linking CRT statically any longer, so you will need to install its CRT DLLs on the target machine in some way. It could be as simple as just copying the DLLs to your application folder (although this is not recommended by Microsoft), but it still needs to be done.
You can build wxWidgets statically simply by choosing the "Release" configuration in the solution file (and not the "DLL Release" one).

Nuget packages that are really exe commands?

I'm researching some of the Nuget stuff. I'm wondering if Nuget is appropriate for distributing .exe commands -- or for that matter if Nuget is only intended only to be used for references to a project (of course you could probably also link to an exe instead of a dll -- IIRC). Obviously, I can easily create a console app and then reference Nuget packages, but I'm wondering if this should always be necessary. Also, it seems that unlike gems, there isn't a local repo of gems, so I feel like .exe(s) are not the intended use for Nuget packages, but I don't see why they need to be limited in this fashion -- or am I missing something?
You can include executable programs in you NuGet packages. From Creating and Publishing a Package:
tools - The tools folder of a package is for powershell scripts and programs
accessible from the Package Manager Console. After the folder is copied to the target
project, it is added to the `$env:Path (PATH) environment variable.
There are a few things you should be aware of, though, if you choose to do this:
You are correct that, unlike RubyGems, NuGet doesn't have the concept of system- or machine-level packages; packages are either targeted to a single project, or (more rarely) to a solution. So this executable will be placed in the package's folder for each solution in which it is used.
The NuGet Visual Studio extension adds the path of the package's tools folder to the PATH environment variable of its console, so you can conveniently execute the programs therein. Outside of Visual Studio, when using other NuGet clients (such as nuget.exe), there won't be any automatic PATH handling, so you'd have to handle getting a path to the program.
This NuGet feature is designed for scripts and executable programs that are somehow related to developing a project (e.g., code generators, tools that manipulate projects files, tools that compliment frameworks like emulators or development servers, etc.). While you can certainly use this feature in ways for which it wasn't designed, if you're looking to deliver system programs that aren't really related to project development, you might want to look at Chocolatey, "a Machine Package Manager, somewhat like apt-get, but built with windows in mind."

Resources