I wanted to ask Is there any way by which you can simply use 'std::cout << "Hello world";' directly from command line.
As in like if you have python installed,
$python
print 'Hello world'
Hello world
Can something like this be done for C++ by any means?
There is cling which is an interactive C++ shell. I haven't used it but it may fit your needs.
Here is a bit of a more expanded response: it took me a while get cling built, primarily because I wasn't following instructions exactly and set up the source tree to include things it should have included. Here are the steps I used to build and install cling (building a release version didn't work for me):
svn co -r 191429 http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co -r 191429 http://llvm.org/svn/llvm-project/cfe/trunk clang
git clone http://root.cern.ch/git/cling.git
cd ..
cat tools/cling/patches/*.diff | patch -p0
./configure --enable-targets=host --prefix=/opt/cling
mk -j8
sudo - make install
After this, I got a C++ shell. Of course, my first interaction wasn't entirely successful because the cling page says that it includes some headers. I had assumed that it would surely include <iostream> but that wasn't the case. Here is a simple interaction that works, though:
$ /opt/cling/bin/cling
****************** CLING ******************
* Type C++ code and press enter to run it *
* Type .q to exit *
*******************************************
[cling]$ #include <iostream>
[cling]$ std::cout << "hello, world\n";
hello, world
[cling]$ #include <iterator>
[cling]$ std::copy(s.begin(), s.end(), std::ostream_iterator<char>(std::cout));
hello, world
[cling]$ .q
Python is an interpreted language:
http://en.wikipedia.org/wiki/Interpreted_language
C++ is a compiled language:
http://en.wikipedia.org/wiki/Compiled_language
So no.
Sorry
I don't think so, C++ needs to be compiled first, Python is an interpreted language.
So you can't have a script that calls
cout<<"Hello world";
without first compiling the code.
If you're using GCC and Cygwin or Linux, you could do something like the following:
echo -e '#include <iostream>\n int main(void) {std::cout << "Hello world";}'|g++ -xc++ - && ./a.out && rm a.out
Related
I've followed every single guide I could possibly find but to be completely honest I have no idea what some installation 'steps' even mean.
I tried installing Cygwin (and MYSY) and running the commands that the guides told me to, but the terminal either doesn't do anything or it gives me the error: 'no such file or directory'. (I changed the folder directory to where my files where)
Also I'm not entirely sure I installed everything correctly because I should've checked some add-ons during the installation right? I did as in the guide but still I maybe missed something...
Could someone please explain to me step by step how to install it saying explicitly all that has to be done, (I'm running windows 7) considering It's the first time I do such thing and I have no idea what ./configure , make and all the other commands even mean...
The following is a simple step by step using only cygwin tools.
To compile C++ we need the g++ compiler; to locate the correct package to be installed the cygwin tool is cygcheck (that is installed by default), with the -p switch it interrogates the database at https://cygwin.com/packages/:
$ cygcheck -p bin/g++
Found 3 matches for bin/g++
gcc-g++-7.3.0-1 - gcc-g++: GNU Compiler Collection (C++)
gcc-g++-7.3.0-2 - gcc-g++: GNU Compiler Collection (C++)
gcc-g++-7.3.0-3 - gcc-g++: GNU Compiler Collection (C++)
so we need the gcc-g++ package.
To install it, we run the cygwin setup, select the Full view, search the gcc-g to filter the thousands of packages and click on skip at the gcc-g++ row
after complety the installation, to verify we have it correctly installed:
$ cygcheck -c gcc-g++
Cygwin Package Information
Package Version Status
gcc-g++ 7.3.0-3 OK
Installing gcc-g++ will pull also the installation of the C compiler package gcc-core.
To compile a gmp program we need the proper header and shared library; that are usually included in a "*-devel" package:
$ cygcheck -p include/gmpxx.h
Found 9 matches for include/gmpxx.h
libgmp-devel-6.1.0-3p1 - libgmp-devel: Library for arbitrary precision arithmetic (development) (installed binaries and support files)
libgmp-devel-6.1.1-1 - libgmp-devel: Library for arbitrary precision arithmetic (development) (installed binaries and support files)
libgmp-devel-6.1.2-1 - libgmp-devel: Library for arbitrary precision arithmetic (development)
mingw64-i686-gmp-6.0.0a-2 - mingw64-i686-gmp: Multiple Precision arithmetic library for Win32 toolchain (installed binaries and support files)
...
All the packages with mingw64 are for cross compiling and we can ignore, so it is libgmp-devel. Verifying that is properly installed
$ cygcheck -c libgmp-devel
Cygwin Package Information
Package Version Status
libgmp-devel 6.1.2-1 OK
And the package content is the header files and the import libraries
$ cygcheck -l libgmp-devel
/usr/include/gmp.h
/usr/include/gmpxx.h
/usr/lib/libgmp.dll.a
/usr/lib/libgmpxx.dll.a
Now we can program one example, I am taking it from
https://gmplib.org/manual/C_002b_002b-Interface-General.html
and written in a file called mpz_add.cpp
You can use whatever editor you want. The important is that the file follows
the Unix line termination standard LF and not the Windows CR+LF (see note below if not)
$ file mpz_add.cpp
mpz_add.cpp: C++ source, ASCII text
$ cat mpz_add.cpp
#include <gmpxx.h>
#include <iostream>
using namespace std;
int main (void)
{
mpz_class a, b, c;
a = 1234;
b = "-5678";
c = a+b;
cout << "sum is " << c << "\n";
cout << "absolute value is " << abs(c) << "\n";
return 0;
}
To compile our example and test it:
$ g++ mpz_add.cpp -lgmpxx -lgmp -o mpz_add
$ ./mpz_add
sum is -4444
absolute value is 4444
We can also verify which library are linked in the program mpz_add, I added some extra comment:
$ cygcheck ./mpz_add
D:\cyg_pub\tmp\gmp\mpz_add.exe
D:\cygwin64\bin\cygwin1.dll <= cygwin library
C:\WINDOWS\system32\KERNEL32.dll <= windows system library
C:\WINDOWS\system32\ntdll.dll ...
C:\WINDOWS\system32\KERNELBASE.dll ...
D:\cygwin64\bin\cyggmp-10.dll <= GMP C library
D:\cygwin64\bin\cyggmpxx-4.dll <= GMP C++ library
D:\cygwin64\bin\cyggcc_s-seh-1.dll <= C library
D:\cygwin64\bin\cygstdc++-6.dll <= C++ library
If the file has the wrong line termination, the best tool is d2u (Dos to Unix)
$ cygcheck -p bin/d2u
Found 6 matches for bin/d2u
...
dos2unix-7.4.0-1 - dos2unix: Line Break Conversion
$ file mpz_add.cpp
mpz_add.cpp: C++ source, ASCII text, with CRLF line terminators
$ d2u mpz_add.cpp
dos2unix: converting file mpz_add.cpp to Unix format...
$ file mpz_add.cpp
mpz_add.cpp: C++ source, ASCII text
As you added also the tag makefile and autotools, the first is in the package make:
$ cygcheck -p bin/make.exe
Found 6 matches for bin/make.exe
..
make-4.2.1-2 - make: The GNU version of the 'make' utility
The second is more complex and you need the packages autoconf automake and libtool,
I would like to know how you can get a Git commit hash and/or other information into the contents of a C++ variable in the compiled binary without having it be part of the source that's tracked by Git.
I need to keep track of firmware release information in a compiled executable running on an embedded processor. Means to identify the particular release of the firmware binary such as meaningful filenames, MD5 checksums or even date/time stamps are not available in this closed environment (i.e., there is no filesystem).
One approach is to have the device's console output produce identifying text, such as 'Release 1.2.3', 'commit hash 1bc123...', or similar. The firmware release information is only of interest to maintenance personnel, so a trained operator could examine the console output. To implement this it could potentially involve manual editing of a version string, which is then compiled into the code and output to the console at program startup.
This is acceptable for major releases where a signoff workflow is used to double-check that the version information is correct. However, this being a manual process it is inherently unreliable. For example, what if the developer forgets to update the version information? - There is now a disconnect between the compiled code and its reported version string.
A workflow where the code is freshly compiled and downloaded each time the user wants to test the hardware is not practical in the situation in question, ie., it is quite onerous to update the firmware.
An automatic way of identifying the version of the code is thus required. In the situation in question, Git is used, and the developers regularly commit their work to feature branches. Displaying the Git commit hash, and perhaps also whether or not there are unstaged changes, would be a way of identifying the status of the source code used to compile the firmware.
The requirement is that I would like my application to have information available to it so that it is able to display:
"Git commit:[01abcdef...etc], branch: experimentalStuffDoNotRelease"
Thus, I would like to automatically include Git information, such as commit hash and branch, in the compiled C and/or C++ code.
The development environment has developers using both Windows and Linux, and uses Eclipse CDT with a relatively unsophisticated workflow of: check out; compile; download to the hardware.
I use a makefile, like so:
GIT_HASH=`git rev-parse HEAD`
COMPILE_TIME=`date -u +'%Y-%m-%d %H:%M:%S UTC'`
GIT_BRANCH=`git branch | grep "^\*" | sed 's/^..//'`
export VERSION_FLAGS=-DGIT_HASH="\"$(GIT_HASH)\"" -DCOMPILE_TIME="\"$(COMPILE_TIME)\"" -DGIT_BRANCH="\"$(GIT_BRANCH)\""
all:
g++ main.cpp $(VERSION_FLAGS)
When the makefile is run, the git hash and the time of compilation are both loaded into macros accessible within the source, like so:
#include <iostream>
int main(){
std::cerr<<"hash="<<GIT_HASH<<", time="<<COMPILE_TIME<<", branch="<<GIT_BRANCH<<std::endl;
}
Which gives output like:
hash=35f531bf1c959626e1b95f2d3e1a7d1e4c58e5ec, time=2017-05-18 04:17:25 UTC, branch=master
In Eclipse CDT, use a pre-build step to generate an include file containing the relevant information, and a conditional inclusion to check that the file was created:
Right-click the project
Select Properties
Expand the C/C++ Build
Select Settings In the Build Steps tab
Enter the following in the Command text box:
git log --pretty=format:'#define GIT_INFO_PRESENT%n static const char* GIT_INFO = "Version Information=[%H,%d]\r\n";' -n 1 > ../src/gitcommit.h
This will, upon build, create a file gitcommit.h that will be included in the source code. To customise it, adjust the string to your needs. (See https://git-scm.com/docs/pretty-formats)
As an example, I produce a debug output at the beginning of the main routine to inform the user of the commit and branch (not strictly needed knowing the commit, but certainly helpful):
Put this in the file, probably at the top
#if __has_include("gitcommit.h")
#include "gitcommit.h"
#else
static const char* GIT_INFO = "Git version information not present.\r\n";
#endif
To display the information somewhere in your code, do similar to this:
printf(GIT_INFO);
Note that I haven't, in this case, made the pre-build step a shell script or Windows/DOS .bat file, as I work often in Linux or Windows.
Note that this isn't tested in Windows.
In both cases, 'git' must be executable from the standard command line.
There is a dependency on provision of __has_include. This was intended to provide simplicity so that a default include file need not be provided.
Note that the gitcommit.h file's path should be discoverable by the compiler.
Usually as part of your build you run some command that generates something like that.
For example, git describe gives you something that you could use:
echo // auto generated version: > version.h
git describe > echo // auto generated version: > version.h
echo -e "#define VERSION " >> version.h
git describe >> version.h
For example x264 use this simple script to generate it:
if [ -d .git ] && command -v git >/dev/null 2>&1 ; then
localver="$(($(git rev-list HEAD | wc -l)))"
if [ "$localver" -gt 1 ] ; then
ver_diff="$(($(git rev-list origin/master..HEAD | wc -l)))"
ver="$((localver-ver_diff))"
echo "#define X264_REV $ver"
echo "#define X264_REV_DIFF $ver_diff"
if [ "$ver_diff" -ne 0 ] ; then
ver="$ver+$ver_diff"
fi
if git status | grep -q "modified:" ; then
ver="${ver}M"
fi
ver="$ver $(git rev-list -n 1 HEAD | cut -c 1-7)"
version=" r$ver"
fi
fi
echo "#define X264_VERSION \"$version\""
echo "#define X264_POINTVER \"0.$ver\""
This will generate something like:
#define X264_VERSION " r2708 86b7198"
#define X264_POINTVER "0.148.2708 86b7198"
Here's simple solution if you need git hash and local modifications flag only:
$ cat update-version-info.sh
#!/bin/sh
version=$(git describe --always --dirty --tags)
echo "#define GIT_VERSION \"$version\"" > git-version.h
$ cat 1.c
#include <stdlib.h>
#include <stdio.h>
#include "git-version.h"
int main() {
#ifdef GIT_VERSION
printf("%s\n", GIT_VERSION);
#endif
return 0;
}
$ ./1
ee4f307-dirty
Based on #Richard's answer and my fixes for qmake/Qt, here is the solution I use:
With Qt 5.14 the following lines in .pro file work for me:
GIT_HASH="\\\"$$system(git -C \""$$_PRO_FILE_PWD_"\" rev-parse --short HEAD)\\\""
GIT_BRANCH="\\\"$$system(git -C \""$$_PRO_FILE_PWD_"\" rev-parse --abbrev-ref HEAD)\\\""
BUILD_TIMESTAMP="\\\"$$system(date -u +\""%Y-%m-%dT%H:%M:%SUTC\"")\\\""
DEFINES += GIT_HASH=$$GIT_HASH GIT_BRANCH=$$GIT_BRANCH BUILD_TIMESTAMP=$$BUILD_TIMESTAMP
In your code you can check the revision like this:
int main(int argc, char *argv[])
{
QStringList args;
for (int i = 0; i < argc; i++)
args << QString(argv[i]);
if (args.contains("-v") || args.contains("--version")) {
std::cout << QString("branch: %1, version: %2, built_at: %3").arg(GIT_BRANCH).arg(GIT_HASH).arg(BUILD_TIMESTAMP).toUtf8().constData() << std::endl;
return 0;
}
// ...
}
A C file or a C++ file can be generated by some program (for example, some shell script on Linux, or some GNU awk script, or your C program running system or popen(3) running some git command).
You just configure your build automation tool (e.g. your Makefile if you use GNU make, or your build.ninja file if you use ninja) appropriately.
Both Bismon and RefPerSys are doing so and keep their git id inside the obtained executable (displaying it when invoked with --version). Note: both are projects I created.
PS a different question is how to configure your IDE to run a particular build automation tool. This is specific to your IDE. But Eclipse CDT FAQ offers an insight.
I have a very simple example named HelloWorld and located in folder "C:/HelloWorld" in Dev-Cpp as follows:
#include <iostream>
using namespace std;
int main(){
cout << "Hello World";
return 0;
}
Of course, if I press F11 (Compile and run) then the program executes normally.
But I want to execute this program in an another way: use make command!!!
I have known that the syntax to run make command : make -f [make file name]. In Dev-Cpp, this command is make -f "Makefile.win". So I jump into HelloWorld folder and type as follows:
The console displays many errors relating to included headers.
How can I run make command without any errors? Thanks in advance.
not so easy with make :)
at first if you use msvc or DevCpp try to find "Export makefile"
at second you need to configure your compilator(s).
at third you need to show what Makefile.win contains.
man:
http://www.gnu.org/software/make/manual/make.html
gcc:
https://gcc.gnu.org/install/binaries.html
All right. There are something wrong with my make command.
The problem is I had installed two versions of gcc in my computer. The HelloWorld example is compiled and built with the latest GCC version.
However, the make command I had type is belonged to the older GCC version. As a result, it leads to many errors.
In order to run make command correctly, I must to use the right make command that is defined in Dev-Cpp (below picture): mingw32-make.exe
I am trying to detect Solaris/SunOS version at compile time so that I can enable/disable use of port_create() and other APIs.
Is there a header identifying SunOS/Solaris version at compile time?
If no header is giving you this information, you could of course parse the output of uname and generate -D preprocessor option(s) from your build script/makefile/...
Elaborating upon the suggestion by #meaning-matters, one can make a compile-time definition, say SUN_VERSION using the output of uname -r. That actually gives a floating point number, e.g., 5.10, which you could convert into a preprocessor-comparable form using a simple sed command, e.g., this compiler option:
-DSUN_VERSION=`uname -r | sed -e 's/\.\([0-9]\{1,1\}\)$/0\1/' -e 's/\.//'`
produces 510 for 5.10, 509 for 5.9, etc.
In your source program, you could use it like this
#if SUN_VERSION >= 510
(or whatever makes sense).
Identifying the OS release in order to assert an API is available or not is risky if not doomed. You cannot assume an API will stay in future releases nor if it is available in a parallel branch (eg. Illumos vs Solaris 11 which are both reporting SunOS 5.11 as their version).
The usual way to overcome this issue is simply to check if the API is available by compiling a small test source code to figure it out. This is usually done in a script traditionally named configure that builds a Makefile and an include file tailored to your system.
To expand upon #meaning-matters answer, use GNU make, and set a variable to the OS version. Pass that variable on to the compiler using the -D command-line option.
Makefile:
OS_VERSION := $(shell uname -r)
version:
$(CC) -DOS_VERSION=$(OS_VERSION) version.c -o version
test:
echo $(OS_VERSION)
version.c:
#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
int main()
{
printf( "OS Version: " TOSTRING(OS_VERSION) "\n" );
return( 0 );
}
Output:
bash 4.1$ gmake test
echo 5.11
5.11
bash 4.1$ gmake version
cc -DOS_VERSION=5.11 version.c -o version
bash 4.1$ ./version
OS Version: 5.11
bash 4.1$
Use := (assign if not already set) to only run the uname command once.
That will show "5.10" for Solaris 10, "5.11" for Solaris 11.
I was trying to create folders named 1 2 3 4, using the C++ program below. I can successfully achieve that in RHEL.
However it created a folder named {1..4} in ubuntu 13.10.
Why does this happen? Thank you for helping me!
#include <cstdlib>
int main()
{
std::system("mkdir {1..4}");
}
It's a part of CPP unit test in our product. Yes, it's ugly. But I am afraid very few thing can be done in this situation.
You are right.
In RHEL,
sh -c 'echo {1..4}'
1 2 3 4
In Ubuntu
sh -c 'echo {1..4}'
{1..4}
So I use the program below instead. It works!
#include
int main()
{
std::system("bash -c 'mkdir {1..4}'");
}
seems system use sh by default....Thank you for your answer!
A bit of terminology: Linux has directories in its file systems, not "folders" (folders may appear visually on the desktop, but that is a desktop detail).
You don't need to use system(3) (which is running sh not bash!).
And POSIX sh don't know the {1..4} notation, hence the {1..4} string is passed verbatim to /bin/mkdir command (see mkdir(1) ...).
Run
sh -c 'echo {1..4}'
to test that sh don't understand the {1..4} notation.
(so it is a bug in your old RHEL, where perhaps /bin/sh is a symlink to /bin/bash while on Debian and Ubuntu it is a symlink to the more Posix compliant and faster /bin/dash)
Just use the mkdir(2) syscall and code
#include <cstdlib>
#include <cstdio>
#include <sys/stat.h>
#include <sys/types.h>
int main() {
for (int i=1; i<=4; i++) {
char buf[8];
snprintf(buf, sizeof(buf), "%d", i);
if (mkdir(buf, 0755))
{ perror("mkdir"); exit(EXIT_FAILURE); };
}
}
I hope you don't want to create a single directory named 1 2 3 4. It is possible and easy, but it really is poor taste. For your mental safety, use only letters, digits and underscores _ in directory names.
I am using snprintf(3) to convert an int to a character buffer. With C++11 you could use std::to_string and c_str ...
Read Advanced Linux Programming...
Using the mkdir(2) syscall instead of going thru a command invoked by system(3) has several important advantages:
it is much faster, you don't need to fork(2) a /bin/sh -c shell like system(3) should do.
it uses much less resources, since no additional process is fork-ed, so your program will still run when you have reached your limits (see setrlimit(2) ...)
it is more reliable. Should mkdir(2) fail you could (and should) handle the failure nicely. See errno(3) and strerror(3) ....