I am using CMake to link and build my C++ project, and in said project I am using the fstream library to read from a file. However, when passing the path of the file to my code, I am forced to use a long string such as "../../../../folder/folder/folder/file" to properly reference which file I want opened. I presume this is because my .exe that CMake creates is buried deep, "far" away from my source code, which is why I would have to backtrack so much.
I am wondering if there is something I could put in my CMakeLists.txt to potentially allow for the shortening of this inclusion path.
To save myself some time I have not included my file structure as of now, but if it is needed in order for a solution to be formed I certainly can edit and add it in. I do not necessarily need a case-specific solution, rather just a generalized method in which I could go about doing this.
It looks like CMake doesn't provide such functionality , CMake doesn't do much with execution of your application.
So, For solution you have following
can either create a shell script to copy the file into the desired location which can be picked by the executable and shell script can be run while make process
pass it as a commandline argument to your c++ executable.
create a macro with this location and use this macro in the source file : - CMake can help you in this
Using add_compile_definitions( ...)
Related
I'm trying to create a binary file in cmake which:
- depeneds on some .c source files
- also depeneds on an assembler .s file
Now I have added the .c files normally by setting a variable as a list which contains all .c files in a directory. All good so far.
Now I need to add that assembler file as well as part of my binary directory. I did some research in the mailing archieve of cmake and I saw that with assembler files it's a little different you can't just include them as you do with the c files. You have to sometime preprocess them and include their output as a dependecy to the final binary file. Or so I understood.
The way I tried to do it in my project is something like this:
get assembler file name and path using a get_filename_component command:
in an 'add_custom_command' preprocess the file like this:
COMMAND ${COMPILER_NAME} --preprocess=p ${ASSEMBLER_FILE_NAME} >
${OUT_S_FILE}
Where OUT_S_FILE will be added as a dependency to a target which will be then added as a dependency to the binary file so that it gets created before the binary is created. Now I do not understand the --preprocess=p argument I tried googleing it but to no avail I do not know if it's correct or what it actually does(I have seen it in an example which took care of some assembler files).
set a variable: "ASM_OUT_FILE" to path of the file processed above
create a custom target which depends on this "ASM_OUT_FILE"
Finally add this target as a dependency so it gets created before the binary is created.
I'm sorry I cannot provide more actually example for what I've done but it's work related :D.
The result is "no rule to make target for that assembler file" as if the file was not there but it is(I checked).
Please tell me if possible if there are other things I need to do or if I'm doing something wrong in handling this assembler file. Thank you for reading and I'm sorry if my erxplanation was not so clear!
Edit:
set_source_files_properties(assembly_file.s PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp")
I am rather new to CMake, starting off for the first time with a larger project consisting of many subprojects.
For particular reasons (described below for the curious) I already have a set of include files that contain info about the source files needed for each CMake target (lib or exe) – and, for now, I prefer to (re)use these files (reason also described below)
Writing a function to parse these files and add their content as source files to the targets was a surprisingly easy task.
But – now the Problem:
Obviously I want to have each targets CMakeLists.txt depend on the particular include file, that generates the list of source files, so that changes on the include file will be detected as if it were changes to CMakeLists.txt itself, but I simply can’t find any references on how to accomplish that.
N.B.: I found AddFileDependencies but that is for adding dependencies on source files, not the CMakeLists.txt. However, CMake itself can figure out dependencies to included .cmake file somehow, so I figured, it should be possible to do somehow.
Background for the curious:
For this project (quite a number of libraries used by quite a number of executable targets, all organized as subprojects) I was using QMake (without actually using Qt itself) for setting up makefiles. Doing so I was able to use Qt Creator while still being able to generate Visual Studio Solution/Project files automagically. We’re also still in progress of evaluating different IDEs and the choice has not been made yet. But the most important reason to use a generator like QMake / CMake was not being forced to set up the VS files for all these subprojects manually.
Although I needed to trick QMake sometimes to do what I wanted to, things went quite well - even for the VS solution - except for one thing: Visual Studio messes up dependencies on Flex/Bison and other files using custom build rules. It keeps recompiling the Flex/Bison/other files saying „command line changed“ – which I gave up trying to fix.
For this reason I thougt, I’d try CMake as a generator instead, which looks very promising so far – although not having builtin precompiled header support in CMake is somewhat ridiculous these days (off topic, I know).
Since Qt Creators CMake support is by far not as good as the support for QMake projects, I firgured, using the approach of parsing the .pri files containing the source file list would enable me using QMake and CMake side by side – especially since the remaining project settings are rather less complicated than on most open source projects.
There's a nice trick which does exactly what you need. It's based on the idea I found in the git-revision module of #rpavlik see this so question
This is the overall idea:
Create a dummy timestamp file
Add a custom command which touches the timestamp whenever the input .pri file changes
include the timestamp file in your CMakeLists.txt
A possible implementation:
set(input_pri_file <path-to-the-input-pri-file>)
set(timestamp_file ${CMAKE_CURRENT_BINARY_DIR}/timestamp.cmake)
add_custom_command(
OUTPUT ${timestamp_file}
COMMAND ${CMAKE_COMMAND} -E touch ${timestamp_file}
MAIN_DEPENDENCY ${input_pri_file}
VERBATIM
COMMENT "Updating timestamp.cmake"
)
if(NOT EXISTS "${timestamp_file}")
file(WRITE ${timestamp_file} "") # create initial empty file
endif()
include(${timestamp_file})
# create the file list from input_pri_file
....
# use the file list
add_executable(main ${filelist})
Here's what happens when the .pri file changes:
the change triggers the execution of the custom command
which updates the timestamp
because the CMakeLists includes the timestamp it is dependent on it
so updating the timestamp triggers a re-configuration of the CMakeLists.txt
I use the configure_file() if I have some input that should retrigger CMake's configuration process. See e.g. How to make CMake reconfiguration depend on custom file? and configure_file()'s unit test
So in your case it would look something like:
configure_file(SomeInput.pri ${CMAKE_CURRENT_BINARY_DIR}/SomeInput.pri)
Then you use ${CMAKE_CURRENT_BINARY_DIR}/SomeInput.pri to generate the sources. Just make sure you do not add COPYONLY, because then configuration won't retrigger on changes of SomeInput.pri.
EDIT: Alternatively use - a relative new addition - the CMAKE_CONFIGURE_DEPENDS directory property.
I'm wanting to setup my CMakeLists.txt file so that it can generate the .clang_complete file required by the vim plugin clang_complete.
Ordinarily, you would do this by passing a parameter to the python script it supplies with the compiler and all of the parameters for compilation. Note that I am omitting the actual directory cc_args.py is in to save on space.
cc_args.py gcc test.c -o test -I~/IncludeDirs/
You can also do this during the make phase...
make CC='cc_args.py gcc' CXX='cc_args.py g++'
However, I am unsure of how to (if it is possible to) set this up within a CMakeLists.txt file. It's really annoying to have to type this in every time I want to setup clang_complete. The reason why I want to do it this way, is because I have multiple projects that I use a custom script to build the CMakeLists.txt file, so having to write a script for each one or manually place a generic one is a step I'd like to avoid.
I've tried a couple of things that have so far have come up with errors.
I've tried setting CMAKE_CC_COMPILER and CMAKE_CXX_COMPILER to lines similar to the first i.e. "cc_args.py g++". The errors that come up here say that It can't find the compiler (which is understandable).
The next thing I tried was setting the Compiler variables just to the cc_args.py and adding a flag for the actual compiler: suffice to say, that failed horribly. CMake said that it couldn't compile a test program (considering the script isn't a compiler, and the tests don't use the flags I set, I'm not surprised at this).
So without writing any other external scripts that require moving around, is there anyone that can think of a way that can do this?
The solution is to set the CXX environment variable before executing cmake. Something like that:
CXX="$HOME/.vim/bin/cc_args.py clang++" cmake ..
make
See http://www.guyrutenberg.com/2013/01/29/vim-creating-clang_complete-using-cmake/ for more details.
I know you said "without writing any other external scripts," but it seems like you just need a one-liner:
exec cc_args.py g++
And then set that file as your CMAKE_CXX_COMPILER. You could even use CMake's file() function to write the one-liner at build time if you don't want to have to distribute it.
I've been able to easily get all my headers and source files organized using filters like so:
source_group(Source\ Files\\network FILES
network/lobbylist.cpp
network/network.cpp
network/networkenet.cpp
network/networkfactory.cpp
network/networklinux.cpp
network/networkraw.cpp
network/networkwin.cpp
)
However, today I started adding Lua scripts to my project and found that, although no errors were displayed during project generation and everything seemed to be spelled correctly, CMake didn't add a new filter for the scripts in the solution at all.
source_group(Source\ Files\\scripts FILES
scripts/en_lang.lua
)
I also tried putting the group under the Header Files filter and under the project root, but no go. Does CMake simply not recognize or know what to do with non-.h/.hpp/.c/.cpp/etc files? Is there any way to get around this? Obviously I can still edit the scripts in a separate window or open it manually in VS, but having it right there in the solution explorer would be preferable.
You have to add the lua files to ADD_EXECUTABLE
There are struct definitions in the .h file that my library creates after I build it.. but I cannot find these in the corresponding .h.in. Can somebody tell me how all this works and where it gets the extra info from?
To be specific: I am building pth, the userspace threading library. It has pth_p.h.in, which doesn't contain the struct definition I am looking for, yet when I build the library, a pth_p.h appears and it has the definition I need.
In fact, I have searched every single file in the library before it is built and cannot find where it is generating the struct definition.
Pth uses GNU Autoconf, Automake, and Libtool. By running ./configure you'll be running a shell script which eventually runs m4 to detect the presence of a whole bunch of different system attributes and make changes to a number of files.
It looks like it boils down to ./configure generating Makefile from Makefile.in and then running something via make that triggers the shtool subcommand scpp:
pth_p.h: $(S)pth_p.h.in
$(SHTOOL) scpp -o pth_p.h -t $(S)pth_p.h.in -Dcpp -Cintern -M '==#==' $(HSRCS)
Obscure link, but here's an shtool-scpp manpage, which describes it as:
This command is an additional ANSI C
source file pre-processor for sharing
cpp(1) code segments, internal
variables and internal functions. The
intention for this comes from writing
libraries in ANSI C. Here a common
shared internal header file is usually
used for sharing information between
the library source files.
The operation is to parse special
constructs in files, generate a few
things out of these constructs and
insert them at position mark in tfile
by writing the output to ofile.
Additionally the files are never
touched or modified. Instead the
constructs are removed later by the
cpp(1) phase of the build process. The
only prerequisite is that every file
has a ``"#include ""ofile"""'' at the
top.
.h.in is probably processed within a configure (generated from configure.ac) script, look out for
AC_CONFIG_FILES([thatfile.h])
It replaces variables of the form #VAR# in the .in file with their values.
Edit: Just noticed if I'm right you should retag your question