I have a C++ project that employs unit testing via CppUnit and has the following directory structure:
.
|-- bin
| `-- tests
|-- src
| `-- include
`-- test
`-- include
In the top-level directory resides my Makefile.am file. I would like to use a non-recursive Makefile. I have been able to build the executable of my project in the bin folder and the tests for make check in the bin/tests folder.
The problem is the following:
When make check runs the tests, the current working directory is still the top-level directory (i.e., the directory from which I ran make check). Is it possible to change the working directory specifically for the test suites?
The relevant piece in my Makefile.am file is the following:
$(TESTDIR)=./bin/tests
check_PROGRAMS = $(TESTS)
TESTS = $(TESTDIR)clocktest
__TESTDIR_clocktest_SOURCES = test/clocktest.cpp test/unittest.cpp src/clock.cpp
__TESTDIR_clocktest_CPPFLAGS = $(AM_CPPFLAGS) $(CPPUNIT_CFLAGS) $(TESTCPPFLAGS)
__TESTDIR_clocktest_LDADD = $(CPPUNIT_LIBS)
From make --help:
-C DIRECTORY, --directory=DIRECTORY
Change to DIRECTORY before doing anything.
I think that should do what you're looking for.
Related
Following is my CMakeLists.txt structure
|-- MyProject
|-- CMakeLists.txt
|-- README.md
|-- bin
|-- include
|-- lib
|-- src
| |-- CMakeLists.txt
| |-- main.cc
| |-- parser
| |-- CMakeLists.txt
| |-- parser.cc
| |-- parser.h
|-- third-party
|-- CMakeLists.txt
|-- cassandra-cpp-driver
Now I want to introduce a yugabyteDB-cpp-driver https://github.com/yugabyte/cassandra-cpp-driver/tree/2.9.0-yb to use its API, so I add those commands into my root CMakeLists.txt
set(THIRD_PARTY_DIR ${PROJECT_SOURCE_DIR}/third-party)
add_subdirectory(${THIRD_PARTY_DIR})
Then I add these to third-party/CMakeLists.txt
set(CQL_DRIVER_LIB_NAME "cassandra-cpp-driver")
set(CQL_DRIVER_INC_PATH ${CQL_DRIVER_LIB_NAME}/include)
add_subdirectory(${CQL_DRIVER_LIB_NAME})
After these, when I trying to do build the project, I got
CMake Error at third-party/cassandra-cpp-driver/CMakeLists.txt:10 (include):
include could not find requested file:
CppDriver
CMake Error at third-party/cassandra-cpp-driver/CMakeLists.txt:12 (CassInitProject):
Unknown CMake command "CassInitProject".
Seems the cpp-driver it self has a include() command which calls the .cmake files the git contains, but I can't trigger it in my project.
Note: Below I describe a solution to the specific problem occuring, but this is in no way a complete solution to allow you to include the project the way you intend to. This is unlikely to be possible without modifying the third party cmake logic. The cmake logic just doesn't seem to be designed for your intended use case.
CMake Error at third-party/cassandra-cpp-driver/CMakeLists.txt:10 (include):
include could not find requested file:
CppDriver
The relevant lines in the CMakeLists.txt file in the repository linked are
set(CASS_ROOT_DIR ${CMAKE_SOURCE_DIR})
...
list(APPEND CMAKE_MODULE_PATH ${CASS_ROOT_DIR}/cmake/modules)
include(CppDriver)
The first line is supposed to make cmake able to the CppDriver.cmake module when using the include() command.
CMAKE_SOURCE_DIR refers to the directory containg the toplevel CMakeLists.txt though, which is your own directory. To be able to include the project via add_subdirectory, the relevant line should read
set(CASS_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
(Note: In no way this is a complete analysis of the cmake logic. There may be different parts that would require similar adjustments.)
You could fix this specific error by simply adding the correct path before using add_subdirectory():
set(CQL_DRIVER_LIB_NAME "cassandra-cpp-driver")
set(CQL_DRIVER_INC_PATH ${CQL_DRIVER_LIB_NAME}/include)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${CQL_DRIVER_LIB_NAME}/cmake/modules)
add_subdirectory(${CQL_DRIVER_LIB_NAME})
But you'd just run into a similar issue in a different place in the third party cmake logic.
I would like to configure correctly project's settings.json file to use CMakeLists.txt file of multiple sub-project.
My approach is given below
The structure of the project is as like as follows.
vscode_build_cmake/
`-- task
|-- add
| |-- CMakeLists.txt
| |-- include
| | `-- foo.h
| `-- src
| |-- foo.cpp
| `-- main.cpp
`-- print
|-- CMakeLists.txt
|-- include
| `-- foo.h
`-- src
|-- foo.cpp
`-- main.cpp
Here, add & print are completely isolated sub-project of the main project task. Each sub-project has their own build recipe which is written in their own CMakeLists.txt file. Usual steps to build sub-project is :
cd task/add
mkdir build
cd build
cmake .. && make
Same steps is for task/print.
Right now I would like to perform this build task using VSCode Cmake tool. What I have found that I only need to make a vscode_build_cmake/.vscode/settings.json file where I can point to the directory of CMakeLists.txt file. I am now working with
{
"cmake.configureOnOpen": false,
"cmake.sourceDirectory": "${workspaceFolder}/task/add"
}
I just press ctrl+shift+p and write in the command box run build task and press Enter. That one do the job for me and I can see build, bin, lib directories inside task/add directory.
But the problem, I am facing now is that if I need to build print sub-project I have to manually edit the settings.json file as like as follows
{
"cmake.configureOnOpen": false,
"cmake.sourceDirectory": "${workspaceFolder}/task/print"
}
After that, I have to delete cache and reconfigure and build task which perform now the build task only for print project. This one is very tedious to me.
My desire is to know
Is there any way to point out the both CMakeLists.txt file of add and print in cmake.sourceDirectory? Which can tell me which build task I would like to perform? Eg:
{
"cmake.configureOnOpen": false,
"cmake.sourceDirectory": ["${workspaceFolder}/task/add",
"${workspaceFolder}/task/print"]
}
Or ,
Is there any way to perform build task of both sub-project.(this one is optional. Previous one is important for my case).
I am using CMake Tools v1.13.4.
If you're intent on not having a tasks/CMakeLists.txt that add_subdirectorys add/ and print/, then you can consider using VS Code's multi-root workspace feature, which the vscode-cmake-tools extension supports.
If you have a reason not to use / that you don't like the multi-root workspace approach, you can show your support for vscode-cmake-tools issue #1374 ("Support Multiple CMakeLists.txt without Requiring a Multi-Root Workspace") and the proposed solutions. At the time of this writing, the proposal process is still in earlier stages.
I have small project and after building it he layout looks like this.
|-- BUILD
|-- README.md
|-- VERSION
|-- WORKSPACE
|-- bazel-bin -> /home/bkch/.cache/bazel/_bazel_bkch/172376ca1288bc6e93208fc2d53c0b74/execroot/distroless/bazel-out/k8-fastbuild/bin
|-- bazel-distroless -> /home/bkch/.cache/bazel/_bazel_bkch/172376ca1288bc6e93208fc2d53c0b74/execroot/distroless
|-- bazel-out -> /home/bkch/.cache/bazel/_bazel_bkch/172376ca1288bc6e93208fc2d53c0b74/execroot/distroless/bazel-out
|-- bazel-testlogs -> /home/bkch/.cache/bazel/_bazel_bkch/172376ca1288bc6e93208fc2d53c0b74/execroot/distroless/bazel-out/k8-fastbuild/testlogs
|-- debian_archives.bzl
bazel-bin, bazel-out, bazel-distroless, bazel-testlogs are symbolic links to .cache in user root folder. Instead of the symbolic links I would like to build them in current workspace directory.
From the documentation I tried using --output_base=$PWD/output or --output_user_root=$PWD/output . The moment I use these options the bazel build is failing of various random reasons. But when I use bazel build //... with out these options the build succeeds.
I guess the answer might lie here... github.com/bazelbuild/bazel/issues/13601 we just need to have folder outside the project folder --output_base=$PWD/../output
I am trying to deploy a C++ application compiled with gcc on Linux by putting the required .so files into the executable directory. I added the linker flag -Wl,-rpath=$ORIGIN so that the program may look for the linked libraries in the directory where it's located. This works so far as that all libraries that are directly linked with my executable are found (checked via ldd).
However, when I try to launch the application I get the following error:
This application failed to start because it could not find or load the Qt platform plugin "xcb".
Available platform plugins are: linuxfb, minimal, offscreen, xcb.
Reinstalling the application may fix this problem.
The platform plugins are located in the folder ./platforms (relative to the executable path). Those some other shared object files which are apparently loaded by Qt, one of them being libqxcb.so. Now, the problem is that this file again depends on libQt5Gui.so, libQt5Core.so etc. These are located in my application path, but I suspect that the libqxcb.so is somehow not able to find them there, thus it fails. Is there a possibility how I could fix this?
If I use the following script to run the application, it works (note: Ct is the name of the executable):
#!/bin/sh
DIR="$( cd "$( dirname "$0" )" && pwd )"
cd $DIR
LD_LIBRARY_PATH=LD_LIBRARY_PATH:. ./Ct
But I would like to achieve this without having to use a script to run the application.
The qt deployment document is not particularly helpful with this.
The key to solving this issue is when you look at ldd output of libqxcb.so it goes in the lib folder.
libQt5Core.so.5 => <*>/plugins/platforms/./../../lib/libQt5Core.so.5 (0x00007f5f8374a000)
Therefore the directory structure should be as following:
app
|-- lib
| |-- libQt5Core.so.5
| |-- libQt5Gui.so.5
| |-- libQt5DBus.so.5
| |-- libQt5XcbQpa.so.5
| |-- libicui18n.so.56
| |-- libicuuc.so.56
| `-- libicudata.so.56
|-- qt.conf
|-- app_exec
`-- plugins
`-- platforms
`-- libqxcb.so
In project.pro set your application rpath for lib folder:
unix:!mac{
QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN/lib\'"
}
Finally you need to set up qt.conf for your app to be able to find plugins (by default looks from the platforms folder):
[Paths]
Prefix=./
Libraries=lib
Plugins=plugins
I have a Hierarchical project that uses source code from a common system-directory, for which I am using the SCons Repository() function and want all the build output (local code and code taken from the Repository) placed in a variant_dir.
If I use the Repository() function in a simple scenario (non-hierchical with no calls to sub-directory SConscripts) then the compiled Repository() object file is placed in the variant_dir as expected. But if I do the same in a hierarchical build, the compiled Repository() object file is placed in the project root directory.
Assuming I want to use the following source code located in a system-directory:
/usr/local/repoDir/repoFile.cc
And I have the following project structure:
# tree .
.
|-- SConstruct
|-- build
| `-- linux_x86_64
`-- moduleA
|-- localFile.cc
`-- SConscript
Here are the build scripts:
SConstruct
Edit: Removed filename from call to Repository(), thanks to Dirk Baechle from users#scons.tigris.org for pointing that out.
env = Environment()
env.Repository('/usr/local/repoDir')
env['variantDir'] = 'build/linux_x86_64'
SConscript('moduleA/SConscript',
exports = ['env'],
variant_dir = env['variantDir'],
duplicate = 0)
moduleA/SConscript
import os
Import('env')
srcFiles = [
'localFile.cc',
#os.path.join(env['variantDir'], 'repoFile.cc'), # fails to find source file
#'#%s' % os.path.join(env['variantDir'], 'repoFile.cc'), # fails to find source file
#'repoFile.cc', # fails to find source file
'#repoFile.cc', # only option that works, but places object in root proj dir
]
env.Append(CPPPATH = ['.', '#'])
env.Program(target = 'myApp', source = srcFiles)
I would like the repoFile.cc file to be compiled and have its object file placed in build/linux_x86_64, but instead its placed in the same directory as the root SConstruct.
As you can see from the comments in moduleA/SConscript, I tried referencing the repoFile.cc several different ways, and the only way that worked is as mentioned therein. Additionally, I tried calling the Repository() function in moduleA/SConscript, but it didnt change anything.
Edit: Here is the compilation output
# scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o repoFile.o -c -Ibuild/linux_x86_64 -ImoduleA -I/usr/local/repoDir/moduleA -I/usr/local/repoDir/build/linux_x86_64 -I. -I/usr/local/repoDir /usr/local/repoDir/repoFile.cc
g++ -o build/linux_x86_64/localFile.o -c -Ibuild/linux_x86_64 -ImoduleA -I/usr/local/repoDir/moduleA -I/usr/local/repoDir/build/linux_x86_64 -I. -I/usr/local/repoDir moduleA/localFile.cpp
g++ -o build/linux_x86_64/myApp build/linux_x86_64/localFile.o repoFile.o
scons: done building targets.
And resulting directory structure:
# tree .
.
|-- repoFile.o <=== This file should be in build/linux_x86_64 NOT here
|-- SConstruct
|-- build
| `-- linux_x86_64
| |-- localFile.o
| `-- myApp
`-- moduleA
|-- localFile.cpp
`-- SConscript
I checked around and found this, but its not quite the same:
Scons Hierarchical Builds with Repository directory
Any suggestions as to how I can get the object file in the right place?
I asked this same question on the SCons-users mailing list, and received some information that partly answers this question. Thanks to Dirk Baechle for helping me with this issue.
The Repository() function effectively mounts the directory passed in to the root of the SCons project: that is to the directory where the SConstruct file is. If files in a repo sub-directory need to be referenced in sub-directories of the SCons project, then the sub-directory names (that of the repo dir and scons project dir) must match. That's why the different options in the SConscript file in the question above fail to find the repo file.
If the repo sub-directory moduleA existed with the file repoFile.cc, then it would be found as expected and the compiled object would be placed in the variant_dir as expected.
One limitation I see to the Repository() function is that you can't mount the repo directory to a SCons project sub-directory. This sounds like a feature request.
The fact that SCons places the compiled object file in the source directory seems like a bug to me. At the very least, it should be placed in the variant_dir root directory.