Can ctest use relative path to run test?
There is no problem to run ctest after cmake. But if I copy the whole folder to somewhere else, ctest cannot run properly. It is using absolute path and cannot find the binary.
--build-exe-dir
Specify the directory for the executable.
From https://cmake.org/cmake/help/v3.23/manual/ctest.1.html
I am currently facing the same issue. This answer is a work in progess answer:
when building your tests, when you call add_test, make sure that you use relative path, with an ugly trick like [1]
after the build, you must update DartConfiguration.tcl, like in [2]
[1]
get_target_property(_OUTPUT_DIRECTORY ${__TEST_EXE}
RUNTIME_OUTPUT_DIRECTORY)
if(${_OUTPUT_DIRECTORY} STREQUAL "_OUTPUT_DIRECTORY-NOTFOUND")
set(_OUTPUT_DIRECTORY "./")
endif()
set(__ABS_TEST_EXE
${_OUTPUT_DIRECTORY}/$<TARGET_FILE_NAME:${__TEST_EXE}>)
string(REPLACE ${CMAKE_CURRENT_BINARY_DIR}/ "./" __TEST_EXE_PATH
${__ABS_TEST_EXE})
add_test(NAME ${_TEST_NAME} COMMAND ${__TEST_EXE_PATH})
[2]
- BuildDirectory: /absolute/path/to/you/build
+ BuildDirectory: ./
Related
I'm using autotools on a C project that, after installation, needs a particular directory structure in /var/lib as follows:
/var/lib/my-project/
data/
configurations/
local/
extra/
inputs/
I'm currently using the directive AS_MKDIR_P in configure.ac like so:
AS_MKDIR_P(/var/lib/my-project/data)
AS_MKDIR_P(/var/lib/my-project/configurations/local)
AS_MKDIR_P(/var/lib/my-project/configurations/extra)
AS_MKDIR_P(/var/lib/my-project/inputs)
But it needs the configure script to be run with root permissions which I don't think is the way to go. I think the instructions to create this directory structure needs to be in Makefile.am, so that make install creates them rather than configure, but I have no idea how to do that.
You really, really, really do not want to specify /var/lib/my-project. As the project maintainer, you have the right to specify relative paths, but the user may change DESTDIR or prefix. If you ignore DESTDIR and prefix and just install your files in /var/lib without regard for the user's requests, then your package is broken. It is not just slightly damaged, it is completely unusable. The autotool packaging must not specify absolute paths; that is for downsteam packagers (ie, those that build *.rpm or *.deb or *.dmg or ...). All you need to do is add something like this to Makefile.am:
configdir = $(pkgdatadir)/configurations
localdir = $(configdir)/local
extradir = $(configdir)/extra
inputdir = $(pkgdatadir)/inputs
mydatadir = $(pkgdatadir)/data
config_DATA = cfg.txt
local_DATA = local.txt
extra_DATA = extra.txt
input_DATA = input.txt
mydata_DATA = data.txt
This will put input.txt in $(DESTDIR)$(pkgdatadir)/inputs, etc. If you want that final path to be /var/lib/my-project, then you can specify datadir appropriately at configure time. For example:
$ CONFIG_SITE= ./configure --datadir=/var/lib > /dev/null
This will assign /var/lib to datadir, so that pkgdatadir will be /var/lib/my-project and a subsequent make install DESTDIR=/path/to/foo will put the files in /path/to/foo/var/lib/my-package/. It is essential that your auto-tooled package honor things like prefix (which for these files was essentially overridden here by the explicit assignment of datadir) and DESTDIR. The appropriate time to specify paths like /var/lib is when you run the configure script. For example, you can add the options to the configure script in your rpm spec file or in debian/rules, or in whatever file your package system uses. The auto-tools provide a very flexible packaging system which can be easily used by many different packaging systems (unfortunately, the word "package" is highly overloaded!). Embrace that flexibility.
According to autotools documentation (here and here), there are hooks that you can specify in Makefile.am that will run at specific times during the installation. For my needs I will use install-exec-hook (or install-data-hook) which will be run after all executables (or data) have been installed:
install-exec-hook:
$(MKDIR_P) /var/lib/my-project/data
$(MKDIR_P) /var/lib/my-project/configurations/local
$(MKDIR_P) /var/lib/my-project/configurations/extra
$(MKDIR_P) /var/lib/my-project/inputs
MKDIR_P is a variable containing the command mkdir -p, or an equivalent to it if the system doesn't have mkdir. To make it available in Makefile.am you have to use the macro AC_PROG_MKDIR_P in configure.ac.
I installed the base package to compile C++ with MinGW Installer GUI and CMake. I created a simple file .c with hello world, and can use cmake . -G"MSYS Makefiles" normally. I added E:\Programmation\MinGW\bin and E:\Programmation\MinGW\msys\1.0\bin to my path.
Here is my CMakeLists.txt:
cmake_minimum_required (VERSION 3.3)
project (Prototype)
set (EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
file (
GLOB_RECURSE
source_files
src/*
)
add_executable (
my_exe
${source_files}
)
Once the makefile is created however, when I use make I'll get the following error:
/bin/sh:/e/Users/MyName/Documents/GitHub/ProjectName/prototype/c/E:/Programmation/MinGW/msys/1.0/bin/make.exe: No such file or directory
make.exe": *** [all] Error 127
I can compile the file main.c just fine with gcc main.c and the exe it produces works, so the problem is with the make.exe.
If I use it in the msys.bat shell, located in E:\Programmation\MinGW\msys\1.0, it works as it should. So my guess is that the problem is with Powershell and the path. I'm thinking maybe it's because of the way hard drives are designated, since in the error I get it calls my E:\ disk /e/ first then E:/. When I work in msys.bat I have to write it this way: /e/Users/MyName...
This is PEBKAC. The problem is not with make.exe, but rather, in the way you are attempting to misuse it.
How many times must I say this? Using MSYS make.exe, (or indeed any of the MSYS tools), in any environment other that the MSYS shell, which is started by running msys.bat, is definitively unsupported by the MSYS Project maintainers.
Since you say you problem goes away, when you use make.exe as you are supposed to, (in the MSYS shell, invoked by running msys.bat), this is your problem, and your problem alone. It apparently does not work, when you attempt to use it improperly, (i.e. from PowerShell): that's tough luck; when you break free software, by misusing it, you get to keep all the pieces.
Contrary to the accepted answer, it is actually possible to do this using PowerShell:
sh.exe -c "cd ""$pathToMake""; make"
Make sure you sanitise backslashes for the shell before the call above.
$pathToMake = $pathToMake -replace "\\", "/"
Also the MSYS bin has to be in your path, which would typically look like this (your path maybe different):
$env:Path = "C:\GNUstep\msys\1.0\bin;$($env:Path)"
cmake_minimum_required(VERSION 3.2.1 FATAL_ERROR)
project("soxy")
add_definitions(-std=c99)
include_directories(soxy)
# Includes
include(ExternalProject)
ExternalProject_Add(
LibUV
GIT_REPOSITORY "https://github.com/libuv/libuv.git"
GIT_TAG "v1.4.2"
CONFIGURE_COMMAND sh <SOURCE_DIR>/autogen.sh && ./configure --prefix=${CMAKE_CURRENT_SOURCE_DIR}
PATCH_COMMAND ""
BUILD_COMMAND "make"
BUILD_IN_SOURCE 1
PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/build
)
set( SOXY_SRC src/file_utils.c
src/http_parser.c
src/http_request.c
src/path_utils.c
src/string_utils.c
)
set( SOXY_HDR src/debug.h
src/file_utils.h
src/http_client.h
src/http_parser.h
src/http_request.h
src/logger.h
src/path_utils.h
src/soxy_constantsh
src/soxy.h
src/string_utils.h
)
set( SOXY_BIN src/soxy.c )
add_executable(soxy ${SOXY_BIN})
add_dependencies(soxy LibUV)
Project structure:
/soxy
/soxy/CMakeLists.txt
/soxy/build/
When I build the makefile and run make, the lib and include for the external project end up in /soxy, I'd like them to show up in /soxy/build/ and when it builds my project it doesn't setup the include right such that #include <uv.h> doesn't work and is an unresolved header file inclusion.
You are using --prefix=${CMAKE_CURRENT_SOURCE_DIR}. Try using CMAKE_CURRENT_BINARY_DIR instead.
Hmmm, you are getting several things wrong.
You usually don't need to define a list of header files.
You are not telling anywhere to compile the files contained in the SOXY_SRC variable. You would compile them for example if you did add_executable(soxy ${SOXY_BIN} ${SOXY_SRC}).
After add_dependencies you'll also need target_link_libraries.
You should target "out of source" build. That is, you shouldn't have stuff like ${CMAKE_CURRENT_SOURCE_DIR}/build
So, try the following (I don't know the ExternalProject_Add command so I can only guess the behaviour). Modify two lines of ExternalProject_Add like this:
BUILD_IN_SOURCE 0
PREFIX ${CMAKE_BINARY_DIR}/LibUV
And add:
include_directories(${CMAKE_BINARY_DIR}/LibUV)
You'll probably need also
link_directories(${CMAKE_BINARY_DIR}/LibUV)
Ideally the include directory of LibUV is different from the library directory, take a look to what your
ExternalProject_Add effictively does.
As said before, you'll probably need a target_link_libraries(soxy uv) or something similar, depending on the generated library name
I'm building using the NDK and am having trouble getting the parent directory in the include path. I tried this:
LOCAL_C_INCLUDES += $(LOCAL_PATH)/..
But that does not work, apparently the .. is not processed as I would expect. I ran make -n to see the generated command which includes what I want:
-I/Users/me/android/workspace/jni/module/popt/..
But it fails, although if I manually edit it to instead be:
-I/Users/me/android/workspace/jni/module
It works fine. What should I put in the Android.mk file to include the parent directory in the search path without using ..?
The issue is that popt is a symbolic link, so parent directory .. is not module.
Nothing will be expanding the .. and actually modifying the earlier parts of the path - this is pretty much the same in any build system if you specify a relative path with ...
Why doesn't -I/Users/me/android/workspace/jni/module/popt/.. give the same result as -I/Users/me/android/workspace/jni/module? Is popt a symlink to a different place? In that case, I think a solution would be to define a separate variable in jni/module/Android.mk like MODULE_PATH := $(LOCAL_PATH) and use $(MODULE_PATH) instead of $(LOCAL_PATH)/.. in the other Android.mk file.
you can use "wildcard", for example:
PARENT_DIR_PATH := $(wildcard ..)
This may already be answered somewhere, so please point me in the right direction if so - I couldn't find anything that matched my specific problem when googling!
I've got some CppUnit tests that I'm trying to run.
My top-level CMakeLists.txt contains:
include_directories(
${CPPUNIT_INC}
)
link_directories(
${CPPUNIT_LIB}
)
Both of which are set correctly: I print the paths earlier in the CMakeLists.txt file, and they're correct.
In the subfolder, I have;
add_executable(test-lumberjack TestLumberjack.cpp)
target_link_libraries(
test-lumberjack
Lumberjack
CppUnit
${CMAKE_DL_LIBS}
)
INSTALL(TARGETS test-lumberjack DESTINATION ${PROJECT_OUTPUT_TEST_DIR})
ADD_TEST(NAME test-lumberjack COMMAND "${PROJECT_OUTPUT_TEST_DIR}/test-lumberjack")
However, when I run the tests (either by running the file or using ctest -V), I see the usual linker error EDIT: it's not a linker error, see answer below
The library definitely exists, in the path set earlier in the top level CMakeLists.txt.
I'm stumped! I'm assuming there's something key that I'm totally missing, but I haven't a clue what it is. If you'd like more info, let me know and I'll add it.
Cheers.
I'm an idiot: the CppUnit folder wasn't in my library path. Should've realised this when it was crashing at runtime, not during compilation... Doh!