I have a big C++ application which we are compiling through Jenkins and generating zipped artifacts containing binaries, headers, config and other relevant files. The build is deployed in the form of services on the client. The problem is how can apply version on those binaries to keep a tract of which build is deployed on which client?
Like with earlier C# application we used make changes to AssemblyVersion file with the tags that we apply on GIT and then compile and we could see the executable have the version applied. Is there a way to do the same in C++?
We are using CMakeLists.txt file for generating builds. We have linux based environment (CentOS 7.5) the application is developed in C++.
Thanks in advances!
Since you're using CMake, what you can do is use the configure_file() function in your CMakeLists.txt to create a C++ source file which includes your Git version information as a string, then include the created file into your target.
You can get the Git version information into a CMake variable by calling the git executable from CMake, although there are prewritten modules out there to do the heavy lifting.
You can then use the command-line strings and grep tools to find the version string in the binary, or some other method to get it programmatically, depending on if you're making an executable or library.
Related
I'm trying to cross-compile a gRPC using cmake.
I actually managed to do it. Unfortunately my method involves tinkering inside CMakeLists.txt.
Problem was that, when I was trying to compile gRPC it was using protobuffer he just compiled. It cannot run ARM compiled executables on x86 machine.
I managed to compile it by specifying path to protoc and grpc_cpp_plugin manually in gRPCs main CMakeLists.txt. It is dirty and since I would like to include gRPC as submodule I need clean way to do it.
Has anyone managed to cross-compile gRPC using cmake?
This way should work:
Cross-compile Protobuf for target(ARM) and install it.
Make sure that cross-compiled Protobuf can be searched in the toolchain(ARM) you have.
E.g. it is installed into system-default prefix under sysroot.
On host, install Protobuf of the same version. It needn't to be searchable (that is, user-local installation is sufficient).
Cross-compile gRPC with following parameters (set in CMake GUI or as -D option for cmake executable):
gRPC_PROTOBUF_PROVIDER: package
gRPC_PROTOBUF_PACKAGE_TYPE: MODULE
Protobuf_PROTOC_EXECUTABLE: <path to your host protoc executable>
Explanations
Setting parameter gRPC_PROTOBUF_PROVIDER to "package" tells gRPC to not build its own Protobuf, but use already installed variant. This variant is searched by find_package(Protobuf).
Setting parameter gRPC_PROTOBUF_PACKAGE_TYPE to "MODULE" tells gRPC to not use "Config" file, provided by Protobuf installation, for detect Protobuf things (libraries and executable). Config file contains hardcoded paths which cannot be adjusted outside. Instead, FindProtobuf.cmake script is used for find Protobuf.
Setting parameter Protobuf_PROTOC_EXECUTABLE tells FindProtobuf.cmake script to not search Protobuf executable, but takes it from the parameter.
JetBrains has spoiled me. I'm familiar with the standard UNIX make file and the make, make install routine normally associated with installing software with traditional make files, but I'm not as familiar with cmake since CLion does it all for me.
I want to distribute my code to others and provide simple instructions for building it via cmake so that they have a binary they can execute. The official cmake tutorial shows writing install rules in the CMakeLists.txt file but it isn't clear if this is supported by CLion (or even if it needs to be).
For a simple, single-file (main.cpp) application, what would be an example of how to build it using cmake (assuming those it is distributed to don't have CLion nor use another IDE, they just want to build and use it)?
To build code that comes with a CMakeLists.txt file, you run cmake to generate a Makefile (or other build configuration file):
cmake <path_to_CMakeLists.txt>
Then you run
make;make install
as usual. (or as described in the comment, you can type cmake --build . instead of make - useful if you're on a platform with a different build system)
You don't want to check in the Makefile into your source control, though, as it needs to be generated on the computer that will actually be doing the building.
This is about how to integrate the azure-storage C++ toolkit in CMake.
I try to build a tool in our application that connects to Azure blob storage, lists files/containers, reads data, etc., I work on Linux (Ubuntu 17.04). I have built both the cpprestsdk and azure-storage tools from source.
I am able to compile some things because I literally add
-I/apps/azure/inst/include
to the CMAKE_CXX_FLAGS. As you can see I used CMAKE_INSTALL_PREFIX=/apps/azure/inst, used it for both cpprest and azure-storage.
In the lib subdirectory there is a cpprestsdk/ directory that contains .cmake files. But I need a .cmake file for azure-storage that I can include in my own CMakeLists.txt, which adds stuff I need (flags, libs, etc.). Looking at the samples reveals that these are built in a way that will only work during the build of the sdk.
Does anyone know if there is such a .cmake include file, and if so .... where is it installed?
OK well, I could find nothing and nobody posts an answer, so I've been experimenting. The short answer is: use the cpprest stuff and add some azure-storage directives yourself.
The only thing I could find is CMake code in the README.md of cpprest. I took that in and added my own azure storage dir name where that could be needed.
Added:
find_path( AZURE_INST_DIR "" HINTS /apps/azure/inst REQUIRED )
The whole thing works because the big bulk of dependencies is under cpprest, azure-storage itself does not have extra dependencies (thank god!).
Note gcc users: turn off -Wshadow and -Woverloaded-virtual because the cpprest and azure-storage code is riddled with those (apparently these are not available in Visual studio).
I am using Buck for my own C++ project, but I depend on a third-party library that is built using CMake. The CMake file is complex, so I do not think it is practical to recreate their CMake file in Buck. Instead, I would like to call CMake from Buck.
What is the best way to call CMake from Buck?
How should I structure my project to minimise headaches?
My suggestion is using genrule and prebuilt_cxx_library.
This is my Buck study project using Google Test:
https://github.com/ar90n/lab/tree/master/sandbox/buck-study/gtest
This project contains two Buck files. The one (./gtest/BUCK) is for fetching and building Google Test. The another (./BUCK) is for building and running test programs.
If you want to build and run this project, please execute the following commands,
$ buck fetch //gtest:googletest-src
$ buck build :sample1
$ buck run :sample1
Calling CMake will break reproducibility, so it isn't the best approach. Instead, try the following:
Fork the project that builds with CMake.
Call CMake to generate any header files.
Save the header files somewhere in the project (e.g. /cmake-generated).
Create a header-only library of the header files generated by CMake.
Build the rest of the project with Buck, depending on the CMake library.
Commit everything to Git.
Repeat step 2 for every target that you require.
This is not as good as a true port to Buck, but you get most of the benefits for a one-time manual step.
I'm very new to C++ world, so please, sorry for such a dummy question. I googled a little, but wasn't able to find a proper answer.
My question is fairly simple - how should I use libraries in C++ world. For example in Java - there is maven and gradle for this task. In Python - I use pip. In javascript npm and bower do all the stuff. In C# you use nuget or just adding DLL lib to your project. But looks like in C++ things isn't such easy.
I found a tool, called conan but amount of libraries they have is pretty small and does not include any what I'm looking for.
So, for example - I want to use nlp lib meta but it seems like they don't provide any installer files. So I assume I need to get sources from Github. Should I compile them and then try to add the compiled files to my project or do I need to have a lib folder in my project, and put meta's sources in those folder and after operate with meta's sources as they are in my project?
My question isn't about how to install specific meta lib, but more from the source management point of view. If I use Visual Studio on Windows for example, but my colleague will be coding Clion under Linux. And I don't know the proper way of managing dependencies in C++ world.
C++ doesn't have anything like pip or npm/bower. I don't know if maven or gradle can be persuaded to handle C++ libraries.
In general, you are going to have to end up with
Header files in a directory somewhere
library files (either static libraries, or DLLs/shared objects). If the library is a header-only library like some of the boost libraries, then you won't need this.
You get hold of the library files, either by building them on your machine (typical for open source projects, and projects aimed at Linux platforms), or by downloading the pre-compiled binaries (typical for Windows libraries, particularly paid-for).
Hopefully, the instructions for building the library will be included on the library website. As noted in the comments, 'meta' seems to be quite good at that.
When you try to compile with the library, you may need a command line option (eg -I) to specify the directory containing the header files, and you may need a linker option (eg -l) to tell the linker to link against your library.
Cget will install any package that uses standard cmake, and works for linux and windows. It has shorten syntax for getting packages directly from github(such as cget install google/googletest).
In addition, dependencies can be automatically downloaded as well by listing them in a requirements.txt file.
There is also recipes for installing non-cmake packages and the repository here has over 300 libraries(and growing). So you can install curl with just cget install pfultz2/cget-recipes curl.
C++ sadly has no package manager for libraries. Some are out there and try to be one which are still small and scattered though (like conan).
In linux you have some "-dev" packages you can install but they are also not "all".
You most likely end up downloading them yourself. Next though is you have the problem of integrating those libraries. You have different build systems per operating system so you have to see how you build c++ files.
Like in windows with Visual studio you have to get a visual studio project or a nmake compatible makefile to build the libraries and then add them to your project. Same with linux makefiles.
There are several build frameworks who are higher level like cmake. The example you have in your post also works with CMake. So integrating that one into a cmake build environment would be easier but this only applies for other libraries also trying to use/integrate cmake build environments to it (e.g. boost / qt is doing this).
Yeah these are some thoughts to this. Sadly there won't be an easy/definitive answer to this because there is no real central c++ packet repository which is also integrated into a build system.
It appears to me that the Crascit/DownloadProject could be of help in your situation. It provides CMake plugins for downloading projects from a git repository by specifying tags, etc. Then you can use add_custom_target to run commands you need to have the project built.
There are a number of popular C++ released via nuget packages.
You can search on the gallery for them, usually using the native or c++ tags. Obviously you need a nuget manager for your OS, and I'm pretty sure that the C++ nuget packages rely on MSBuild for a lot of the grunt work, so you may have trouble getting a non-Visual Studio oriented setup to work nicely.
Also Gradle actually does have some support for native dependencies as well. I had a look at little while ago but the work on it was curtailed because the support for VS 2015 was lacking.
I recommend vcpkg for cross platform development. It has a number of IDE integrations. GitHub project is here.
I do cross platform development using tools like CMake, Visual Studio, WSL. vcpkg was incredibly helpful.
I started new project... in cureent time it's just "source package manager" you can provide some source code on github and then it will be just copy to you project (based on cmake + auto generating cmake files)
So links here:
https://github.com/wsjcpp/wsjcpp