My project folder has the following structure
-Project/
/src
-Main.cpp
-MyReader.cpp
/headers
-MyReader.h
/DataFiles
-File.dat
-File1.dat
My class Object.cpp has a couple of methods which reads from File.dat and File1.dat and parse the information to Map objects. My problem is that I am using Autotools (in which I'm very very newbie) for generating config and installer files and I don't know how to make all the DataFiles files accessible for the program after installation. The program doesn't work properly because of the code fails when trying to read those files through relative paths. Locally, the program runs perfectly after executing in terminal make && ./program.
How can I solve this issue? Thanks in advance for your help!
A platform independent way to do this with Autotools is using the $(datadir) variable to locate the system data directory and work relative to that.
So in your Makefile.am file you can create a name like this:
myprog_infodir = $(datadir)/myprog
# Set a macro for your code to use
myprog_CXXFLAGS = -DDATA_LOCATION=\"$(datadir)/myprog\"
# This will install it from the development directories
myprog_info_DATA = $(top_srcdir)/DataFiles/File.dat $(top_srcdir)/DataFiles/File1.dat
# make sure it gets in the installation package
extra_DIST = $(top_srcdir)/DataFiles/File.dat $(top_srcdir)/DataFiles/File1.dat
Then in your program you should be able to refer to the data like this:
std::ifstream ifs(DATA_LOCATION "/File.dat");
Disclaimer: Untested code
I figured out one method and will give my example here:
In my Makefile.am
AM_CPPFLAGS = -D MATRIXDIR="\"$(pkgdatadir)/matrix\""
nobase_dist_pkgdata_DATA = matrix/AAcode.txt \
matrix/BLOSUM50 matrix/BLOSUM70.50 matrix/BLOSUM100 matrix/BLOSUM50.50 \
matrix/BLOSUM75 matrix/BLOSUM100.50 matrix/BLOSUM55 matrix/BLOSUM75.50 \
... more not shown
I put quite some number of datafiles in the matrix directory, just show a few of them. In my source file, I simply use the macro MATRIXDIR:
scorematrix.cpp:string MatrixScoreMethod::default_path=MATRIXDIR;
This seems to work well for me. You can use other versions of the data automake variable, such as dist_data_DATA instead of pkgdata. It is a good idea to use pkgdata this way your data will not be mixed with other packages. The nobase_ is to tell automake not to strip the matrix directory during install. Those escaped double quotes seems to be needed for string type so that you don't get compiler errors.
Once in a while I like to send a version of my software to my Ubuntu PPA on Launchpad. To do so, I need to regenerate the source, description, and change files. To do that, I run the following command:
debuild -S -sa -nc -m"alexis#example.com"
The problem is that it spits out all the files one directory up from my main folder. So say I am working on a project named Beautiful, I would see:
projects/
projects/Beautiful/
projects/Beautiful/<source files from my git>
projects/Beautiful_1.2.3~xenial.dsc
projects/Beautiful_1.2.3~xenial_source.build
projects/Beautiful_1.2.3~xenial_source.changes
projects/Beautiful_1.2.3~xenial_source.ppa.upload
projects/Beautiful_1.2.3~xenial.tar.gz
I would like to place all of the source files in a sub-folder such as:
projects/
projects/Beautiful/
projects/Beautiful/<source files from my git>
projects/Beautiful_source/Beautiful_1.2.3~xenial.dsc
projects/Beautiful_source/Beautiful_1.2.3~xenial_source.build
projects/Beautiful_source/Beautiful_1.2.3~xenial_source.changes
projects/Beautiful_source/Beautiful_1.2.3~xenial_source.ppa.upload
projects/Beautiful_source/Beautiful_1.2.3~xenial.tar.gz
Is it possible from the command line or a rule somewhere? Or is the one directory up the only place where debuild will work on that?
I would like to edit an existing software to add a new source file (Source.cpp).
But, I can't manage the compilation process (it seems to be automake and it looks very complicated).
The software (iperf 2: https://sourceforge.net/projects/iperf2/files/?source=navbar) is compiled using a classical ./configure make then make install.
If I just add the file to the corresponding source and include directory, I got this error message:
Settings.cpp:(.text+0x969) : undefined reference to ...
It looks like the makefile isn't able to produce the output file associated with my new source file (Source.cpp). So, I probably need to indicate it manually somewhere.
I searched a bit in the project files and it seemed that the file to edit was: "Makefile.am".
I added my source to the variable iperf_SOURCES in that file but it didn't workded.
Could you help me to find the file where I need to indicate my new source file (it seems a pretty standard compilation scheme but I never used automake softwares and this one seems very complicated).
Thank you in advance
This project is built with the autotools, as you already figured out.
The makefiles are built by automake. It takes its input in files that usually have a am file name extension.
The iperf program is built by the makefile generated from src/Makefile.am. This is indicated by:
bin_PROGRAMS = iperf
All (actually this is a simplification, but which holds in this case) source files of a to be built binary are in the corresponding name_SOURCES variable, thus in this case iperf_SOURCES. Just add your source file to the end of that list, like so (keeping their formatting):
iperf_SOURCES = \
Client.cpp \
# lines omitted
tcp_window_size.c \
my_new_file.c
Now, to reflect this change in any future generated src/Makefile you need to run automake. This will modify src/Makefile.in, which is a template that is used by config.sub at the end of configure to generate the actual makefile.
Running automake can happen in various ways:
If you already have makefiles that were generated after an configure these should take care of rebuilding themselves. This seems to fail sometimes though!
You could run automake (in the top level directory) by hand. I've never done this, as there is the better solution to...
Run autoreconf --install (possibly add --force to the arguments) in the top level directory. This will regenerate the entire build system, calling all needed programs such as autoheader, autoconf and of course automake. This is my favorite solution.
The later two options require calling configure again, IMO ideally doing an out of source built:
# in top level dir
mkdir build
cd build
../configure # arguments
make # should now also compile and link your new source file
I'm trying to get up and running with Boost, so I'm trying to compile the simple example problem from Boost's "Getting Started" page. I've had two issues, and I'm not sure they're related (I'm better than a novice, but not by much) but maybe they're related...
1st issue: the "tar --bzip2 -xf /path/to/boost_1_49_0.tar.bz2" command didn't work (yes, I put the correct path in, but it gave me some errors, I forget what they were) so I used "tar -xjvf " from the directory where boost_1_49_0.tar.bz2 was located. That de-compressed the zip file and I proceeded with the example...
2nd issue: The example.cpp file will not compile, the first statement in the code is #include "boost/lambda/lambda.hpp" but then for every header file lambda.hpp is trying access, there's a "No such file or directory" compile error. For example, here are two (of the six, and I get errors for all 6) header files within lambda.hpp and the errors displayed by the cygwin compiler:
boost/lambda/lambda.hpp:14:33: boost/lambda/core.hpp: No such file or directory
boost/lambda/lambda.hpp:21:52: boost/lambda/detail/operator_actions.hpp: No such file or directory
If it helps, this is the command I'm running to compile (I generally create the executable in a separate -o command):
g++ -c example.cpp
Why can't the system find these? I added the installed directory (path/to/boost_1_49_0) to the PATH variable before I started so I know that's no it. Thanks for any advice...
(I've looked on stackoverflow and there were similar issues, but no solutions that worked)
It looks like you've already solved the first issue: namely, that you must specify the -j flag on tar to untar a bzip2'd file.
For the second issue, you need to specify boost on your include path, either by specifying it with the -I command line option or via the CPLUS_INCLUDE_PATH environment variable.
How can I compile/run C or C++ code in a Unix console or a Mac terminal?
If it is a simple single-source program,
make foo
where the source file is foo.c, foo.cpp, etc., you don’t even need a makefile. Make has enough built-in rules to build your source file into an executable of the same name, minus the extension.
Running the executable just built is the same as running any program - but you will most often need to specify the path to the executable as the shell will only search what is in $PATH to find executables, and most often that does not include the current directory (.).
So to run the built executable foo:
./foo
gcc main.cpp -o main.out
./main.out
This is the command that works on all Unix machines... I use it on Linux/Ubuntu, but it works in OS X as well. Type the following command in Terminal.app.
g++ -o lab21 iterative.cpp
-o is the letter O, not zero
lab21 will be your executable file
iterative.cpp is your C++ file
After you run that command, type the following in the terminal to run your program:
./lab21
Two steps for me:
First:
make foo
Then:
./foo
All application execution in a Unix (Linux, Mac OS X, AIX, etc.) environment depends on the executable search path.
You can display this path in the terminal with this command:
echo $PATH
On Mac OS X (by default) this will display the following colon separated search path:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
So any executable in the listed directories can by run just by typing in their name. For example:
cat mytextfile.txt
This runs /bin/cat and displays mytextfile.txt to the terminal.
To run any other command that is not in the executable search path requires that you qualify the path to the executable. So say I had an executable called MyProgram in my home directory on Mac OS X I can fully qualify it like so:
/Users/oliver/MyProgram
If you are in a location that is near the program you wished to execute you can qualify the name with a partial path. For example, if MyProgram was in the directory /Users/oliver/MyProject I and I was in my home directory I can qualify the executable name like this, and have it execute:
MyProject/MyProgram
Or say I was in the directory /Users/oliver/MyProject2 and I wanted to execute /Users/oliver/MyProject/MyProgram I can use a relative path like this, to execute it:
../MyProject/MyProgram
Similarly if I am in the same directory as MyProgram I need to use a "current directory" relative path. The current directory you are in is the period character followed by a slash. For example:
./MyProgram
To determine which directory you are currently in use the pwd command.
If you are commonly putting programs in a place on your hard disk that you wish to run without having to qualify their names. For example, if you have a "bin" directory in your home directory for regularly used shell scripts of other programs it may be wise to alter your executable search path.
This can be does easily by either creating or editing the existing .bash_profile file in your home directory and adding the lines:
#!/bin/sh
export PATH=$PATH:~/bin
Here the tilde (~) character is being used as a shortcut for /Users/oliver. Also note that the hash bang (#!) line needs to be the first line of the file (if it doesn't already exist). Note also that this technique requires that your login shell be bash (the default on Mac OS X and most Linux distributions). Also note that if you want your programs installed in ~/bin to be used in preference to system executables your should reorder the export statement as follows:
export PATH=~/bin:$PATH
Do all of this in "Terminal".
To use the G++ compiler, you need to do this:
Navigate to the directory in which you stored the *.cpp file.
cd ~/programs/myprograms/
(the ~ is a shortcut for your home, i.e. /Users/Ryan/programs/myprograms/, replace with the location you actually used.)
Compile it
g++ input.cpp -o output.bin (output.bin can be anything with any extension, really. Extension .bin is just common on Unix.)
There should be nothing returned if it was successful, and that is okay. Generally you get returns on failures.
However, if you type ls, you will see the list of files in the same directory. For example, you would see the other folders, input.cpp and output.bin
From inside the directory, now execute it with ./outbut.bin
A compact way to go about doing that could be:
make foo && ./$_
It is nice to have a one-liner so you can just rerun your executable again easily.
Assuming the current directory is not in the path, the syntax is ./[name of the program].
For example ./a.out
To compile C or C++ programs, there is a common command:
make filename
./filename
make will build your source file into an executable file with the same name. But if you want to use the standard way, You could use the gcc compiler to build C programs and g++ for C++.
For C:
gcc filename.c
./a.out
For C++:
g++ filename.cpp
./a.out
Add the following to get the best warnings, and you will not regret it. If you can, compile using WISE (warning is error).
- Wall -pedantic -Weffc++ -Werror
Step 1 - create a cpp file using the command
touch test.cpp
Step 2 - Run this command
g++ test.cpp
Step 3 - Run your cpp file
./a.out
I am on a new MacBook Pro with the Apple M1 Pro chip. I have my Xcode installed - both IDE and command line tools. This is how it worked for me:
g++ one.cpp -o one
./one
Use a makefile. Even for very small (= one-file) projects, the effort is probably worth it because you can have several sets of compiler settings to test things. Debugging and deployment works much easier this way.
Read the make manual. It seems quite long at first glance, but most sections you can just skim over. All in all, it took me a few hours and made me much more productive.
I found this link with directions:
http://www.wesg.ca/2007/11/how-to-write-and-compile-c-programs-on-mac-os-x/
Basically you do:
gcc hello.c
./a.out (or with the output file of the first command)
In order to compile and run C++ source code from a Mac terminal, one needs to do the following:
If the path of .cpp file is somePath/fileName.cpp, first go the directory with path somePath
To compile fileName.cpp, type c++ fileName.cpp -o fileName
To run the program, type ./fileName
Just enter in the directory in which your .c/.cpp file is.
For compiling and running C code.
gcc filename.c
./a.out filename.c
For compiling and running C++ code.
g++ filename.cpp
./a.out filename.cpp
You need to go into the folder where you have saved your file.
To compile the code: gcc fileName
You can also use the g++ fileName
This will compile your code and create a binary.
Now look for the binary in the same folder and run it.
For running C++ files, run the below command, assuming the file name is "main.cpp".
Compile to make an object file from C++ file.
g++ -c main.cpp -o main.o
Since #include <conio.h> is not supported on macOS, we should use its alternative which is supported on Mac. That is #include <curses.h>. Now the object file needs to be converted to an executable file. To use file curses.h, we have to use library -lcurses.
g++ -o main main.o -lcurses
Now run the executable.
./main
Running a .C file using the terminal is a two-step process.
The first step is to type gcc in the terminal and drop the .C file to the terminal, and then press Enter:
gcc /Desktop/test.c
In the second step, run the following command:
~/a.out