I'd like to use open source library on Windows. (ex:Aquila, following http://aquila-dsp.org/articles/iteration-over-wave-file-data-revisited/) But I can't understand anything about "Build System"... Everyone just say like, "Unzip the tar, do configure, make, make file" at Linux, but I want to use them for Windows. There are some several questions.
i) Why do I have to "Install" for just source code? Why can't I use these header files by copying them to the working directory and throw #include ".\aquila\global.h" ??
ii) What are Configuration and Make/Make Install? I can't understand them. I just know that configuration open source with Windows need "CMake", and it is configuration tool... But what it actually does??
iii) Though I've done : cmake, mingw32-make, mingw32-make install... My compiler said "undefined references to ...". What this means and what should I do with them?
You don't need to install for sources. You do need to install for the libraries that get built from that source code and that your code is going to use.
configure is the standard name for the script that does build configuration for the software about to be built. The usual way it is run (and how you will see it mentioned) is ./configure.
make is a build management tool (as the tag here on SO will tell you). One of the most common mechanisms for building code on linux (etc.) is to use the autotools suite which uses the aforementioned configure script to generate build configuration information for use by generated makefiles which make then uses to build the software. make is also the way to run the default build target defined in a makefile (which is often the all target and which usually builds the appropriate library/binary/etc.).
make install is a specific, secondary, invocation of the make tool on the install target which (generally) installs the (in this case previously) built code into an appropriate location (in the autotools/configure universe the default location is generally under /usr/local).
cmake is, again as the SO tag says, a build system that generates configuration files for other build tools (make, VS, etc.). This allows the developers to create the build configuration once and build on multiple platforms/etc. (at least in theory).
If running cmake worked correctly then it should have generated the correct information for whatever target system you told it to use (make or VS or whatever). Assuming that was make that should have allowed mingw32-make to build the software correctly (assuming additionally that mingw32-make is not a distinct cmake target than make). If that is not working correctly then something is still missing from your system (and cmake probably should have caught that).
But to give any more detail you will need to give more detail about what errors you are actually getting and from what command.
(Oh, and on Windows, and especially if you plan on building your software with VS (or some other non-mingw32-make tool) the chances of you needing to run mingw32-make install are incredibly small).
For Windows use cmake or latest ninja.
The process is not simple or straight, but achievable. You need to write CMake configuration.
Building process is not simple and straight, that's why there exists language like Java(that's another thing though)
Rely on CMake build the library, and you will get the Open-Source library for Windows.
You can distribute this as library for Windows systems, distribute and integrate with your own software, include the Open Source library, in either cases, you would have to build it for Windows.
Writing CMake helps, it would be helpful to build for other platforms as well.
Now Question comes: Is there any other way except CMake for Windows Build
Would you love the flavor of writing directly Assembly?
If obviously answer is no, you would have to write CMake and generate sln for MSVC and other compilers.
Just fix some of the errors comes, read the FAQ, Documentation before building an Open Source library. And fix the errors as they lurk through.
It is like handling burning iron, but it pays if you're working on something meaningful. Most of the server libraries are Open Source(e.g. age old Apache httpd). So, think before what you're doing.
There are also not many useful Open Source libraries which you could use in your project, but it's the way to Use the Open Source libraries.
Related
SO!
Let's say I have a number of settings (GCC compiler 9.3.0 built from source, as the distribution I have to use has a very old one, along with environment setup) for a new Kit in QtCreator.
I have managed to setup an environment for compilation and execution of compiled binaries, and made a script to make it work (like qmake -nocache -recursive/make/sudo make install, direct execution of g++, and other stuff).
One thing that script can't do at the moment, is that it cannot create a kit for QtCreator with new compilers and environment being set as required, so after running a script, its user has to go through setting it up himself through GUI, which is bad, because this can cause misconfiguration.
This thing I'm trying to create is going to be used by around ~200 people in my company, so leaving readme.txt with instructions just doesn't go well enough for me - I don't want running around fixing missing "{" and "}" in Environment description in created Kits, and other stuff.
Are there ways to create Kits for QtCreator automatically from command line? Maybe, there's some files to edit?
I've looked into this one a few years back (I wanted to do something similar for registering Buildroot toolchains automatically in QtCreator), and I was unable to find an off the shelf solution. So i think there are 2 ways to implement this:
a) Implementing a command line utility the manipulate the ~/.config/QtProject/qtcreator/{toolchains,profiles}.xml files. Maybe by (re)using the existing C++ implementation within QtCreator, or just re-implement it ie. in Python. Back than I didn't start to work on this as there was no real business need.
b) Switching to qbs, as qbs has support for setting up toolchains from the command line ( see: https://doc.qt.io/qbs/cli-setup-toolchains.html)
If you decide to go with solution a), please let me know and maybe we can partner up to implement it.
Check out the command line sdktool bundled with QtCreator:
The SDK tool can be used to set up Qt versions, tool chains, devices
and kits in Qt Creator.
There still is a lot of knowledge about Qt Creator internals required
to use this tool!
I haven't tried it yet, but I did find the executable under Tools/QtCreator/libexec/qtcreator subdirectory of the Qt Creator installation directory. ./sdktool --help works for me under Linux.
I don't understand, why do we need cmake to build libraries ? I am sorry if my question is stupid, but i need to use some libraries on Widnows, and what ever library i choose i need to build it and/or compile it with cmake.. What is it for ? Why cant i just #include "path" the things that i need into my project, and than it can be compiled/built at the same time as my project ?
And also, sometimes i needed to install Ruby, Perl, Python all of them some specific version so cmake can build libraries... Why do i need those programs, and will i need them only to build library or later in my project too ? (concrete can i uninstall those programs after building libraries ?)
Building things in c++ on different platforms is a mess currently.
There are several different build system out there and there is no standard way to do this. Just providing a visual studio solution wont help compilation on linux or mac.
If you add a makefile for linux or mac you need to repeat configurations between the solution and the makefiles. Which can result in a lot of maintenance overhead. Also makefiles are not really a good build tool compared to the new ones out there.
That you have only CMake libraries is mostly a coincidence. CMake is though a popular choice currently.
There are several solutions out there to unify builds. CMake is a build tool in a special way. It can create makefiles and build them but you can also tell cmake to create a visual studio solution if you like.
The same goes with external programs. They are the choice of the maintainer of the library you use and there are no standards for things like code generation.
While CMake may not be "the" solution (although the upcoming visual studio 2015 is integrating cmake support) but the trend for those build system which are cross-platform is going more and more in this direction.
To your question why you cannot only include the header:
Few libraries are header only and need to be compiled. Either you can get precompiled libs/dlls and just include the header + add the linker path. This is easier in linux because you can have -dev packages which just install a prebuild library and it's header via the package manager. Windows has no such thing natively.
Or you have to build it yourself with whatever buildtool the library uses.
The short answer is that you don't, but it would probably be difficult to build the project without it.
CMake does not build code, but is instead a build file generator. It was developed by KitWare (during the ITK project around 2000) to make building code across multiple platforms "simpler". It's not an easy language to use (which Kitware openly admits), but it unifies several things that Windows, Mac, and Linux do differently when building code.
On Linux, autoconf is typically used to make build files, which are then compiled by gcc/g++ (and/or clang)
On Windows, you would typically use the Visual Studio IDE and create what they call a "Solution" that is then compiled by msvc (the Microsoft Visual C++ compiler)
On Mac, I admit I am not familiar with the compiler used, but I believe it is something to do with XCode
CMake lets you write a single script you can use to build on multiple machines and specify different options for each.
Like C++, CMake has been divided between traditional/old-style CMake (version < 3.x) and modern CMake (version >= 3.0). Use modern CMake. The following are excellent tutorials:
Effective CMake, by Daniel Pfeifer, C++Now 2017*
Modern CMake Patterns, by Matheiu Ropert, CppCon 2017
Better CMake
CMake Tutorial
*Awarded the most useful talk at the C++Now 2017 Conference
Watch these in the order listed. You will learn what Modern CMake looks like (and old-style CMake) and gain understanding of how
CMake helps you specify build order and dependencies, and
Modern CMake helps prevent creating cyclic dependencies and common bugs while scaling to larger projects.
Additionally, the last video introduces package managers for C++ (useful when using external libraries, like Boost, where you would use the CMake find_package() command), of which the two most common are:
vcpkg, and
Conan
In general,
Think of targets as objects
a. There are two kinds, executables and libraries, which are "constructed" with
add_executable(myexe ...) # Creates an executable target "myexe"
add_library(mylib ...) # Creates a library target "mylib"
Each target has properties, which are variables for the target. However, they are specified with underscores, not dots, and (often) use capital letters
myexe_FOO_PROPERTY # Foo property for myexe target
Functions in CMake can also set some properties on target "objects" (under the hood) when run
target_compile_definitions()/features()/options()
target_sources()
target_include_directories()
target_link_libraries()
CMake is a command language, similar shell scripting, but there's no nesting or piping of commands. Instead
a. Each command (function) is on its own line and does one thing
b. The argument(s) to all commands (functions) are strings
c. Unless the name of a target is explicitly passed to the function, the command applies to the target that was last created
add_executable(myexe ...) # Create exe target
target_compile_definitions(...) # Applies to "myexe"
target_include_directories(...) # Applies to "myexe"
# ...etc.
add_library(mylib ...) # Create lib target
target_sources(...) # Applies to "mylib"
# ...etc.
d. Commands are executed in order, top-to-bottom, (NOTE: if a target needs another target, you must create the target first)
The scope of execution is the currently active CMakeLists.txt file. Additional files can be run (added to the scope) using the add_subdirectory() command
a. This operates much like the shell exec command; the current CMake environment (targets and properties, except PRIVATE properties) are "copied" over into a new scope ("shell"), where additional work is done.
b. However, the "environment" is not the shell environment (CMake target properties are not passed to the shell as environment variables like $PATH). Instead, the CMake language maintains all targets and properties in the top-level global scope CACHE
PRIVATE properties get used by the current module. INTERFACE properties get passed to subdirectory modules. PUBLIC is for the current module and submodules (the property is appropriate for the current module and applies to/should be used by modules that link against it).
target_link_libraries is for direct module dependencies, but it also resolves all transitive dependencies. This means when you link to a library, you gets all the PUBLIC properties of the parent modules as well.
a. If you want to link to a library that has a direct path, you can use target_link_libraries, and
b. if you want to link to a module with a project and take its interface, you also use target_link_libraries
You run CMake on CMakeLists.txt files to generate the build files you want for your system (ninja, Visual Studio solution, Linux make, etc.) and the run those to compile and link the code.
Large variety of open-source projects are distributed in source-code and supposed to be compiled with ./configure && make approach. But if I want to cross-compile, at which of those two steps I am supposed to tell them what target platform I want to get the binary?
Does it have to do with configure/make in general, or this is specific to every project? What could be an example of compiling some project, library or console application and specifying target?
I know many projects have a web-page on their websites that is dedicated to "cross compiling this program". So it seems to be project-specific setting. But the project still uses configure/make, so what is the relation of all that?
If your system is using standard GNU autoconf, then you would always define the cross-compilation at configure time, not at make time. If the configure script does not know you're cross-compiling it may obtain incorrect answers when it probes the system looking for what is supported and what is not supported.
Cross-compilation is what the --build, --host, and --target flags to configure are for. You should never need to set --build: it always refers to the system you're running configure on, and configure can figure that out for itself. For a normal cross-compilation you also do not set --host, and you would set --target to the cross-compilation target. You may also need to set the CC (for C programs) and/or CXX (for C++ programs), LD, AR, STRIP, and a few others, if needed. Personally I prefer to build in a separate directory as well, although some packages don't support it unfortunately):
tar xzf foo-1.1.tar.gz
mkdir obj
cd obj
../foo-1.1/configure --target=... CC=...-gcc CXX=...-g++ ...
make
Note this is all provided by basic autoconf / automake, so all projects will do it the same way (although in my experience many projects which do not attempt cross-compilation somewhat regularly, do something wrong such that it doesn't work so well).
I understand it is somehow making a connection so that a compiler when envokes connects a source code to whatever libraries that it needs to.
But what is going on a more technical level, or better put what do I need to know in order to confidentally compile code.
I'm working with C++ and MinGW, and have started to look into build files and stuff for Sublime Text 2 (Have learned mostly under unix, or Java + eclipse so far). But what I don't understand what is adding a compiler to your path do for you?
Do I need to add it for every folder I want to compile from? Or is it system wide? I'm really learning this stuff for the first time, we we're never showed how to set up development environments or even deploy code on other systems.
You probably mean include paths and library paths in the compiler:
include paths: where the compiler will look for headers; and
library paths: where the linker, invoked by the compiler, will look for binary libraries to finish building your project.
If that is the case, look here for a gentle explanation.
Basically, what is happening is that the compiler looks in certain places for symbols defined by the operating system and other libraries installed system-wide.
In addition to those paths, you need to tell the compiler where to find the symbols defined in your own project.
You may also mean something related to installing the compiler itself or configuring the editor to use it.
In that case, what is happening is that you need to tell the build system where to find the executable for the compiler.
Basically, what is probably happening is that your editor wants to know where the compiler is so that it can provide real time feedback on your code. Adding the compiler to the system path will usually, but not always, solve your problem.
In more detail:
A C++ build is a rather complex tool chain, involving determining dependencies, preprocessing, compiling, and linking. There are tools that automate that tool chain, and those tools are in turn wrapped into the functionality of modern IDEs like Eclipse, Visual C++, or Sublime Text 2. You many need to tell your editor where to find the tools it uses to provide you with those services.
I've created, debugged, and revised a project that I've been working on, but now I want to be able to specify what version of the binary I'm on. I'm using Eclispe-CDT with MinGW to make this project on my local system, so there is no versioning software involved. Does anyone know how to specify this for both Windows and Linux platforms?
On Windows, the idea is to produce a COFF file with the relevant information.
That is done by adding a step to the build, using windres (found also here).
See this thread as an example.
you could add windres via the project properties/Builders as an additional builder and add the generated object file in the C/C++ Build/GCC C++ Linker/Miscellaneous/Other Objects.
Then you
- a) could do a clean build if the resource is changed or
- b) could change the build options (if you have patience) to change to do a clean build every time you save the project.
On Unix, this doesn't seem to be supported in a similar fashion.