I downloaded Opt++. I did the basic install:
1. cd optpp-2.4
2. ./configure
3. make >& make.log
4. make check >& makecheck.log
5. make install
I replicated Example 1: Unconstrained Quasi-Newton Without Derivatives in the codes below. But as I try to compile, i.e.
g++ run_rosen.cpp rosen.cpp -Wno-write-strings -DHAVE_NAMESPACES -I/usr/local/include -I/usr/local/lib -lopt -lnewmat
I get the errors below. And I also think it's odd that there's a reference to my downloads directory.
//usr/local/lib/libopt.a(dqrdc.o): In function dqrdc:
/home/a/downloads/optpp-2.4/src/PDS/dqrdc.c: 156: undefind reference to dswap_
/home/a/downloads/optpp-2.4/src/PDS/dqrdc.c: 182: undefind reference to dswap_
...
//usr/local/lib/libopt.a(pdsdone.o): In function pdsdone:
/home/a/downloads/optpp-2.4/src/PDS/pdsdone.c: 128: undefind reference to dnrm2_
...
Codes:
run_rosen.cpp
#include <fstream>
#include "rosen.h"
#include "NLF.h"
#include "OptQNewton.h"
using namespace OPTPP;
int main()
{
int ndim = 2;
FDNLF1 nlp (ndim, rosen, init_rosen);
OptQNewton objfcn(&nlp);
objfcn.setSearchStrategy(TrustRegion);
objfcn.setMaxFeval(200);
objfcn.setFcnTol(1.e-4);
if (!objfcn.setOutputFile("rosen.out", 0))
{
cerr << "main: output file open failed" << endl;
}
objfcn.optimize();
objfcn.printStatus("Solution from quasi-newton");
objfcn.cleanup();
}
rosen.h
#ifndef ROSEN_H
#define ROSEN_H
#include "NLF.h"
#include "OptNewton.h"
void init_rosen(int ndim, NEWMAT::ColumnVector& x);
void rosen(int ndim, const NEWMAT::ColumnVector& x, double& fx, int& result);
#endif // ROSEN_H
rosen.cpp
#include "rosen.h"
void init_rosen(int ndim, NEWMAT::ColumnVector& x)
{
if (ndim != 2)
{
exit(1);
}
x(1) = 1.2;
x(2) = 1.0;
}
void rosen(int ndim, const NEWMAT::ColumnVector& x, double& fx, int& result)
{
if (ndim != 2)
{
exit(1);
}
double f1, f2;
f1 = (x(2) - x(1) * x(1));
f2 = 1. - x(1);
fx = 100. * f1 * f1 + f2 * f2;
result = OPTPP::NLPFunction;
}
You need to link against a BLAS library. Try adding this to the end of your build command:
-lblas
Related
I am putting together a minimal example leveraging parallelism features in C++17/20 within Matlab MEX functions. I am able to compile and run the mex function from Matlab, but when I set the execution policy of my C++ STL function to "par" instead of "seq", Matlab gives a runtime linkage complaint. Code and error message follows:
test.m (Matlab top-level script):
vec_in = zeros(5);
coeff = 0.05;
vec_out = test_mex_gateway(vec_in, coeff);
test_mex_gateway.cpp (C++ interface to Matlab):
#include "mex.h"
extern void test_execute(float *array_in, float *array_out, const size_t vec_size, const float coeff);
void mexFunction( int nlhs,
mxArray *plhs[],
int nrhs,
const mxArray *prhs[] )
{
// Check for proper number of input and output arguments
if( nrhs != 2 )
{
mexErrMsgTxt( "3 input arguments required: input_data, coeff" );
}
if( nlhs > 2 )
{
mexErrMsgTxt( "Too many output arguments." );
}
const mwSize *matlab_data_dims_in;
mwSize matlab_data_dims_out[1];
// Input Parameters
float *input_data = (float *) mxGetData(prhs[0]);
float coeff = mxGetScalar(prhs[1]);
// Get dimensions
matlab_data_dims_in = mxGetDimensions(prhs[0]);
const int vec_len = matlab_data_dims_in[1];
// Set output data dimension
matlab_data_dims_out[0] = vec_len;
// Output data
plhs[0] = mxCreateNumericArray(1, matlab_data_dims_out, mxSINGLE_CLASS, mxREAL);
float *output_data = (float *) mxGetData(plhs[0]);
test_execute(input_data, output_data, vec_len, coeff);
}
test_execute.cpp (This is where the actual C++ STL call is made):
#include <execution> // std::execution::*
#include <numeric> // std::exclusive_scan()
void test_execute(float *array_in, float *array_out, const size_t vec_size, const float coeff)
{
std::exclusive_scan
(
std::execution::par, // std::execution::seq works here for Mex call, par does not
array_in,
array_in + vec_size,
array_out,
0.0f,
[coeff](float a, float b)
{
float ret = a + b + coeff;
return ret;
}
);
}
I also have a stand-alone main function to replace the Mex wrapper to do a pure C++ test, test_standalone.cpp:
#include <vector>
#include <iostream>
size_t VEC_NUM_ELEM = 10;
extern void test_execute(float *array_in, float *array_out, const size_t vec_size, const float coeff);
int main(int argc, char **argv)
{
if (argc != 2)
{
std::cout << "Try: " << argv[0] << "<coeff>" << std::endl;
return -1;
}
const float coeff = std::stof(argv[1]);
std::cout << "Coeff: " << coeff << std::endl;
float __attribute__ ((aligned (64))) *vec1_array = (float *)malloc(VEC_NUM_ELEM * sizeof(float));
float __attribute__ ((aligned (64))) *vec2_array = (float *)malloc(VEC_NUM_ELEM * sizeof(float));
for (unsigned i = 0; i < VEC_NUM_ELEM; i++)
{
vec1_array[i] = static_cast<float>(i);
}
test_execute(vec1_array, vec2_array, VEC_NUM_ELEM, coeff);
return 0;
}
Here is how I am building and linking, build.sh:
#!/bin/bash
rm *.o
rm *.exe
rm *.mexa64
cstd=c++17
gpp910=/home/m/compilers/bin/g++
tbblib=/home/m/reqs/tbb/lib/intel64/gcc4.8
echo "Building test_execute.cpp..."
$gpp910 -std=$cstd -I/home/m/reqs/tbb/include -L$tbblib -ltbb -Wl,rpath=$tbblib -c test_execute.cpp -fPIC
echo "Building test_standalone.cpp..."
$gpp910 -std=$cstd -L$tbblib test_execute.o test_standalone.cpp -o test_standalone.exe -ltbb
echo "Building test_mex_gateway.cpp..."
mex test_execute.o test_mex_gateway.cpp -L$tbblib -ltbb
The parallel STL calls has a requirement to link against the Intel TBB (Threading Building Blocks), so before I run Matlab to call test.m OR before I run my test_standalone.exe, I run:
export LD_LIBRARY_PATH=/home/m/reqs/tbb/lib/intel64/gcc4.8:$LD_LIBRARY_PATH
I also make sure to make the the C++ library associated with the version of GCC we built with available at runtime:
export LD_LIBRARY_PATH=/home/m/compilers/lib64:$LD_LIBRARY_PATH
When I run test_standalone.exe, everything behaves normally whether I have the execution policy set to "par" or "seq" on std::exclusive_scan. When run test.m, if "seq" was compiled, I can run with no errors. If "par" was compiled, Matlab complains at runtime about a linkage issue:
Invalid MEX-file 'test_mex_gateway.mexa64': test_mex_gateway.mexa64: undefined symbol:
_ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl
I suspect this was a function that was supposed to be linked from TBB, which I confirmed:
$ nm /home/m/reqs/tbb/lib/intel64/gcc4.8/libtbb.so.2 | grep baseEl
0000000000028a30 T _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl
000000000005ed70 r _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl$$LSDA
I confirmed Matlab's LD_LIBRARY_PATH has the path I supplied in the above "export .." to this library.
I tried making sure my libraries came before the many Matlab-centric paths Matlab adds to LD_LIBRARY_PATH after it launches from the terminal.
I tried baking the path to the linked libraries via a -Wl,rpath=<path_to_tbb.so> passage to the linker.
After almost two days, I can't figure out why Matlab is having this very specific runtime issue, especially when the pure C++ version is not. Any help would be appreciated.
RHEL 7.9
Matlab R2020a
GCC 9.1.0
TBB (Intel Thread Building Blocks) 2020.3
It appears that Matlab comes with a version of libtbb.so included in its installation. From what I can tell, when launching a Mex file, Matlab will use its own libraries first, regardless of your LD_LIBRARY_PATH order. This is what was giving me runtime issues as a Mex file but not as a pure C++ file. Removing the libtbb.so from Matlab's installation directory allowed runtime linkage to find my version of libtbb, and I was able to run without errors. Thanks to Cris Luengo for pointing me in the right direction.
I have been hammering at this for the past 2 days and i've already tried every single solution on the internet, so here goes.
I have a problem with undefined references. I am doing a project to compare 3 algorithms and i have compartmentalized them into 3 different sets of cpp files. I am using Dev C++ with gcc 4.9.2.6 as my compiler. I know it is a linker error, but all my solutions are not working and i can't seem to identify it.
My main file is
#include <iostream>
#include <stdio.h>
#include <string>
#include <fstream>
#include <time.h>
#include "SDL.h"
#include "bitmap_image.hpp" //ext
#include "Bresenham.hpp"
#include "XiaolinWu.hpp"
#include "GuptaSproull.hpp"
void GenerateBMPBlank(int xsize,int ysize,std::string fileid);
void BresenhamTest(int xsize,int ysize, std::string TestDataFile);
void XiaolinWuTest(int xsize,int ysize, std::string TestDataFile);
void GuptaSproullTest(int xsize, int ysize, std::string TestDataFile);
void executeTest(int xsize,int ysize, std::string TestDataFile); //resulting BMP file generated will have the format "x_y_algorithmName.bmp"
int main()
{
short x,y;
std::string TestFileLocation;
std::cout << "Please indicate file path of Test Data textfile"<< std::endl;
std::cin>>TestFileLocation;
std::cout << "Please indicate file dimensions" << std::endl;
std::cin>> x >> y;
executeTest(x,y, TestFileLocation);
std::cout<< "Procedure executed"<< std::endl;
std::cin.get();
return 0;
}
void GenerateBMPBlank(int xsize,int ysize,std::string fileid) //uses external library http://partow.net/programming/bitmap/ to generate a blank white bmp file
{
bitmap_image blankBMP(xsize,ysize); //creates bitmap image
blankBMP.set_all_channels(255,255,255); //sets entire image to be completely white
blankBMP.save_image(fileid);
} //tested
void executeTest(int xsize,int ysize, std::string TestDataFile)
{
SDL_Init( SDL_INIT_EVERYTHING );
std::cout<<"Beginning test of data set from "+TestDataFile<<std::endl;
std::cout<<"Now executing Bresenham's algorithm"<<std::endl;
BresenhamTest(xsize,ysize, TestDataFile);
std::cout<<"Now executing Xiaolin Wu's algorithm"<<std::endl;
XiaolinWuTest(xsize,ysize,TestDataFile);
std::cout<<"Now executing Gupta Sproull 's algorithm"<<std::endl;
GuptaSproullTest(xsize,ysize,TestDataFile);
SDL_Quit();
}
void BresenhamTest(int xsize,int ysize, std::string TestDataFile)
{
std::string ResultName= std::to_string(xsize) + "_" + std::to_string(ysize) + "_Bresenham.bmp";
GenerateBMPBlank(xsize,ysize,ResultName);
clock_t tStart = clock();
Bresenham b(ResultName,TestDataFile);
printf("Time taken for Bresenham: %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}
void XiaolinWuTest(int xsize,int ysize, std::string TestDataFile)
{
std::string ResultName= std::to_string(xsize) + "_" + std::to_string(ysize) + "_XiaolinWu.bmp";
GenerateBMPBlank(xsize,ysize,ResultName);
clock_t tStart = clock();
XiaolinWu w(ResultName,TestDataFile);
printf("Time taken for XiaolinWu: %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}
void GuptaSproullTest(int xsize,int ysize, std::string TestDataFile)
{
std::string ResultName= std::to_string(xsize) + "_" + std::to_string(ysize) + "_GuptaSproull.bmp";
GenerateBMPBlank(xsize,ysize,ResultName);
clock_t tStart = clock();
GuptaSproull g(ResultName,TestDataFile);
printf("Time taken for GuptaSproull: %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}
However, an error is produced as follows
C++ files/ComparatorMain.o:ComparatorMain.cpp:(.text+0x544): undefined reference to `Bresenham::Bresenham(std::string, std::string)'
C++ files/ComparatorMain.o:ComparatorMain.cpp:(.text+0x76b): undefined reference to `XiaolinWu::XiaolinWu(std::string, std::string)'
C++ files/ComparatorMain.o:ComparatorMain.cpp:(.text+0x992): undefined reference to `GuptaSproull::GuptaSproull(std::string, std::string)'collect2.exe: error: ld returned 1 exit status
As the implementation of the 3 different cpp files are nearly identical (with the main difference just being the algorithm implemented as well as some misc. functions which have complied and so far aren't showing errors), I will just show the main parts of Bresenham.cpp and hpp where the linker errors are occurring (if additional information is needed, just tell me). The definitions for GuptaSproull.cpp as well as XiaolinWu.cpp are pretty much identical for the code shown below. I cut out most of the function implementations for easier reading and i don't think its relavant (unless i got that part wrong).
Bresenham.hpp
#ifndef BRESENHAM_H
#define BRESENHAM_H
#include <iostream>
#include "SDL.h"
#undef main
class Bresenham{
public:
Bresenham(std::string BMPName,std::string TestDataFile);
SDL_Surface* OpenBMP(std::string BMPName);
void CloseBMP(SDL_Surface* surface,std::string Filename);
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
void bresenhamDrawLine(int x1,int y1,int x2, int y2, SDL_Surface *surface);
};
#endif
Bresenham.cpp
#ifndef BRESENHAM_H
#define BRESENHAM_H
#include <iostream>
#include <cstdio>
#include <cmath>
#include <fstream>
#include "SDL.h"
#include "Bresenham.hpp"
#undef main
#endif
class Bresenham
{
Bresenham(std::string BMPName,std::string TestDataFile)
{
std::ifstream testFile(TestDataFile);
SDL_Surface *image;
image=OpenBMP(BMPName);
if ( SDL_MUSTLOCK(image) ) //surface must be locked before pixels can be drawn
{
if ( SDL_LockSurface(image) < 0 ) {
fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
return;
}
}
int x1,y1,x2,y2;
while(testFile>>x1>>y1>>x2>>y2)
{
bresenhamDrawLine(x1,y1,x2,y2,image); //loops through the dataset and calls the bresenham draw line function
}
if ( SDL_MUSTLOCK(image) )
{
SDL_UnlockSurface(image);
}
CloseBMP(image,BMPName);
}
void bresenhamDrawLine(int x1,int y1,int x2, int y2, SDL_Surface *surface)
{
/* implemented */
}
SDL_Surface* OpenBMP(std::string BMPName)
{
/* implemented */
}
void CloseBMP(SDL_Surface *surface,std::string FileName)
{
/* implemented */
}
void putpixel(SDL_Surface *surface, int x, int y, double brightness) //this function allows us to place a pixel at coordinates (x,y) in SDL.
{
/*implemented*/
}
};
Now I have done a few messy attempts to try and fix this problem (such as adding #ifndef BRESENHAM_H #define BRESENHAM_H #include "Bresenham.hpp" into the .cpp file. However, the error above still occurs.
Is this linked to the way I implemented my code to do the testing? I used a constructor to basically run my test on the algorithms (which i suspect you might find a shoddy way of implementing such a test). I have done the following (so yeah those didn't work):
Verified that all the files are in the build path (under the same project)
Tried adding namespaces to see if it fixed the problem (it didn't)
I've searched under pretty much every single link in google in order to find a potential fix (none of them seems to work).
There are no compiler errors so far (in all the files).
I suspect i might need to abandon this style of implementing the test and migrate over to using a static function instead (Could someone comment if this would work?). I'm not really used to C++ (this is my first "big" program in this language so far), so pardon me if I'm missing something glaringly obvious (which i hope i didn't).
What should I do?
You actually have two declarations of Bresenham class, one in Bresenham.hpp and one in Bresenham.cpp. Change your cpp file in following way:
Bresenham::Bresenham(std::string BMPName,std::string TestDataFile)
{
std::ifstream testFile(TestDataFile);
SDL_Surface *image;
image=OpenBMP(BMPName);
if ( SDL_MUSTLOCK(image) ) //surface must be locked before pixels can be drawn
{
if ( SDL_LockSurface(image) < 0 ) {
fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
return;
}
}
int x1,y1,x2,y2;
while(testFile>>x1>>y1>>x2>>y2)
{
bresenhamDrawLine(x1,y1,x2,y2,image); //loops through the dataset and calls the bresenham draw line function
}
if ( SDL_MUSTLOCK(image) )
{
SDL_UnlockSurface(image);
}
CloseBMP(image,BMPName);
}
void Bresenham::bresenhamDrawLine(int x1,int y1,int x2, int y2, SDL_Surface *surface)
{
/* implemented */
}
SDL_Surface* Bresenham::OpenBMP(std::string BMPName)
{
/* implemented */
}
void Bresenham::CloseBMP(SDL_Surface *surface,std::string FileName)
{
/* implemented */
}
void Bresenham::putpixel(SDL_Surface *surface, int x, int y, double brightness) //this function allows us to place a pixel at coordinates (x,y) in SDL.
{
/*implemented*/
}
What should I do?
First of all, you need to set up correct code units:
remove #undef main (makes no sense)
remove the include guards from your cpp files, they belong only in header files. With these, the code just doesn't get compiled, hence the linking problem !
As CodeFuller states it clearly in his answer, you must separate the class declaration (in .hpp file) and the implementation of the methods (in the .cpp file)
For more, you need to gives us an MVCE that demonstrates your problem (I agree, that is some bit of work).
I get a lot of undefined references. I don't know what I'm doing wrong.
I'm getting the following errors:
undefined reference to 'LetteroidField::start()'
undefined reference to 'LetteroidField::setTitle(std::string)'
undefined reference to 'Letteroid::setletter(char)'
undefined reference to 'Letteroid::setLetter()'
undefined reference to 'Letteroid::setCoords()'
undefined reference to 'Letteroid::erase()'
and other letteroid references.
I'm not done with the other classes, but I don't know why I'm getting these errors. Am I not using #include "" correctly?
This is my professor's sample code. I contacted him but he is not answering (its an online class).
#include "letteroidfield.h"
#include "letteroid.h"
#include "blinkingletteroid.h"
#include "jumpingletteroid.h"
#include "movingletteroid.h"
#include <stdlib.h> /* srand, rand */
#include <time.h>
/// include your derived classes here
int main()
{
LetteroidField screen;
screen.start();
screen.setTitle("Ken's example for the class, press 'x' to quit");
BlinkingLetteroid one;
BlinkingLetteroid two;
BlinkingLetteroid three;
one.setLetter('!'); /// character
one.setCoords(5, 10); /// row, col
two.setLetter('h');
two.setCoords(7, 9);
three.setLetter('#');
three.setCoords(15, 57);
JumpingLetteroid four;
four.setLetter('j');
four.setCoords(rand() % 21, rand() % 21);
MovingLetteroid five;
five.setLetter('m');
int x = 20;
int y = 20;
while (x >= 1)
{
--x;
}
while (y >= 1)
{
--y;
}
if (x == 1)
{
x = 20;
}
if (y == 1)
{
x = 20;
}
five.setCoords(x,y);
/// create and initialize your letteroids here
while ( screen.waitForKeyPress() ) /// keep going until 'x' is pressed
{
one.blink();
two.blink();
three.blink();
/// call the function that draws your letteroids here
}
screen.end();
return 0;
}
#ifndef _LETTEROIDFIELD_H_
#define _LETTEROIDFIELD_H_
#include <string>
class LetteroidField
{
public:
void start(); /// start up the screen for letteroids
bool waitForKeyPress(); /// wait for any key to be pressed (return
void end(); /// shut down the screen and return it to
void setTitle(std::string); /// diplay the title
};
#endif
#ifndef _LETTEROID_H_
#define _LETTEROID_H_
class Letteroid
{
public:
void setCoords(int, int);// set the position(down, across)
void setLetter(char); // set the character
int getX(); // get the position down
int getY(); // get the position across
void erase(); // erase the letteroid from the screen
void draw(); // draw the letteroid to the screen
private:
int myX;
int myY;
char myLetter;
};
#endif
The question you need to ask yourself is: Where are those classes defined?
If the answer is: "in a shared library (file extension ".so") provided alongside the header", then you'll need to link against it by adding at least the following to your compilation command:
g++ main.cpp -L</path/to/library> -l<library_name>
If the answer is: "in a static library (file extension ".a", AKA archive) provided alongside the header", then you'll need include it in your binary by adding at least the following to your compilation command:
g++ main.cpp <library_name.a>
If the answer is: "in a bunch of source files provided alongside the header", then you'll need to include them in your binary by adding at least the following to your compilation command:
g++ main.cpp <source_file1.cpp> <source_file2.cpp> ...
I'm reading the book named "Advanced C and C++ compiling", by Milan Stevanovic
The following is the snapshot from the book, followed by the problem I'm facing.
Concept illustration: Demo Project
The development environment used to build this simple project will be based on the gcc compiler running on
Linux. Listings 2-1 through 2-3 contain the code used in the demo project.
Listing 2-1. function.h
#pragma once
#define FIRST_OPTION
#ifdef FIRST_OPTION
#define MULTIPLIER (3.0)
#else
#define MULTIPLIER (2.0)
#endif
float add_and_multiply(float x, float y);
Listing 2-2. function.c
int nCompletionStatus = 0;
float add(float x, float y)
{
float z = x + y;
return z;
}
float add_and_multiply(float x, float y)
{
float z = add(x,y);
z *= MULTIPLIER;
return z;
}
Listing 2-3. main.c
#include "function.h"
extern int nCompletionStatus = 0;
int main(int argc, char* argv[])
{
float x = 1.0;
float y = 5.0;
float z;
z = add_and_multiply(x,y);
nCompletionStatus = 1;
return 0;
}
Demo Project Preprocessing Example:
The gcc compiler provides the mode in which only the preprocessing stage is performed on the input source files:
gcc -i <input file> -o <output preprocessed file>.i
Unless specified otherwise, the output of the preprocessor is the file that has the same name as the input file and
whose file extension is .i. The result of running the preprocessor on the file function.clooks like that in Listing 2-4.
Listing 2-4. function.i
# 1 "function.c"
# 1 "
# 1 "
# 1 "function.h" 1
# 11 "function.h"
float add_and_multiply(float x, float y);
# 2 "function.c" 2
int nCompletionStatus = 0;
float add(float x, float y)
{
float z = x + y;
return z;
}
float add_and_multiply(float x, float y)
{
float z = add(x,y);
z *= MULTIPLIER;
return z;
}
More compact and more meaningful preprocessor output may be obtained if few extra flags are passed to the gcc, like
gcc -E -P -i <input file> -o <output preprocessed file>.i
which results in the preprocessed file seen in Listing 2-5.
Listing 2-5. function.i (Trimmed Down Version)
float add_and_multiply(float x, float y);
int nCompletionStatus = 0;
float add(float x, float y)
{
float z = x + y;
return z;
}
float add_and_multiply(float x, float y)
{
float z = add(x,y);
z *= 3.0;
return z;
}
Obviously, the preprocessor replaced the symbol MULTIPLIER, whose actual value, based on the fact that the
USE_FIRST_OPTION variable was defined, ended up being 3.0.
Problem:
When I compile the program as is using gcc, following is the error I am facing
Snapshot from my terminal.
gcc -i function.c -o function.i
cc1: error: unrecognized command line option '-i'
gcc function.c -o function.i
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o:
In function '_start':
(.text+0x18): undefined reference to 'main'
collect2: ld returned 1 exit status
$pwd
/home/adminuser/advance_compiling
$ll
total 20
drwxrwxr-x 2 adminuser adminuser 4096 Jan 10 23:51 ./
drwxr-xr-x 26 adminuser adminuser 4096 Jan 10 23:57 ../
-rw-rw-r-- 1 adminuser adminuser 216 Nov 15 08:58 function.c
-rw-rw-r-- 1 adminuser adminuser 163 Jan 10 23:33 function.h
-rw-rw-r-- 1 adminuser adminuser 257 Dec 28 06:46 main.c
How do I get rid of this and proceed in learning the course?
Please suggest.
-i is not a valid command line option - I'm not sure where the book got it from. In order to just run the preprocessor, you should use the option -E instead.
I was a technical reviewer of the book and the author asked me to post this explanation on his behalf:
The error you found is indeed an error, introduced in the very late stage of book proofreading/editing. Sorry for stepping on it + for book errata still not being printed out (will happen some time soon).
Try this
gcc -E -P function.c -o function.i
without the -i option, it's not a gcc option.
note: this answer was fixed after I realized that have misunderstood the question, so i fixed to keep it and not delete it, but Katie did answer it before I did.
Judging by the .i output file in the book's example, it seems the error is in the utility itself.
Instead of using gcc, use cpp. gcc uses cpp (The C Preprocessor) under the hood to handle macro expansion and header inclusion. The output of cpp is a .i file for c source code and .ii for c++.
cpp function.c > function.i
Try the following code:
function.c
#include "function.h"
int nCompletionStatus = 0;
float add(float x, float y)
{
float z = x + y;
return z;
}
float add_and_multiply(float x, float y)
{
float z = add(x,y);
z *= MULTIPLIER;
return z;
}
main.c
//#include "function.h"
extern int nCompletionStatus;
int main(int argc, char* argv[])
{
float x = 1.0;
float y = 5.0;
float z;
z = add_and_multiply(x,y);
nCompletionStatus = 1;
return 0;
}
Now execute:
gcc function.c main.c
otherwise
gcc -c function.c
gcc function.o main.c
I'm on Ubuntu 12.04 & had some boost fies already in /usr/include. I did a
sudo apt-get install libboost-all-dev
and that installed a lot of files too. I don't want to remove this boost and install from source as several other packages depend on the version from the ubuntu repos. This is the sample code I want to run :-
#include <iostream>
#include <boost/numeric/odeint.hpp>
using namespace std;
using namespace boost::numeric::odeint;
typedef vector< double > state_type;
const double sigma = 10.0;
const double R = 28.0;
const double b = 8.0 / 3.0;
void lorenz( state_type &x , state_type &dxdt , double t )
{
dxdt[0] = sigma * ( x[1] - x[0] );
dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
dxdt[2] = x[0]*x[1] - b * x[2];
}
int main()
{
const double dt = 0.01;
state_type x(3);
x[0] = 1.0 ;
x[1] = 0.0 ;
x[2] = 0.0;
stepper_euler< state_type > stepper;
stepper.adjust_size( x );
double t = 0.0;
for( size_t oi=0 ; oi<10000 ; ++oi,t+=dt )
{
stepper.do_step( lorenz , x , t , dt );
cout << x[0] << " " << x[1] << " " << x[2] << endl;
}
}
ON first compile g++ -o test test.cpp, it threw an error
/usr/include/boost/numeric/odeint.hpp permission denied
So I changed the file permission of all odeint files recursively using
sudo chmod -R +x odeint/
This time, it did not say permission denied but threw 400 lines of error as can be seen here -> error log from terminal
How do I compile it ? There are no install guides for odeint in the documentation or anywhere else
This part of boost seems to use C++11 features. Therefore you need to add either -std=c++0x or -std=c++11 to your compiler invocation.
The subsequent error test.cpp: In function ‘int main()’: test.cpp:30:5: error: ‘stepper_euler’ was not declared in this scope points you to another source of error: You forgot to include the file in which stepper_euler is declared. Put the appropriate #include <file> at the beginning of your code.