Configure Cargo so that it puts the result in `target/<default target>/<mode>` when there is no explicit `--target` argument? - rust

On Linux, if I build my project with cargo build, the result will be placed in target/debug. If I instead build it with cargo build --target x86_64-unknown-linux-gnu, the result is put in target/x86_64-unknown-linux-gnu/debug, even though the result is the same.
It's inconvenient to supply the --target argument when I run commands manually. Setting build.target in .cargo/config.toml isn't very convenient either as I'd have to make sure to always do that. Our build scripts on the other hand need an explicit --target, because those scripts may run on different systems. For example, we want to make Windows builds on a Linux machine or vice versa.
If I mix manual commands (where I don't want to manually type out --target) and scripts (that use --target to make sure they build for the correct platform), Cargo will spend a lot of time rebuilding the same thing in two different directories.
So, that's why I wonder if it is possible to configure Cargo so that it puts the result in target/<target>/<mode> even when there is no explicit --target argument.

Related

how to add creating protobuf python files [duplicate]

I'm trying to use add_custom_command to generate a file during the build. The command never seemed to be run, so I made this test file.
cmake_minimum_required( VERSION 2.6 )
add_custom_command(
OUTPUT hello.txt
COMMAND touch hello.txt
DEPENDS hello.txt
)
I tried running:
cmake .
make
And hello.txt was not generated. What have I done wrong?
The add_custom_target(run ALL ... solution will work for simple cases when you only have one target you're building, but breaks down when you have multiple top level targets, e.g. app and tests.
I ran into this same problem when I was trying to package up some test data files into an object file so my unit tests wouldn't depend on anything external. I solved it using add_custom_command and some additional dependency magic with set_property.
add_custom_command(
OUTPUT testData.cpp
COMMAND reswrap
ARGS testData.src > testData.cpp
DEPENDS testData.src
)
set_property(SOURCE unit-tests.cpp APPEND PROPERTY OBJECT_DEPENDS testData.cpp)
add_executable(app main.cpp)
add_executable(tests unit-tests.cpp)
So now testData.cpp will generated before unit-tests.cpp is compiled, and any time testData.src changes. If the command you're calling is really slow you get the added bonus that when you build just the app target you won't have to wait around for that command (which only the tests executable needs) to finish.
It's not shown above, but careful application of ${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories() will keep your source tree clean of generated files.
Add the following:
add_custom_target(run ALL
DEPENDS hello.txt)
If you're familiar with makefiles, this means:
all: run
run: hello.txt
The problem with two existing answers is that they either make the dependency global (add_custom_target(name ALL ...)), or they assign it to a specific, single file (set_property(...)) which gets obnoxious if you have many files that need it as a dependency. Instead what we want is a target that we can make a dependency of another target.
The way to do this is to use add_custom_command to define the rule, and then add_custom_target to define a new target based on that rule. Then you can add that target as a dependency of another target via add_dependencies.
# this defines the build rule for some_file
add_custom_command(
OUTPUT some_file
COMMAND ...
)
# create a target that includes some_file, this gives us a name that we can use later
add_custom_target(
some_target
DEPENDS some_file
)
# then let's suppose we're creating a library
add_library(some_library some_other_file.c)
# we can add the target as a dependency, and it will affect only this library
add_dependencies(some_library some_target)
The advantages of this approach:
some_target is not a dependency for ALL, which means you only build it when it's required by a specific target. (Whereas add_custom_target(name ALL ...) would build it unconditionally for all targets.)
Because some_target is a dependency for the library as a whole, it will get built before all of the files in that library. That means that if there are many files in the library, we don't have to do set_property on every single one of them.
If we add DEPENDS to add_custom_command then it will only get rebuilt when its inputs change. (Compare this to the approach that uses add_custom_target(name ALL ...) where the command gets run on every build regardless of whether it needs to or not.)
For more information on why things work this way, see this blog post: https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/
This question is pretty old, but even if I follow the suggested recommendations, it does not work for me (at least not every time).
I am using Android Studio and I need to call cMake to build C++ library. It works fine until I add the code to run my custom script (in fact, at the moment I try to run 'touch', as in the example above).
First of,
add_custom_command
does not work at all.
I tried
execute_process (
COMMAND touch hello.txt
)
it works, but not every time!
I tried to clean the project, remove the created file(s) manually, same thing.
Tried cMake versions:
3.10.2
3.18.1
3.22.1
when they work, they produce different results, depending on cMake version, one file or several. This is not that important as long as they work, but that's the issue.
Can somebody shed light on this mystery?

How can I run a command::new(...) during cargo clean?

While I am learning rust, I have a crude means of building a non-rust c/c++ library that lives in a submodule. My build script (build.rs) now looks like:
use std::process::Command;
fn main() {
// EXTERN_C
// Build the c-library
Command::new("make").args(&["-C", "cadd"]).status().unwrap();
// The name of the library to link to, i.e. like: -l<lib>
println!("cargo:rustc-link-lib=dylib=add_x64Linuxd");
// The library search path for linking, i.e. like -L<path>
println!("cargo:rustc-link-search=native=cadd/lib");
// The run-time library search path (LD_LIBRARY_PATH)
println!("cargo:rustc-env=LD_LIBRARY_PATH=cadd/lib");
}
This is working nicely, the makefile within cadd/ sorts out any build/re-build deps etc. The only thing I can't do at the moment is hook in make -C cadd clean when I run cargo clean. Ideally I would like it to run the clean make target at the same time. The command would look like:
Command::new("make").args(&["-C", "cadd", "clean"]).status().unwrap();
But I don't know how to get such a command to run during cargo clean. Is there a "clean script" like there is a "build script" - or another method?
Eventually I will get around to learning how to wrap up my makefile project into a cargo crate (I think that's the right terminology) - so I know this is not the optimal way to do this, but I want to get this working in a basic way first (so my head does not explode!).
The cargo clean command simply deletes the cargo target directory.
One solution is for your Makefile to output its compilation artifacts(all files it generates) into the target directory.
You could also change the directory cargo outputs its artifacts to, either via the --target-dir CLI option or by adding the following to the .cargo/config:
[build]
target-dir = "some/path"

Build libpng without PNG_READ_eXIf_SUPPORTED for linux

I need to build libpng, but without #define PNG_READ_eXIf_SUPPORTED in pnglibconf.h
I've read comments from pnglibconf.dfa, and here are some ways of disabling features, however I didn't manage to make what I want using them.
The problem is in that, build process is performed on build server, so I can't change any files inside of libpng submodule. Here is how server works:
Download clone sources from git
Generate makefile by running cmake ..
Run make command.
Thus I have libnpg, but with included PNG_READ_eXIf_SUPPORTED option.
Libpng is a submodule of my project, so it checked out by build server automatically so I can't change pnglibconf manually.
As it said in pnglibconf.dfa file:
There are three ways of disabling features, in no particular order:
1) Create 'pngusr.h', enter the required private build information
detailed below and #define PNG_NO_<option> for each option you
don't want in that file in that file. You can also turn on options
using PNG_<option>_SUPPORTED. When you have finished rerun
configure and rebuild pnglibconf.h file with -DPNG_USER_CONFIG:
make clean
CPPFLAGS='-DPNG_USER_CONFIG' ./configure
make pnglibconf.h
pngusr.h is only used during the creation of pnglibconf.h, but it
is safer to ensure that -DPNG_USER_CONFIG is specified throughout
the build by changing the CPPFLAGS passed to the initial ./configure
I tried to do what is written here. I run cmake .. -DCMAKE_C_FLAGS="-DPNG_USER_CONFIG -I/home/me/dev/include" where /home/me/dev/include - is a path to pngusr.h file
Then I run make command. However, PNG_READ_eXIf_SUPPORTED is still present in generated (by make command pnglibconf.h file).
So my main question is how to make libpng without PNG_READ_eXIf_SUPPORTED option?
It remains unclear to me whether and to what extent the specific customization mechanism you are trying to use works in the version of libpng you are trying to use. But it looks like there's a simpler way. Just below the excerpt you posted, in the same file, is the second (of three) alternatives:
2) Add definitions of the settings you want to change to CPPFLAGS;
for example:
-DPNG_DEFAULT_READ_MACROS=0
(lightly formatted). I'm not in a good position to test that on the CMake-based build system, but it seems to work like a charm in the Autotools build system. From examining and comparing the two, I think it will work for CMake, too. In particular, you would want to run
cmake .. -DCMAKE_CPP_FLAGS="-DPNG_NO_READ_eXIf"
for your particular case.
Note, by the way, that the CPP (i.e. preprocessor) flags are the right place for an option such as you are specifying (for -DPNG_USR_CONFIG in your original attempt, too). In practice, though, they probably still work in the C compiler flags.

Makefile only creating first file

I have a Makefile as follows:
work/step1.tab: temp.tab hcp_raw_data_sample.tab
command
work/step2.tab: work/step1.tab
command
I have temp.tab and hcp_raw_data_sample.tab in the home directory and want step1.tab and step2.tab to be created in the work directory. However, it is only step1.tab which gets created; step2.tab does not. What do I do?
When you run make it builds the first target listed in the makefile, in this case work/step1.tab. It doesn't see any reason to build step2.tab because it had everything it needed to build step1, which was the default target.
To have it build both, move work/step2.tab above work/step1.tab. This makes work/step2.tab the default target.
This way it will see that it needs to build work/step1.tab before it can build work/step2.tab, so it will do so, and then it will build work/step2.tab.
Make executes only the first target. Usually you create a target all that creates all sub-targets you want. If you place all as the first target, that will be built if you call make.

Following instructions to build LLVM to the letter, but executables aren't produced

I am running 64-bit Linux and I am attempting to build the LLVM trunk. I follow the instructions to the letter, and invoke configure with the arguments I want, followed by make. Running make install leaves each directory with no action, and running locate on a name of an llvm executable (such as clang) comes up with no results.
I do not understand what could be wrong here, but I am quite sure that no executables are produced. This exact process works for software in general. Is there some absurdly obvious thing that I am missing?
I'm using gcc 4.5 and 3.81.
Depending on whether you asked for debug or release build, you can check the stuff inside bin subdir of Debug or Release (alternatively, Debug+Assert, Release+Assert) directory in your build directory for the binaries.
If there is still nothing, then you can go to tools/ and invoke make directly to check what's going there. Doing "make VERBOSE=1" might provide some additional information.
You probably want to say what's happening and maybe take a look at what's going on and how exactly you invoked configure and make.
Here is what has been working for me on the last 4 or so Ubuntu 64 bit distros.
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm
cd tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
cd ..
./configure --enable-optimized --disable-doxygen --prefix=/llvm
make
make install

Resources