Unable to reproduce minimal working example Rcpp - c++

I downloaded and installed the Rcpp package recently in order to speed up the code of my own package using some C++ code.
The first thing I do is making a package with Rcpp.package.skeleton(name="firstpackage"):
> Rcpp.package.skeleton(name="firstpackage")
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Done.
Further steps are described in './firstpackage/Read-and-delete-me'.
Adding Rcpp settings
>> added Imports: Rcpp
>> added LinkingTo: Rcpp
>> added useDynLib directive to NAMESPACE
>> added importFrom(Rcpp, evalCpp) directive to NAMESPACE
>> added example src file using Rcpp attributes
>> compiled Rcpp attributes
>> added Rd file for rcpp_hello_world
This generates a file system with folders man, R and src as it should. However the files Makevars, Makevars.win and rcpp_hello_world.h are missing in these folders, if I compare with the example on page 66-67 in the book Seamless R and C++ Integration with Rcpp. Why aren't these files generated like in the example? After installing firstpackage I cannot use the function rcpp_hello_world() so I guess it is because of the missing files.
edit: It is clear now that the problem is not the missing files but something else. I tried again, now exactly following the instructions:
> Rcpp.package.skeleton("ruben")
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Done.
Further steps are described in './ruben/Read-and-delete-me'.
Adding Rcpp settings
>> added Imports: Rcpp
>> added LinkingTo: Rcpp
>> added useDynLib directive to NAMESPACE
>> added importFrom(Rcpp, evalCpp) directive to NAMESPACE
>> added example src file using Rcpp attributes
>> compiled Rcpp attributes
>> added Rd file for rcpp_hello_world
Then I look at the files. (a bit weird but the file structure appears to be the same)
> system("tree ruben")
Folder PATH listing for volume OSDisk
Volume serial number is A811-3ED9
C:\USERS\N14083\DOCUMENTS\RUBEN
ÃÄÄÄman
ÃÄÄÄR
ÀÄÄÄsrc
Then I install the newly created package:
> system("R CMD INSTALL ruben")
* installing to library 'C:/Users/n14083/Documents/R/win-library/3.1'
* installing *source* package 'ruben' ...
** libs
*** arch - i386
Warning: running command 'make -f "C:/PROGRA~1/R/R-31~1.1/etc/i386/Makeconf" -f "C:/PROGRA~1/R/R-31~1.1/share/make/winshlib.mk" SHLIB_LDFLAGS='$(SHLIB_CXXLDFLAGS)' SHLIB_LD='$(SHLIB_CXXLD)' SHLIB="ruben.dll" OBJECTS="RcppExports.o rcpp_hello_world.o"' had status 127
ERROR: compilation failed for package 'ruben'
* removing 'C:/Users/n14083/Documents/R/win-library/3.1/ruben'
Warning message:
running command 'R CMD INSTALL ruben' had status 1
The installation fails:
library(ruben)
Error in library(ruben) : there is no package called ‘ruben’
edit: solution Download the Windows toolset (http://cran.at.r-project.org/doc/manuals/R-admin.html#The-Windows-toolset) and set the PATH correctly, in my case:
pathRtools <- paste(c("c:\\Rtools\\bin",
"C:\\Rtools\\gcc-4.6.3\\bin",
"c:\\PROGRA~2\\MIKTEX~1.9\\miktex\\bin",
"C:\\PROGRA~1\\R\\R-3.1.1\\bin\\i386",
"c:\\windows",
"c:\\windows\\system32"), collapse=";")
Sys.setenv(PATH=pathRtools)
setwd("C:/Users/n14083/Documents")
system("R CMD INSTALL ruben")
and then restart R.

The book was current when it was written. As you now observe, the header is no longer included, neither are the Makevars as they are no longer needed.
That is because we now build with Rcpp Attributes. It is easier.
It still all works (of course).
Log below.
R> Rcpp.package.skeleton("ruben")
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Done.
Further steps are described in './ruben/Read-and-delete-me'.
Adding Rcpp settings
>> added Imports: Rcpp
>> added LinkingTo: Rcpp
>> added useDynLib directive to NAMESPACE
>> added importFrom(Rcpp, evalCpp) directive to NAMESPACE
>> added example src file using Rcpp attributes
>> compiled Rcpp attributes
>> added Rd file for rcpp_hello_world
R>
So let's look at the files:
R> system("tree ruben")
ruben
├── DESCRIPTION
├── man
│   ├── rcpp_hello_world.Rd
│   └── ruben-package.Rd
├── NAMESPACE
├── R
│   └── RcppExports.R
├── Read-and-delete-me
└── src
├── RcppExports.cpp
└── rcpp_hello_world.cpp
3 directories, 8 files
R>
And use them:
R> system("R CMD INSTALL ruben")
* installing to library ‘/usr/local/lib/R/site-library’
* installing *source* package ‘ruben’ ...
** libs
g++ -I/usr/share/R/include -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include" -fpic -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -g -O3 -Wall -pipe -Wno-unused -pedantic -c rcpp_hello_world.cpp -o rcpp_hello_world.o
g++ -I/usr/share/R/include -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include" -fpic -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -g -O3 -Wall -pipe -Wno-unused -pedantic -c RcppExports.cpp -o RcppExports.o
g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o ruben.so RcppExports.o rcpp_hello_world.o -L/usr/lib/R/lib -lR
installing to /usr/local/lib/R/site-library/ruben/libs
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (ruben)
R>
And it obviously works:
R> library(ruben)
R> rcpp_hello_world()
[[1]]
[1] "foo" "bar"
[[2]]
[1] 0 1
R>
So please substantiate the claim
After installing firstpackage I cannot use the function rcpp_hello_world() so I guess it is because of the missing files.
Running this skeleton is part of every unit test run so this has been tested literally thousands of time since the book was written.

Related

How to use OpenBlas Lapacke together with Rcpp

I have some running c++ code using the Lapacke version that comes with OpenBlas. I would like to include this code into an R package and transfer data between that function and R using the Rcpp package. But somehow the two seem not to like each other. As soon as I have #include <lapacke.h> and #include <Rcpp.h> in one source file it isn't compiling anymore. Both separately work fine. There is a whole bunch off error messages which as far as I can tell say that Rcpp is broken (e.g /home/Alex/R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include/Rcpp/traits/traits.h:32:15: error: expected ‘)’ before ‘__extension__’).
I have no idea why this happens. Is there a way to use both at the same time?
Or should I do something completely different?
Here is a minimal example that gives me the error:
I created a package using
Rcpp::Rcpp.package.skeleton("LT", example_code = FALSE)
I added a .cpp file to /src containing
#include <lapacke.h>
#include <Rcpp.h>
int test_LAPACK(){
return(1);
}
I added a Makvars file to /src containing
PKG_CXXFLAGS = -I/opt/OpenBLAS/include
PKG_LIBS = -L/opt/OpenBLAS/lib -lopenblas -lpthread -lgfortran
CXX_STD = CXX11
Compile and install
Rcpp::compileAttributes("LT")
devtools::install("LT")
It actually works on my system following a standard sudo apt install liblapacke-dev provided I also change the include order.
Witness:
Source
rob:/tmp/lapacke/LT$ cat src/lt.cpp
#include <Rcpp.h>
#include <lapacke.h>
int test_LAPACK(){
return(1);
}
rob:/tmp/lapacke/LT$ ls src/ ## no Makevars needed
lt.cpp
rob:/tmp/lapacke/LT$
Build
rob:/tmp/lapacke/LT$ build.r
* checking for file ‘./DESCRIPTION’ ... OK
* preparing ‘LT’:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* installing the package to process help pages
* saving partial Rd database
* cleaning src
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
Removed empty directory ‘LT/R’
* building ‘LT_1.0.tar.gz’
rob:/tmp/lapacke/LT$
Install
rob:/tmp/lapacke/LT$ install.r LT_1.0.tar.gz
* installing *source* package ‘LT’ ...
** libs
ccache g++ -I"/usr/share/R/include" -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include" -fpic -g -O3 -Wall -pipe -march=native -c lt.cpp -o lt.o
ccache g++ -Wl,-S -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o LT.so lt.o -L/usr/lib/R/lib -lR
installing to /usr/local/lib/R/site-library/LT/libs
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (LT)
rob:/tmp/lapacke/LT$
Run
(After I added a line // [[Rcpp::export]], ran compileAtttributes() and rebuilt and installed.)
rob:/tmp/lapacke/LT$ r -lLT -p -e'test_LAPACK()'
[1] 1
rob:/tmp/lapacke/LT$
Summary
Check your compiler. There is no fundamental reason this should not work, and it works here (Ubuntu 18.04).

How to make sure win-builder builds my package with c++11?

I'm trying to make my package (code available here) pass win-builder tests so I can upload to cran. The package relies heavily in Rcpp and I use some things that require C++11 standard. But the win-builder test results keep showing a number of warnings like the following:
warning: delegating constructors only available with -std=c++11 or -std=gnu++11
warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
I tried to make a minimal test with the Rcpp.package.skeleton() example package, adding a few extended initializer list uses, and a Makevars file containig just the one line:
CXX_STD = CXX11
but the minimal test works fine. You can see in the win-builder test results for the minimal test that it's compiling with -std=gnu++11, whereas my package is being compiled without that option:
Minimal test:
*** arch - i386
d:/Compiler/gcc-4.9.3/mingw_32/bin/g++ -std=gnu++11 -I"D:/RCompile/recent/R/include" -DNDEBUG -I"d:/RCompile/CRANpkg/lib/3.5/Rcpp/include" -I"d:/Compiler/gcc-4.9.3/local330/include" -O2 -Wall -mtune=core2 -c RcppExports.cpp -o RcppExports.o
My package:
*** arch - i386
d:/Compiler/gcc-4.9.3/mingw_32/bin/g++ -I"D:/RCompile/recent/R/include" -DNDEBUG -I"d:/RCompile/CRANpkg/lib/3.5/Rcpp/include" -I"d:/Compiler/gcc-4.9.3/local330/include" -pedantic -O2 -Wall -mtune=core2 -c Individual.cpp -o Individual.o
Why are they compiled with different options? I'm using the exact same Makevars file. Just in case it's relevant, I have these lines on my DESCRIPTION:
Imports:
Rcpp (>= 0.12.14),
Matrix,
grid,
animation
LinkingTo: Rcpp
Suggests:
knitr,
rmarkdown
Depends:
R (>= 3.1.0)
License: GPL-2
LazyData: true
RoxygenNote: 6.0.1
URL: https://github.com/Lobz/facilitation
VignetteBuilder: knitr
EDIT: I copied the above into the minimal test package's DESCRIPTION file to make them more similar, and the minimal test file still compiles properly with -std=gnu++11.
Note: I upload the packages to win-builder via devtools::build_win().
Try adding in DESCRIPTION
SystemRequirements: C++11
This avoids the need of having to specify a custom Makevars for different platforms (e.g. Makevars for Unix + Solaris + macOS, Makevars.win for windows).
However, as #DirkEddelbuettel said, C++11 support on Windows exist; but, the completeness of the C++11 implementation with gcc-4.9.3 is problematic on the library side

Building and linking shared libraries in an R package - code compiles, links, but won't load

Platforms tested: Linux Mint 17, Ubuntu 14.04
Full example: this repository.
What am I doing and why?
I'm trying to build an R package which wraps a subset of the CAF library using Rcpp and RcppEigen.
I have successfully linked an R package to a system level install of CAF (example here) (Note: ABSEIR no longer uses CAF, 2/5/2015), but I'd like to have a good way to deploy CAF to machines without administrator access, and as a result simplify the installation of other CAF dependent packages (yes, I'm aware that R doesn't directly support linking against other compiled packages, but it seems like others have successfully circumvented this limitation).
What's the problem?
I'm building two shared objects during package compilation in addition to the package shared object (RcppCAF.so): libcaf_core.so and libcaf_io.so. These are successfully compiled and linked, but the package fails to load, claiming:
** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/home/grantbrown/R/x86_64-pc-linux-gnu-library/3.2/RcppCAF/libs/RcppCAF.so':
librcaf_core.so: cannot open shared object file: No such file or directory
What have I tried?
In addition to numerous failed Makevars configurations, I've found that
if I manually set LD_LIBRARY_PATH to the folder containing the compiled code, the package will successfully install. Obviously, I'd like to avoid this step by finding a way to tell R where to look for these dependencies. I have attempted to use the inst folder for this purpose to no effect. My Makevars file is as follows:
ROOT_DIR := $(abspath .)
$(info The compilation root directory is: $(ROOT_DIR))
$(info The name of the shared library to be created is: $(SHLIB))
$(info The place R should look for librcaf_core.so is: $(abspath ./libcaf_core))
$(info The place R should look for librcaf_io.so is: $(abspath ./libcaf_io))
SOURCES = $(wildcard ./*.cpp)
SOURCES1 = $(wildcard ./libcaf_core/*.cpp)
SOURCES2 = $(wildcard ./libcaf_io/*.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
OBJECTS1 = $(SOURCES1:.cpp=.o)
OBJECTS2 = $(SOURCES2:.cpp=.o)
PKG_CPPFLAGS+= -std=c++11 -Dlibcaf_core_shared_EXPORTS -Wall -pedantic -pthread -fPIC -O2 -g -fPIC -I../inst -I../inst/libcaf_core -I../inst/libcaf_io
PKG_LIBS += -L$(abspath ./libcaf_core) -lrcaf_core -L$(abspath ./libcaf_io) -lrcaf_io
all: $(SHLIB)
$(SHLIB): $(OBJECTS) libcaf_core/librcaf_core.so libcaf_io/librcaf_io.so
libcaf_core/librcaf_core.so: $(OBJECTS1)
g++ -o libcaf_core/librcaf_core.so $(OBJECTS1) $(PKG_CPPFLAGS) -shared
libcaf_io/librcaf_io.so: $(OBJECTS2)
g++ -o libcaf_io/librcaf_io.so $(OBJECTS2) $(PKG_CPPFLAGS) -shared
There are a lot of threads on StackOverflow and mailing lists which deal with problems loading shared objects, but I couldn't find anyone with precisely the same issue. I've even done similar things in the past with no issues, so I'm having trouble figuring out why R can't find my shared objects. Any suggestions?
Edit
Dirk has suggested compiling to a single shared object, which I'm now working on. In the "Using Makevars" section of "Writing R Extensions", however, it does seems to imply that building dependencies should be possible:
"If you want to create and then link to a library, say using code in a subdirectory, use something like
.PHONY: all mylibs
all: $(SHLIB)
$(SHLIB): mylibs
mylibs:
(cd subdir; make)
"
The easiest approach, which you also seem to have found as per your most recent commit is to just have R 'glue' all object code into a single shared library.
That tends to "just work" but it is a little costly as the library needs to be rebuilt. We could look into packaging CAF as an external library which would make RcppCAF more lightweight.

How to build and load shared library on rstudio for package that uses C/C++ files in src folder inside a subdirectory?

I have a R package that I'm working on that contains code written in C and C++ under the src folder. Currently, the package compiles and works on Rstudio as it follows the default directory structure. As the project builds, I want to be able to organize my code under src, within subfolders. Following directions from "Writing R extensions" - Compiling under sub-directories, I have made a folder called 'test'(/src/test) which now contains all my files(*.c, *.cpp, *.h) and modified my Makevars like so -
SOURCES_C = $(wildcard test/*.c)
SOURCES_CPP = $(wildcard test/*.cpp)
PKG_CPPFLAGS= -I${R_HOME}/include -I.
PKG_LIBS = -L${R_HOME}/lib
CXX_STD = CXX11
OBJECTS =$(SOURCES_CPP:.cpp=.o) $(SOURCES_C:.c=.o)
all : $(SHLIB)
#PKG_CFLAGS= -Wall
clean : rm -f *.o
I want to be able to compile the program in this state, where the C/C++ files are under subfolders inside src. Using the aforementioned Makevars -> the separate object files are being built from the test folder with the correct flags and compiler, for all C/CPP files. However, there are some discrepancies with the build command for the shared object. This is the log when compiling the files under src/test which fails with an undefined symbol error.
gcc -std=gnu99 -shared -L/usr/local/lib64 -o BioCro.so test/BBox.o test/Climate.o test/Compound.o test/Grid.o test/LeafOptics.o test/Maths.o test/Normal.o test/Point3D.o test/Ray.o test/Triangle.o test/Vector3D.o test/runFastTracer.o test/Assigncropcent.o test/AuxBioCro.o test/AuxCropGro.o test/AuxMaizeGro.o test/AuxcaneGro.o test/Auxcropcent.o test/AuxwillowGro.o test/BioCro.o test/CalculateBiogeochem.o test/Calculate_Soil_Layer_Temperature.o test/CanA.o test/CanAC_3D.o test/Century.o test/Copy_CropCent_To_DayCent_Structure.o test/Copy_SoilWater_BioCro_To_CropCent.o test/CropGro.o test/CropGro_c.o test/Filling_BioCro_SoilStructure.o test/assignManagement.o test/c3CanA.o test/c3EvapoTrans.o test/c3photo.o test/c4photo.o test/caneGro.o test/createNULLc3tree.o test/cropcent.o test/dailywillow.o test/denitrify.o test/diffusiv.o test/eC4photo.o test/getIdirIdiff.o test/getsoilprop.o test/leachdly.o test/maizeGro.o test/methane.o test/microclimate_for_3Dcanopy.o test/nitrify.o test/nox_pulse.o test/pi_funcs.o test/printcropcentoutput.o test/test_mainC.o test/tgmodel.o test/tracegas.o test/update_3Dcanopy_structure.o test/wfps.o test/willowCent.o test/willowGro.o -L/usr/local/R-3.1.0/lib64/R/lib -L/usr/local/R-3.1.0/lib64/R/lib -lR
installing to /home/vashist1/R/x86_64-unknown-linux-gnu-library/3.1/BioCro/
** R
** data
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/home/vashist1/R/x86_64-unknown-linux-gnu-library/3.1/BioCro/libs/BioCro.so':
/home/vashist1/R/x86_64-unknown-linux-gnu-library/3.1/BioCro/libs/BioCro.so:
undefined symbol: _ZTVN10__cxxabiv117__class_type_infoE
Error: loading failed
Compared with the successful log which builds successfully!
g++ -shared -L/usr/local/lib64 -o BioCro.so Assigncropcent.o AuxBioCro.o AuxCropGro.o AuxMaizeGro.o AuxcaneGro.o Auxcropcent.o AuxwillowGro.o BBox.o BioCro.o CalculateBiogeochem.o Calculate_Soil_Layer_Temperature.o CanA.o CanAC_3D.o Century.o Climate.o Compound.o Copy_CropCent_To_DayCent_Structure.o Copy_SoilWater_BioCro_To_CropCent.o CropGro.o CropGro_c.o Filling_BioCro_SoilStructure.o Grid.o LeafOptics.o Maths.o Normal.o Point3D.o Ray.o Triangle.o Vector3D.o assignManagement.o c3CanA.o c3EvapoTrans.o c3photo.o c4photo.o caneGro.o createNULLc3tree.o cropcent.o dailywillow.o denitrify.o diffusiv.o eC4photo.o getIdirIdiff.o getsoilprop.o leachdly.o maizeGro.o methane.o microclimate_for_3Dcanopy.o nitrify.o nox_pulse.o pi_funcs.o printcropcentoutput.o runFastTracer.o test_mainC.o tgmodel.o tracegas.o update_3Dcanopy_structure.o wfps.o willowCent.o willowGro.o -L/usr/local/R-3.1.0/lib64/R/lib -lR
installing to /home/vashist1/R/x86_64-unknown-linux-gnu-library/3.1/BioCro/libs
1) The shared object compiles using g++ under default conditions, whereas under subdirectory conditions the compiler used is gcc. Can I change that behaviour via Makevars?
2) Further research allowed me to find that the undefined symbol error is a linking error fixed by the -L/-l flag. However, the -L flag is the same for both build commands. Is there any other library I am failing to link which is linked by default?
I ran into the same issue. Looking at the example of the RSiena package mentioned as an example in "Writing R Extensions" section 1.2.1.3 I noticed that that package still has some .cpp files not in a subdirectory. So I added a dummy.cpp file in src/ with the following contents:
void dummy (void)
{
}
After this g++ was correctly used for the linking step and the .so file was created as expected.
In my case it turns out that I don't need to change the Makevars files as I first mentioned in my answer. Even without the change below (so only having the dummy.cpp file present in src/) linking is done correctly.
I'll leave it in in case it may help someone else with a (slightly) different setup.
And add the corresponding .o file in the list of $(OBJECTS) variable in the Makevars file:
OBJECTS = $(SOURCES:.cpp=.o) dummy.o

How to configure and setup google test framework in linux

I'm a newbie to g test and Here is what I am trying to do (On a Linux server from console):
1) Create a small project in C++ ( with a header file containing a function prototype, a cpp file with a function in it and another cpp file with main calling the function already defined in the header file )
2) Configure g test to write unit tests and test the function created in the step 1
3) Create another small project with a couple of unit tests (different scenarios to test the function created under the project in step 1)
Can anyone please tell how to configure g test and the projects created with an example?
Thanks in advance
First of all, get the most updated version of GoogleTest from the Subversion repository (you need Subversion installed):
cd ~
svn checkout http://googletest.googlecode.com/svn/trunk/ googletest-read-only
Then, build the library (you need cmake installed):
mv googletest-read-only googletest
mkdir googletest/lib
cd googletest/lib
cmake ..
make
At this point:
compiled libraries are in the ~/googletest/lib directory
include files are in the ~/googletest/include directory
To use googletest:
Include the header in your files:
#include "gtest/gtest.h"
Export the library path:
export GOOGLETESTDIR=~/googletest
Compile with
g++ ... -I$GOOGLETESTDIR/include -L$GOOGLETESTDIR/lib -lgtest -lpthread
Please find the tutorial
# http://www.yolinux.com/TUTORIALS/Cpp-GoogleTest.html
Caution!!
one correction at the makefile (test/src/Makefile). The order of the library path is not correct!!.
It would be like:
CXX = g++
CXXFLAGS = -g -L/opt/gtest/lib -lgtest -lgtest_main -lpthread
INCS = -I./ -I../../src -I/opt/gtest/include
OBJS = ../../src/Addition.o Addition_Test.o ../../src/Multiply.o Multiply_Test.o
testAll: $(OBJS)
$(CXX) $(INCS) -o testAll Main_TestAll.cpp $(OBJS) $(CXXFLAGS)
.cpp.o:
$(CXX) $(CXXFLAGS) -c $< -o $# $(INCS)
clean:
rm testAll *.o testAll.xml
After a small research here is what I found out:
If your project library contains files like:
1) callMain.cpp which calls the function to do some operations
2) reverse.cpp which contains the logic of reversing a number and
3) header.h containing the declaration of function prototypes
And if you have unit test case scenario scripts like unitTest1.cpp and unitTest2.cpp to be tested via gtest then, this can be achieved as follows:
g++ -I<gtest include directory location> -L<gtest directory location> <gtest_main.cc location> reverse.cpp unitTest1.cpp unitTest2.cpp -lgtest -lpthread -o test_try
This compiles and produces an executable like test_try which when executed gives the desired result. Please correct me if I'm wrong anywhere. Happy coding :)
New answer
Today I read the Google Test FAQ. It's not recommend to install a pre-compiled copy of Google Test(for example, into /usr/local). You can find the answer in the FAQ.
So, recommend this answer and this blog article.
Old answer
Following the CMake document of FindGTest.
The code below works for me.
cmake_minimum_required(VERSION 2.8)
################################
# Add gtest environment
################################
enable_testing()
find_package(GTest REQUIRED)
# add gtest include directory: way 1
include_directories(${GTest_INCLUDE_DIRS})
# add gtest include directory: way 2
#include_directories(${GTest_SOURCE_DIRS}/include ${GTest_SOURCE_DIR})
################################
# Build tests
################################
aux_source_directory(. DIR_SRCS)
add_executable(fooTest ${DIR_SRCS})
# parameter `gtest` should at the front of `pthread`
target_link_libraries(fooTest gtest pthread)
# Take all gtest cases as one Cmake test case
add_test(AllFooTest fooTest)
And then, you can using command:
cmake ., generate Makefile
make, build gtest routine
./fooTest, run gtest routine
make test, run cmake test, it's another way you can run the gtest